Discord.py music_cog机器人成功加入语音频道但无声音输出且超时退出问题求助
解决Discord.py音乐机器人无声音且超时退出的问题
我之前折腾Discord音乐机器人时也碰到过几乎一模一样的问题!结合你的代码和日志信息,咱们来一步步排查和修复:
1. 优先替换YouTube-DL为yt-dlp
YouTube-DL已经很久没维护了,对现在YouTube的音频格式支持很差,很多时候能拿到URL但无法正常播放。换成yt-dlp(它是YouTube-DL的活跃分支)大概率能解决音频流的问题:
- 先安装yt-dlp:
pip install yt-dlp - 修改你的代码里的导入和YDL配置:
# 替换原来的youtube_dl导入 from yt_dlp import YoutubeDL # 更新YDL_OPTIONS,添加更多兼容参数 self.YDL_OPTIONS = { 'format': 'bestaudio/best', 'noplaylist': True, 'quiet': True, 'extract_flat': False, 'audio-format': 'mp3', 'postprocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': '192', }] }
2. 明确指定FFmpeg的完整路径
即使你说检查过FFmpeg路径,很多时候系统环境变量没配置好,或者代码里没明确指定,会导致Discord.py找不到FFmpeg执行文件。修改FFmpegPCMAudio的调用,加上executable参数:
比如Windows系统:
self.vc.play(discord.FFmpegPCMAudio( m_url, executable="C:/Program Files/ffmpeg/bin/ffmpeg.exe", # 换成你的FFmpeg实际路径 **self.FFMPEG_OPTIONS ), after=lambda e: self.play_next())
Linux/macOS系统:
executable="/usr/bin/ffmpeg" # 或者用`which ffmpeg`查到的路径
3. 修复Voice Client的初始化和状态检查
你的代码里self.vc初始化为空字符串"",这会导致后续的连接状态判断逻辑出错。把初始化改成:
self.vc = None # 而不是空字符串
同时在play_music里完善连接检查:
async def play_music(self): if len(self.music_queue) == 0: self.is_playing = False return self.is_playing = True song_info, voice_channel = self.music_queue[0] m_url = song_info['source'] # 处理语音连接逻辑 if self.vc is None or not self.vc.is_connected(): self.vc = await voice_channel.channel.connect() # 确保机器人有权限说话 if not self.vc.is_playing(): await self.vc.guild.change_voice_state(channel=voice_channel.channel, self_deaf=False, self_mute=False) elif self.vc.channel != voice_channel.channel: await self.vc.move_to(voice_channel.channel) self.music_queue.pop(0) # 添加打印日志,确认音频流是否正常加载 print(f"正在播放: {song_info['title']},音频URL: {m_url[:50]}...") self.vc.play( discord.FFmpegPCMAudio(m_url, executable="你的FFmpeg路径", **self.FFMPEG_OPTIONS), after=lambda e: self.play_next() )
4. 增加调试日志排查问题
你目前的日志只显示连接信息,可以把logging级别调到DEBUG,或者在关键步骤加print语句,比如在search_yt函数里打印获取到的音频URL,确认是否有效;在play_next里打印播放完成或错误信息:
def play_next(self): if len(self.music_queue) > 0: self.is_playing = True m_url = self.music_queue[0][0]['source'] self.music_queue.pop(0) def after_play(error): if error: print(f"播放出错: {error}") self.play_next() self.vc.play(discord.FFmpegPCMAudio(m_url, executable="你的FFmpeg路径", **self.FFMPEG_OPTIONS), after=after_play) else: self.is_playing = False
最后验证步骤
- 确保你的机器人在语音频道里有说话权限,检查服务器角色设置
- 测试时尽量用短的YouTube视频(比如1分钟以内的),避免超时
- 运行机器人时观察控制台输出,看是否有FFmpeg相关的错误提示
按照上面的步骤修改后,应该就能正常播放声音了!
内容的提问来源于stack exchange,提问作者Ozzy
相关产品推荐
相关产品推荐

