Discord.js音乐机器人ytdl-core流播放无声音问题排查
问题原因
ytdl()方法返回的是Node.js可读流对象,不是Promise,你此处添加的await属于错误用法,不会等待流加载完成,仅会直接返回流实例,你写入本地文件时仅捕获到了流初始推送的少量数据,才会出现本地文件仅能播放几秒的问题。- 你在创建AudioResource时指定
inputType为StreamType.Arbitrary不合理,你调用ytdl时已经指定返回opus编码的音频流,直接指定inputType: Voice.StreamType.Opus即可,避免discord.js的转码逻辑出错导致无声音输出。 - 手动设置的
highWaterMark参数逻辑存在风险,不合适的缓存大小会导致流截断或者推送延迟,无特殊需求可以删除该配置,使用ytdl默认的缓存配置即可。 songPlayer.play()本身不是异步方法,添加await没有任何作用。- 你未在代码中将创建的AudioPlayer实例订阅到语音连接对象上,未完成订阅也会出现显示发言但无声音的情况。
修正后代码
const songQueue = queue.get(message.guild.id); let songPlayer = Voice.createAudioPlayer(); // 获取当前服务器的语音连接 const connection = Voice.getVoiceConnection(message.guild.id); let source = ytdl(song.url, { filter: 'audioonly', type: 'opus', requestOptions: { headers: { cookie: process.env.COOKIE } } }) let stream = Voice.createAudioResource(source, { inputType: Voice.StreamType.Opus }) try { songPlayer.play(stream); // 完成播放器订阅 connection.subscribe(songPlayer); } catch(err) { console.log(err); console.log(songPlayer); }
额外排查方案
- 升级
ytdl-core到最新版本,YouTube接口频繁调整,旧版本拉取的流会存在截断问题,也可以切换到社区维护的@distube/ytdl-core分支,适配更新更及时。 - 检查你的
process.env.COOKIE是否过期,无效的Cookie会导致ytdl仅能拉取到前几秒的音频流。 - 确认你使用的
@discordjs/voice版本为v14及以上,旧版本的StreamType枚举定义存在差异。
内容的提问来源于stack exchange,提问作者Shirayuki Yumi
相关产品推荐
相关产品推荐

