python - 带有歌曲队列的 Python 不和谐音乐机器人
问题描述
我正在用 Python 制作一个不和谐的音乐机器人,到目前为止它还在播放音乐。我想添加一个队列功能,以便如果此刻正在播放歌曲,则输入的歌曲将在播放完毕后播放。机器人下载歌曲,它是从请求中获得的(不在下面的代码中),并将其重命名为“song.mp3”。然后它开始播放歌曲,完成后删除歌曲,以便可以下载新歌曲,也可以称为“song.mp3”。我对队列系统的想法是,机器人会遍历 song_queue 中的所有 url,当第一个完成后,下载第二个,依此类推。机器人在玩的时候,while voice.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.sleep()
. discord.py是一个异步库,这意味着它可以同时执行多个功能,以确保机器人在使用过程中不会被阻塞,但是添加一个同步调用time.sleep()
会使其停止操作。
当您使用异步库时,最好同时查找其他实用程序的异步版本,这样您就不会陷入在异步操作中使用阻塞同步调用的诱惑。在这种情况下,我建议您将其asyncio.sleep(5)
用于您的目的。您还需要import asyncio
使用该功能。
参考:
推荐阅读
- laravel - 使用 Laravel Passport(隐式授予令牌)成功 Oauth 后正确重定向到 Vue SPA
- c# - 如何使用 FFMPEG 传递参数
- python - 定义不带@的修饰函数
- flutter - 无法加载源“dart:_http/http_impl.dart”:
- .net - ZAP 的桌面应用程序代码审查
- kubernetes - Vsphere 虚拟机中的 Kubernetes
- powershell - 使用 powershell 查找全局可写文件
- python - Ansible/Jinja2 错误:没有名为“地图”的过滤器
- cucumber - 特定条件后跳过步骤
- sql - 分析函数 SUM 返回具有相同值的窗口的平均值