我在Python制作了一个不和谐的音乐机器人,到目前为止它正在播放音乐。我想添加一个队列功能,这样如果一首歌正在播放,输入的歌曲将在播放完成后播放。机器人下载歌曲,它从请求中获得(不在下面的代码中),并将其重命名为“歌曲. mp3”。然后它开始播放歌曲,完成后它会删除歌曲,以便可以下载新的歌曲,也称为“歌曲.mp3”。我对队列系统的想法是,机器人通过song_queue中的所有网址,当它完成第一个网址时,下载第二个网址,依此类推。当机器人播放时,我需要检查它何时可以移动到下一个文件,为此我使用了,而语音。is_playing
,而导致问题,因为其他命令不再起作用。
song_queue = []
@commands.command()
async def play(self, ctx, *, url: str):
if ctx.author.voice and ctx.author.voice.channel:
channel = ctx.author.voice.channel
if not self.bot_is_connected(ctx):
await channel.connect()
else:
await ctx.send("`You are not connected to a voice channel.`")
if ctx.author.voice and ctx.author.voice.channel:
voice = discord.utils.get(self.client.voice_clients, guild=ctx.guild)
video = get_url(f"{url}")
song_queue.append(video)
song_there = os.path.isfile("song.mp3")
try:
if song_there:
os.remove("song.mp3")
except PermissionError:
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
for song in song_queue:
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([song])
meta = ydl.extract_info(song, download=False)
song_name = (meta["title"])
for file in os.listdir("./"):
if file.endswith(".mp3"):
os.rename(file, "song.mp3")
voice.play(discord.FFmpegPCMAudio("song.mp3"))
while voice.is_playing(): #Makes other commands no longer work
print("playing...")
time.sleep(5)
else:
song_queue.remove(song)
song_there = os.path.isfile("song.mp3")
if song_there:
os.remove("song.mp3")
导致你的其他命令停止工作的是time.睡眠()
的使用。discord.py是一个异步库,这意味着它处理能够同时执行多个功能以确保机器人在使用过程中不被阻止,但是添加一个像time.睡眠()
这样的同步调用会使其停止操作。
当您使用异步库时,最好也寻找其他实用程序的异步版本,这样您就不会陷入在异步操作中使用阻塞同步调用的诱惑。在这种情况下,我建议您使用asyncio.睡眠(5)
来达到您的目的。您还需要导入asyncio
才能使用该函数。
参考资料: