我正在尝试创建一个播放音乐的不和谐音乐机器人。下面代码的机器人根本不播放音乐(但成功加入)。
我认为使用youtube_dl提取信息和获取URL的代码是正确的。我可以打开它提取的URL,这是我想播放的正确歌曲。但是当它运行到以下行时:self.voice.play(discord. FFmpegPCMAudio(yt_url,**self.FFMPEG_OPTIONS),后=lambda e:self.play_next())
似乎机器人卡在那里,根本不播放任何声音。
顺便说一下,当我只执行join
命令时,机器人也会显示语音活动,所以这也很奇怪。
这是我所有与此相关的代码:
@commands.command(description="Join the channel", aliases=['j'])
async def join(self, ctx):
if ctx.message.author.voice is not None:
try:
channel = ctx.message.author.voice.channel
self.voice = ctx.guild.voice_client
if self.voice and self.voice.is_connected(): # User in voice channel & Bot also in voice channel somewhere else maybe.
await self.voice.move_to(channel)
else:
self.voice = await channel.connect()
await ctx.send(f"Joined {channel}.")
except:
await ctx.send("Failed to join the channel with unexpected error.")
else:
await ctx.send("You must join a voice channel first.")
# search function
def yt_search(self, keywords):
with YoutubeDL(self.YDL_OPTIONS) as ydl:
try:
info = ydl.extract_info(f"ytsearch:{keywords}", download=False)['entries'][0]
print(info)
# print(info['entries'][0])
# return 251/250/249/140/171 otherwise the first one
all_options = info['formats'] # all dicts
# create a dict for high quality url if available
high_quality_dict = {}
for option in all_options:
print(option)
if option['format_id'] == '249' or option['format_id'] == '250' or option['format_id'] == '251' or \
option['format_id'] == '140' or option['format_id'] == '171':
high_quality_dict[option['format_id']] = option['url'] # throw it into dictionary
# check the high quality one
if '251' in high_quality_dict:
return high_quality_dict['251']
elif '250' in high_quality_dict:
return high_quality_dict['250']
elif '249' in high_quality_dict:
return high_quality_dict['249']
elif '140' in high_quality_dict:
return high_quality_dict['140']
elif '171' in high_quality_dict:
return high_quality_dict['171']
else: # if no high quality
return all_options[0]['url']
except:
return False
# play next func
def play_next(self):
with open('resources/server_playlist.json', 'r') as f:
current_playlist = json.load(f)
current_playlist[self.str_guild_id].pop(0) # pop the one just played
if len(current_playlist[self.str_guild_id]) > 0:
yt_url = current_playlist[self.str_guild_id][0]
self.voice.play(discord.FFmpegPCMAudio(yt_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
else:
self.is_playing = False
# play command
@commands.command(description="Play music from youtube", aliases=['p', 'listen'])
async def play(self, ctx, *, args):
search_words = " ".join(args)
if ctx.author.voice is not None:
song = self.yt_search(search_words)
if song is False: # failed to achieve url in the search step
await ctx.send("Failed to load the song. Unexpected error.")
else:
self.str_guild_id = str(ctx.guild.id)
with open('resources/server_playlist.json', 'r') as f:
server_playlist = json.load(f)
# check whether server_id is in the json
if self.str_guild_id not in server_playlist:
server_playlist[self.str_guild_id] = list()
# add the songs into queue
server_playlist[self.str_guild_id].append(song)
with open('resources/server_playlist.json', 'w') as f:
json.dump(server_playlist, f, indent=4)
# check if the bot currently is playing then connect to vc.
if self.is_playing is False:
yt_url = server_playlist[self.str_guild_id][0]
print(yt_url)
# join voice channel
self.voice = ctx.guild.voice_client
self.channel = ctx.author.voice.channel
if self.voice and self.voice.is_connected(): # User in voice channel & Bot also in voice channel somewhere else maybe.
await self.voice.move_to(self.channel)
else:
self.voice = await self.channel.connect()
self.is_playing = True
print("before playing")
# play the music (**Having Problem!!!**)
self.voice.play(discord.FFmpegPCMAudio(yt_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
# self.voice.is_playing()
else:
await ctx.send(f"{ctx.author.name}: Please join a voice channel first!")
在询问了来自不和谐服务器discord.py人之后,我应该包括为windows安装的ffmpeg,尽管我设置了下载=False
。
我还需要添加可执行文件=