我目前正在创建一个不和谐的机器人,使用discord.py,播放音乐。
使用“-play”命令时,机器人应该播放指定的歌曲。如果在机器人当前播放时播放了一首歌曲,则它会将其添加到队列中,一旦歌曲完成,就会播放该歌曲。
如果一首指定的歌曲在另一首完成后被请求,那么它应该简单地播放指定的歌曲。
然而,目前机器人只实现了两者中的第一个。虽然如果在另一首歌中排队,歌曲确实会播放……当另一首歌结束后使用“-play”命令时,它仍然会将歌曲添加到队列中。播放歌曲的唯一方法是“跳过”当前正在播放的歌曲,即使没有听到任何声音。
相关代码如下:
class Player(commands.Cog):
def __init__(self,bot):
self.bot = bot
self.song_queue = {}
self.setup()
def setup(self):
for guild in self.bot.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 play_song(self, ctx, song):
url = pafy.new(song).getbestaudio().url
ctx.voice_client.play(discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(url)), after=lambda error: self.bot.loop.create_task(self.check_queue(ctx)))
ctx.voice_client.source.volume = 0.5
#other code...
@commands.command()
async def play(self, ctx, *, song=None):
if song is None:
return await ctx.send("Gotta tell me what to play before I can bust out the music")
if ctx.voice_client is None:
return await ctx.send("Come on bud, why would I sing my tunes if you're not even listening!?")
if not("youtube.com/watch?" in song or "https:youtu.be/" in song):
await ctx.send("Searching for song, gonna have to wait a sec")
result = await self.search_song(1, song, get_url=True)
if result is None:
return await ctx.send("Are you sure this is really a song? Maybe try search for it with my command, =play insert song name here")
song = result[0]
if ctx.voice_client.source is not None:
queue_len = len(self.song_queue[ctx.guild.id])
self.song_queue[ctx.guild.id].append(song)
return await ctx.send(f"The song's been added to your queue, position {queue_len+1}.")
await self.play_song(ctx, song)
await ctx.send(f"Tonight I'll be listening to {song}")
我已经解决了这个问题,或者至少想出了解决它的方法。我仍然不确定为什么它会在一首歌结束后添加到队列中,但是我用一个try除条件解决了这个问题。我没有使用ctx. voice.client.status
,而是利用了一个错误,如果另一首歌已经在播放,程序在尝试播放一首歌时会返回这个错误。
只需替换您的ctx. Voice.client.status
if语句和
await self.play_song(ctx, song)
await ctx.send(f"Tonight I'll be listening to {song}")
与
try:
await self.play_song(ctx, song)
except ClientException:
queue_len = len(self.song_queue[ctx.guild.id])
self.song_queue[ctx.guild.id].append(song)
return await ctx.send(f"I don't think you can listen to two songs at once. The
song's been added to your queue, position {queue_len+1}.")
当一首歌已经在播放时,程序会引发ClientException
,因此监听此错误可以让我们访问队列,如果一首歌没有播放,那么它将简单地播放这首歌。