Discord Bot使用discord-player添加Spotify歌曲时出现InvalidTrack错误
问题描述
我尝试抓取Spotify播放列表中的所有歌曲并添加到队列时,遇到了InvalidTrack错误。
所用代码
else if (interaction.options.getSubcommand() === "splaylist") { // 使用discord-player搜索播放列表 let url = interaction.options.getString("url") const tracks = await getTracks(url).then(tracks => {return tracks}); // 返回播放列表中前100首歌的数组 console.log(tracks); // tracks包含所有歌曲的信息 async function getResults(track){ // 遍历tracks数组,通过歌名+歌手搜索并添加到队列 const result = await client.player.search(track, { requestedBy: interaction.user, searchEngine: QueryType.AUTO }) if (result.tracks.length === 0) return await interaction.reply(`未找到对应播放列表:${url}`) await queue.addTrack(result.track) // 将歌曲添加到队列 } // 本应遍历每首歌执行函数 await tracks.forEach(track => getResults(track.toString())); }
完整错误信息
InvalidTrack: [InvalidTrack] invalid track at new PlayerError (E:\DiscordMusicBot\node_modules\discord-player\dist\Structures\PlayerError.js:28:15) at Queue.addTrack (E:\DiscordMusicBot\node_modules\discord-player\dist\Structures\Queue.js:235:19) at getResults (E:\DiscordMusicBot\commands\play.js:113:29) at runMicrotasks (<anonymous>) at processTicksAndRejections (node:internal/process/task_queues:96:5) { createdAt: 2022-09-23T14:48:21.556Z, statusCode: 'InvalidTrack' }
解决方法
修复无效的搜索关键词
直接调用track.toString()会把歌曲对象转成[object Object]这种无效字符串,导致搜索不到正确歌曲。需要从track对象中提取有效信息,比如歌名+歌手:// 假设track对象有title和artists字段,根据实际返回结构调整 await getResults(`${track.title} - ${track.artists[0].name}`);解决异步遍历的问题
forEach不支持异步等待,await tracks.forEach(...)不会等所有歌曲添加完成就继续执行,改用for...of循环:for (const track of tracks) { await getResults(`${track.title} - ${track.artists[0].name}`); }确保搜索到有效歌曲
检查搜索结果的第一首歌是否存在,避免添加空值触发错误:async function getResults(trackQuery){ const result = await client.player.search(trackQuery, { requestedBy: interaction.user, searchEngine: QueryType.AUTO }) if (result.tracks.length === 0) { console.log(`未找到歌曲:${trackQuery}`); return; } const validTrack = result.tracks[0]; await queue.addTrack(validTrack); }更简单的批量添加方式
discord-player支持直接解析Spotify播放列表URL并批量添加,没必要手动遍历,直接用下面的代码替代原有逻辑:else if (interaction.options.getSubcommand() === "splaylist") { const url = interaction.options.getString("url"); const result = await client.player.search(url, { requestedBy: interaction.user, searchEngine: QueryType.SPOTIFY_PLAYLIST }); if (result.tracks.length === 0) { return interaction.reply(`未找到对应播放列表:${url}`); } await queue.addTracks(result.tracks); interaction.reply(`已添加${result.tracks.length}首歌到队列`); }
内容的提问来源于stack exchange,提问作者vixitu
相关产品推荐
相关产品推荐

