首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何在我的Discord音乐机器人中实现队列系统?

我如何在我的Discord音乐机器人中实现队列系统?
EN

Stack Overflow用户
提问于 2021-11-04 22:10:56
回答 1查看 74关注 0票数 0
代码语言:javascript
复制
@client.command()
async def play(ctx, *, url = None):
  if ctx.author.voice is None:
      msg = await ctx.send("You are not in a voice channel.")
      await msg.delete(delay = 3)
  voice_channel = ctx.author.voice.channel
  if ctx.voice_client is None:
      await voice_channel.connect()
  else:
      await ctx.voice_client.move_to(voice_channel)

  search_keyword = url
  if not ("youtube.com/watch?" in search_keyword):
    search_keyword = search_keyword.replace(" ", "+")
    html = urllib.request.urlopen(f"https://www.youtube.com/results?search_query={search_keyword}")
    video_ids = re.findall(r"watch\?v=(\S{11})", html.read().decode())
    url = str(f"https://www.youtube.com/watch?v={video_ids[0]}")
  
  ctx.voice_client.stop()
  FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
  YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist':'True'}
  vc = ctx.voice_client

  with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
    info = ydl.extract_info(url, download=False)
    title = info.get('title', None)
    length = info['duration']
    url2 = info["formats"][0]["url"]
    source = await discord. FFmpegOpusAudio.from_probe(url2, **FFMPEG_OPTIONS)
    vc.play(source)
  
  embed = discord.Embed(title = "Currently Playing", colour = discord.Colour.blue())
  embed.add_field(name = "Song", value = title, inline = False)
  embed.add_field(name = "Length", value = str(datetime.timedelta(seconds = length)), inline = False)
  embed.add_field(name = "Link", value = url, inline = False)
  msg = await ctx.send(embed=embed)
  await msg.add_reaction("\u23F8")
  await msg.add_reaction("\u25B6")
  await msg.add_reaction("\u23F9")
  while True:
    try:
      reaction, user = await client.wait_for("reaction_add", check=lambda reaction, user: user.id == ctx.author.id and reaction.message.id == msg.id and reaction.emoji in ["\u23F8", "\u25B6", "\u23F9"], timeout = length)
    
    except asyncio.TimeoutError:
      return await msg.clear_reactions()
        
    async def process():
      if reaction.emoji == "\u23F8":
        await msg.remove_reaction(reaction.emoji, ctx.author)
        ctx.voice_client.pause()
      elif reaction.emoji == "\u25B6":
        await msg.remove_reaction(reaction.emoji, ctx.author)
        ctx.voice_client.resume()
      elif reaction.emoji == "\u23F9":
        await msg.remove_reaction(reaction.emoji, ctx.author)
        ctx.voice_client.stop()

    asyncio.create_task(process())

这是我的play命令的代码。现在,如果在播放歌曲时调用该命令,则该歌曲将停止,而新请求的歌曲将开始播放,这是因为该歌曲在下载之前执行了ctx.voice_client.stop()。但是,我正在尝试实现一个队列系统,如果在播放另一首歌曲时调用该命令,它将被添加到队列中,队列中的歌曲将在当前歌曲结束后立即播放。目前,我的想法是用if语句替换ctx.voice_client.stop(),该语句检查机器人当前是否正在播放,并将其附加到包含当前队列的全局列表变量或播放歌曲。但我对如何让它一个接一个地播放队列并实现一个跳过命令一无所知。另一个复杂的部分是将跳过命令实现为类似于我实现暂停和播放命令的反应。我现在不知道我的想法是否行得通,所以任何意见都是值得感谢的。

EN

回答 1

Stack Overflow用户

发布于 2021-11-06 16:18:15

首先,您需要在命令之外创建一个空队列

queues = {}

还有一个检查队列中是否有歌曲的功能,它将播放这首歌曲

代码语言:javascript
复制
#check queue
queues = {}
def check_queue(ctx, id):
  if queues[id] !={}:
    voice = ctx.guild.voice_client
    source = queues[id].pop(0)
    voice.play(source, after=lambda x=0: check_queue(ctx, ctx.message.guild.id))

和内部播放命令创建一个函数,用于在歌曲已在播放时将下一首歌曲添加到队列中,并添加检查队列函数

代码语言:javascript
复制
  if voice.is_playing():
    guild_id = ctx.message.guild.id
    if guild_id in queues:
      queues[guild_id].append(source)
    else:
      queues[guild_id] = [source]
  else:
    vc.play(source, after=lambda x=0: check_queue(ctx, ctx.message.guild.id))

如果你需要更多的帮助Need help Discord bot queue,你可以在这里查看我的代码

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69846415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档