提问者:小点点

Discord.py-音乐机器人队列命令


我正在尝试在python中编写一个简单的不和谐音乐机器人。我尝试编写一个队列命令,以便我可以对某首歌曲进行排队(搜索歌曲并播放它们等所有工作)。这是我的队列命令代码:

  @commands.command()
  async def checkqueue(self, ctx):
    if len(self.song_queue[ctx.guild.id]) == 0:
      return await ctx.send("Queue is empty")
    else:
      embed = discord.Embed(title="Song Queue", description="", colour=discord.colour.dark_gold())
      i = 1
      for url in self.song_queue[ctx.guild.id]:
        embed.description += f"{i}) {url}\n"
        i += 1
      await ctx.send(embed=embed)

当队列为空时,机器人会不和谐地发送一条消息说“队列为空”。当我使用play命令时,它会向队列中添加一首歌曲。但是,当我尝试在队列中至少有一首歌曲时使用checkline命令时,机器人不会发送嵌入。不确定这是队列命令中的代码还是队列命令之外的代码的问题,所以这是我的命令Cog中其余代码的精简版本。

import discord
from discord.ext import commands
import youtube_dl
import pafy
import asyncio

class Commands(commands.Cog):
  def __init__(self, client):
    self.client = client
    self.song_queue = {}

  @commands.Cog.listener()
  async def on_ready(self):
    for guild in self.client.guilds:
      self.song_queue[guild.id] = []
  
  async def check_queue(self, ctx):
    if len(self.song_queue[ctx.guild.id]) > 0:
      ctx.voice_client.stop()
      await self.play_song(ctx, self.song_queue[ctx.guild.id][0])
      self.song_queue[ctx.guild.id].pop(0)

  async def search_song(self, amount, song, get_url=False):
    info = await self.client.loop.run_in_executor(None, lambda: youtube_dl.YoutubeDL({"format": "bestaudio", "quiet" : True}).extract_info(f"ytsearch{amount}:{song}", download=False, ie_key="YoutubeSearch"))
    if len(info["entries"]) == 0: 
      return None

    return [entry["webpage_url"] for entry in info["entries"]] if get_url else info
  
  async def play_song(self, ctx, song):
    url = pafy.new(song).getbestaudio().url
    ctx.voice_client.play(discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(url)), after=lambda error: self.client.loop.create_task(self.check_queue(ctx)))
    ctx.voice_client.source.volume = 0.5

  @commands.command()
  async def stop(self, ctx):
    if ctx.voice_client is not None:
      return await ctx.voice_client.disconnect()
      return await ctx.send("Disconnected")
    else:
      return await ctx.send("I am not connected to a voice channel")

  @commands.command()
  async def join(self, ctx):
    if ctx.author.voice is None:
      return await ctx.send("You are not connected to a voice channel")
    else:
      channel = ctx.author.voice.channel
      await channel.connect()
      await ctx.send(f"Connected to voice channel: '{channel}'")

  @commands.command()
  async def play(self, ctx, *, song=None):
    if song is None:
      return await ctx.send("You must include a song to play.")
    
    if ctx.voice_client is None:
      return await ctx.send("I must be in a voice channel to play a song.")

    if not ("youtube.com/watch?" in song or "https://youtu.be/" in song):
      await ctx.send("Searching for a song, this may take a few seconds...")

      result = await self.search_song(1, song, get_url=True)

      if result is None:
        return await ctx.send("Sorry, I couldn't find the song you asked for. Try using my search command to find the song you want.")

      song = result[0]

    if ctx.voice_client.source is not None:
      queue_len = len(self.song_queue[ctx.guild.id])

      if queue_len < 10:
        self.song_queue[ctx.guild.id].append(song)
        return await ctx.send(f"Song added to the queue at position {queue_len+1}")
      else:
        return await ctx.send("Maximum queue limit has been reached, please wait for the current song to end to add more songs to the queue")
      
    await self.play_song(ctx, song)
    await ctx.send(f"Now playing: {song}")
  
  @commands.command()
  async def search(self, ctx, *, song=None):
    if song is None:
      return await ctx.send("Please include a song to search for")
    await ctx.send("Searching for song, this may take a few seconds...")

    info = await self.search_song(5, song)

    embed = discord.Embed(title=f"Results for '{song}':", description="You can use these URL's to play the song\n", colour=discord.Colour.blue())

    amount = 0
    for entry in info["entries"]:
      embed.description += f"[{entry['title']}]({entry['webpage_url']})\n"
      amount += 1
    
    embed.set_footer(text=f"Displaying the first {amount} results.")
    await ctx.send(embed=embed)

  @commands.command()
  async def checkqueue(self, ctx):
    if len(self.song_queue[ctx.guild.id]) == 0:
      return await ctx.send("Queue is empty")
    else:
      embed = discord.Embed(title="Song Queue", description="", colour=discord.colour.blue())
      i = 1
      for url in self.song_queue[ctx.guild.id]:
        embed.description += f"{i}) {url}\n"
        i += 1
      await ctx.send(embed=embed)
  
  @commands.command()
  async def queue(self, ctx, *, song=None):
    if song is None:
      return await ctx.send("You must include a song to queue.")

    if not ("youtube.com/watch?" in song or "https://youtu.be/" in song):
      await ctx.send("Searching for a song, this may take a few seconds...")

      result = await self.search_song(1, song, get_url=True)

      if result is None:
        return await ctx.send("Sorry, I couldn't find the song you asked for. Try using my search command to find the song you want.")

      song = result[0]

    if ctx.voice_client.source is not None:
      queue_len = len(self.song_queue[ctx.guild.id])

      if queue_len < 10:
        self.song_queue[ctx.guild.id].append(song)
        return await ctx.send(f"Song added to the queue at position {queue_len+1}")
      else:
        return await ctx.send("Maximum queue limit has been reached, please wait for the current song to end to add more songs to the queue")

共1个答案

匿名用户

我对您的代码遇到的问题是嵌入的颜色。当我运行您的代码时,其他一切都很顺利。当您引用颜色时,您没有正确访问该函数。

你做了什么:

embed = discord.Embed(title="Song Queue", 
                      description="", 
                      colour=discord.colour.dark_gold())

你应该做什么:

embed = discord.Embed(title="Song Queue", 
                      description="", 
                      colour=discord.Colour.dark_gold())