play now auto joins,

shuffle no longer supports unshuffle,
add some embeded status updates
This commit is contained in:
Arthur Lu 2022-08-25 00:22:57 +00:00
parent 9bfc9cdc05
commit 695bcb391c
3 changed files with 69 additions and 62 deletions

15
src/embed.py Normal file
View File

@ -0,0 +1,15 @@
import discord
from pytube import YouTube
def get_status(channel, queue, playing):
desc = 'playing {0} in {1}'.format(playing, channel)
emb = discord.Embed(title='music-bot', description=desc,color=0x00FF00)
lst = ""
for i in range(0, min(10, queue.num_remaining())):
title = queue.elem[i].title
lst += "{0}: {1}\n".format(str(i), title)
if lst == "":
lst = "empty queue"
emb.add_field(name="next up: ", value=lst)
return emb

View File

@ -1,15 +1,17 @@
import random import random
class music_queue: class music_queue:
def __init__(self, random=False): def __init__(self):
self.elem = [] self.elem = []
self.random=random
def enqueue(self, a): def enqueue(self, a):
self.elem.append(a) self.elem.append(a)
def shuffle(self):
random.shuffle(self.elem)
def dequeue(self): def dequeue(self):
if self.random:
return self.elem.pop(random.randrange(0, len(self.elem)))
else:
return self.elem.pop(0) return self.elem.pop(0)
def purge(self):
self.elem = []
def has_next(self): def has_next(self):
return len(self.elem) != 0 return len(self.elem) != 0
def num_remaining(self):
return len(self.elem)

View File

@ -1,7 +1,8 @@
import asyncio import asyncio
from config import *
import discord import discord
from discord.ext import commands from discord.ext import commands
from config import * from embed import get_status
from pytube import YouTube, Playlist from pytube import YouTube, Playlist
import shutil import shutil
@ -31,7 +32,8 @@ bot.config = config
async def on_ready(): async def on_ready():
print('Logged in as {0} ({0.id})'.format(bot.user)) print('Logged in as {0} ({0.id})'.format(bot.user))
print('------') print('------')
bot.queue = None bot.queue = music_queue()
bot.currently_playing = ""
@bot.command() @bot.command()
async def setprefix(ctx, *arg): async def setprefix(ctx, *arg):
@ -59,29 +61,11 @@ async def setrole(ctx, *arg: discord.Role):
await ctx.send("set playable role to {0}".format(arg[0])) await ctx.send("set playable role to {0}".format(arg[0]))
@bot.command()
async def join(ctx):
roleid = bot.config['guild']['roleid']
if not ctx.message.author.voice:
await ctx.send("You are not connected to a voice channel!")
return
elif(roleid not in [role.id for role in ctx.author.roles]):
await ctx.send("you do not have the role to play music")
return
else:
channel = ctx.message.author.voice.channel
bot.queue = music_queue()
await ctx.send(f'Connected to ``{channel}``')
await channel.connect()
return
@bot.command() @bot.command()
async def leave(ctx): async def leave(ctx):
bot.queue.purge()
await ctx.voice_client.disconnect() await ctx.voice_client.disconnect()
bot.queue = None
shutil.rmtree('session/') # temporary cleanup procedure, will add caching later shutil.rmtree('session/') # temporary cleanup procedure, will add caching later
@bot.command() @bot.command()
@ -92,16 +76,25 @@ async def skip(ctx):
@bot.command() @bot.command()
async def shuffle(ctx): async def shuffle(ctx):
if bot.queue: roleid = bot.config['guild']['roleid']
bot.queue.random = not bot.queue.random
await ctx.send("shuffle set to {0}".format(bot.queue.random)) if(ctx.author.voice == None):
await ctx.send("you are not in a voice channel")
return
elif(roleid not in [role.id for role in ctx.author.roles]):
await ctx.send("you do not have the role to play music")
return
elif(not ctx.voice_client.is_connected()):
await ctx.send("bot is not connected to a voice channel")
else: else:
await ctx.send("not in a voice chat, use {0}join".format(bot.config['guild']['prefix'])) bot.queue.shuffle()
await ctx.send(embed=get_status(ctx.voice_client.channel, bot.queue, bot.currently_playing))
@bot.command() @bot.command()
async def play(ctx, *arg): async def play(ctx, *arg):
roleid = bot.config['guild']['roleid'] roleid = bot.config['guild']['roleid']
prefix = bot.config['guild']['prefix']
if(len(arg) != 1): if(len(arg) != 1):
await ctx.send("usage: play <YouTube url>") await ctx.send("usage: play <YouTube url>")
@ -112,8 +105,14 @@ async def play(ctx, *arg):
elif(roleid not in [role.id for role in ctx.author.roles]): elif(roleid not in [role.id for role in ctx.author.roles]):
await ctx.send("you do not have the role to play music") await ctx.send("you do not have the role to play music")
return return
elif(bot.queue == None):
await ctx.send("not in a voice chat, use {0}join".format(bot.config['guild']['prefix'])) if(ctx.voice_client == None): # if not in vc, join
channel = ctx.message.author.voice.channel
await ctx.send(f'Connected to ``{channel}``')
await channel.connect()
bot.queue.random = False
elif (ctx.voice_client.channel != ctx.author.voice.channel): # if in another vc than author, ignore
await ctx.send("bot already connected to another channel, use {0}leave".format(prefix))
return return
url = arg[0] url = arg[0]
@ -137,13 +136,11 @@ async def play(ctx, *arg):
else: else:
await bot.start_playing(ctx) await bot.start_playing(ctx)
async def start_playing(ctx): async def start_playing(ctx): # should guarantee ctx.voice_client.is_playing() is True
event = asyncio.Event() event = asyncio.Event()
event.set() event.set()
try:
while bot.queue.has_next(): while bot.queue.has_next():
event.clear() event.clear()
@ -152,17 +149,20 @@ async def start_playing(ctx):
name = yt.title name = yt.title
duration = yt.length duration = yt.length
bot.currently_playing = name
filepath = 'session/' filepath = 'session/'
fileprefix = '' fileprefix = ''
filename = name filename = name
if duration < bot.config['max-length']: if duration < bot.config['max-length']:
await ctx.send('playing {0} | {1} tracks remaining in queue'.format(name, len(bot.queue.elem))) await ctx.send(embed=get_status(ctx.voice_client.channel, bot.queue, bot.currently_playing))
##await ctx.send('playing {0} | {1} tracks remaining in queue'.format(name, bot.queue.num_remaining()))
yt.streams.filter(only_audio=True, file_extension='mp4').last().download(output_path=filepath, filename=filename, filename_prefix=fileprefix) yt.streams.filter(only_audio=True, file_extension='mp4').last().download(output_path=filepath, filename=filename, filename_prefix=fileprefix)
path = filepath + fileprefix + filename path = filepath + fileprefix + filename
print("play here")
ctx.voice_client.play(discord.FFmpegPCMAudio(path), after=lambda e:event.set()) ctx.voice_client.play(discord.FFmpegPCMAudio(path), after=lambda e:event.set())
else: else:
@ -170,16 +170,6 @@ async def start_playing(ctx):
await event.wait() await event.wait()
except AttributeError:
pass
except Exception as e:
print(e)
await ctx.voice_client.disconnect()
bot.queue = None
shutil.rmtree('session/') # temporary cleanup procedure, will add caching later
bot.start_playing = start_playing bot.start_playing = start_playing
bot.run(token) bot.run(token)