discord.py音乐机器人:如何结合播放和排队命令

时间:2018-12-04 03:50:00

标签: python-3.x discord.py

你好,我想创建一个音乐机器人,但我想要它,以便可以播放音乐并使用相同的命令将其他音乐添加到队列中。我已尝试执行此操作,但无法使其正常工作。这是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 个答案:

答案 0 :(得分:0)

您需要某种队列系统,在该系统中歌曲请求存储在队列中,并且需要一个循环来检查队列中是否有任何项目,并在队列中的第一个项目(如果有)上获取。如果队列中没有歌曲,则循环将等待直到添加了歌曲。您可以使用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')