我正在开发一个discord机器人,我正在尝试实现一个音乐播放器。我正在使用discord和youtube dl包。这是处理play命令的函数(它仍然是一个原型):
@client.command(brief='Plays the song from the url.')
async def play(ctx, url):
voice = get(client.voice_clients, guild=ctx.guild)
if not voice.is_playing():
try:
if 'song.mp3' in os.listdir(curr_dir):
os.remove(os.path.join(curr_dir, 'song.mp3'))
await download_to_mp3(url)
voice.play(discord.FFmpegPCMAudio(os.path.join(curr_dir, 'song.mp3')))
voice.volume = 100
except youtube_dl.DownloadError:
await ctx.send('Invalid url.')
以及下载到mp3()函数:
async def download_to_mp3(url):
opts = {
'outtmpl': os.path.join(curr_dir, 'song.webm'),
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(opts) as ydl:
ydl.download([url])
我的意思是,当下载完成时,我仍然可以使用bot的其他功能。据我所知,wait语句说“暂停play()函数的执行,在我等待的时候做些别的事情。当下载到mp3完成时,继续”。但是,它似乎读取下载时发出的命令,但仅在下载完成后执行这些命令。如何使其在下载时执行命令
这正是它的工作原理,只要您遵循异步规则,最基本的规则是:在异步期间不要阻塞。因为
YoutubeDL.download
显然是一个阻塞函数(您不需要等待它),所以download_to_mp3
的执行会暂停整个事件循环。仅仅是在download_to_mp3
中没有await
语句这一事实就提示您,该函数只是名义上的异步函数修复它的正确方法是从} ,它将在不同的线程中执行阻塞函数,并返回一个等待对象,该对象将暂停等待器,直到阻塞函数完成。例如:
YoutubeDL
切换到同一类型的异步下载程序(如果存在的话)。如果这不是一个选项,或者如果需要快速修复,可以使用^{相关问题 更多 >
编程相关推荐