discord.py 音乐机器人:如何结合播放和队列命令
Posted
技术标签:
【中文标题】discord.py 音乐机器人:如何结合播放和队列命令【英文标题】:discord.py Music Bot: How to Combine a Play and Queue Command 【发布时间】:2019-05-05 10:27:40 【问题描述】:您好,我正在尝试创建一个音乐机器人,但我想要它,这样我就可以使用相同的命令播放音乐并将其他音乐添加到队列中。我试过这样做,但我无法让它工作。以下是 play 和 queue 是两个独立命令的代码:
@bot.command(pass_context=True)
async def join(ctx):
await bot.join_voice_channel(bot.get_channel('487315853482786820'))
@bot.command(pass_context=True)
async def leave(ctx):
voice_client = bot.voice_client_in(ctx.message.server)
await voice_client.disconnect()
players =
queues =
def check_queue(id):
if queues[id] != []:
player = queues[id].pop(0)
players[id] = player
player.start()
@bot.command(pass_context=True)
async def play(ctx, url):
server = ctx.message.server
voice_client = bot.voice_client_in(server)
player = await voice_client.create_ytdl_player(url, after=lambda: check_queue(server.id))
players[server.id] = player
player.start()
@bot.command(pass_context=True)
async def queue(ctx, url):
server = ctx.message.server
voice_client = bot.voice_client_in(server)
player = await voice_client.create_ytdl_player(url, after=lambda: check_queue(server.id))
if server.id in queues:
queues[server.id].append(player)
else:
queues[server.id] = [player]
await bot.say('Video queued.')
@bot.command(pass_context=True)
async def pause(ctx):
id = ctx.message.server.id
players[id].pause()
@bot.command(pass_context=True)
async def stop(ctx):
id = ctx.message.server.id
players[id].stop()
@bot.command(pass_context=True)
async def resume(ctx):
id = ctx.message.server.id
players[id].resume()
【问题讨论】:
【参考方案1】:您需要某种队列系统,其中歌曲请求存储在队列中,并且需要一个循环来检查队列中是否有任何项目,如果队列中的第一个项目可用,则获取它。如果队列中没有歌曲,则循环等待直到添加歌曲。您可以使用asyncio.Queue()
和asyncio.Event()
来执行此操作。
import asyncio
from discord.ext import commands
client = commands.Bot(command_prefix='!')
songs = asyncio.Queue()
play_next_song = asyncio.Event()
@client.event
async def on_ready():
print('client ready')
async def audio_player_task():
while True:
play_next_song.clear()
current = await songs.get()
current.start()
await play_next_song.wait()
def toggle_next():
client.loop.call_soon_threadsafe(play_next_song.set)
@client.command(pass_context=True)
async def play(ctx, url):
if not client.is_voice_connected(ctx.message.server):
voice = await client.join_voice_channel(ctx.message.author.voice_channel)
else:
voice = client.voice_client_in(ctx.message.server)
player = await voice.create_ytdl_player(url, after=toggle_next)
await songs.put(player)
client.loop.create_task(audio_player_task())
client.run('token')
【讨论】:
谢谢,它现在工作得很好!我只需要弄清楚如何实现恢复、暂停和跳过。我相信我会弄清楚的。再次感谢! 查看此处了解可以完成的操作discordpy.readthedocs.io/en/latest/…。您可能还必须以其他函数可以访问它的方式保存对象,例如在类中。 我想在我的 DJ 中实现下一个命令,这个命令只是对 toggle_next() 的调用,但似乎当调用下一个切换时,所有队列都会一次性消耗掉,如果我有很多歌曲要播放,它们会丢失。你知道为什么会这样吗?我有 await play_next_son.wait() 和 clear() 等待 play_next_song.set 被调用,但似乎没有保持 while True 循环。 已解决:不要直接调用toggle_next() 只是voice.stop() 因为当stop discord.py 调用after 参数中的函数并会自动运行while True 循环以获取下一项队列。谢谢。以上是关于discord.py 音乐机器人:如何结合播放和队列命令的主要内容,如果未能解决你的问题,请参考以下文章