diff --git a/commands/play.js b/commands/play.js index 6e7dd8d..c798110 100644 --- a/commands/play.js +++ b/commands/play.js @@ -42,7 +42,7 @@ module.exports = { } catch (err) { console.error(err) res.setDescription('播放時發生錯誤,可能是因為網址錯誤或是無法播放此網址的音樂\n如果要搜尋,請使用 `/search` 指令') - return interaction.followUp({ embeds: [res] }) + return interaction.editReply({ embeds: [res] }) } } diff --git a/commands/remove.js b/commands/remove.js index 06f3d8b..ae56384 100644 --- a/commands/remove.js +++ b/commands/remove.js @@ -44,8 +44,6 @@ module.exports = { const start = interaction.options.getInteger('起始歌曲編號') ?? 1 const end = Math.min(interaction.options.getInteger('結尾歌曲編號') ?? start, dj.queue.length) - console.log(start, end) - if (start > end) { res.setDescription('結尾怎麼會小於開頭呢?這樣怎麼對?') return interaction.reply({ embeds: [res], flags: MessageFlags.Ephemeral }) diff --git a/commands/resend.js b/commands/resend.js index 86740b0..f06c685 100644 --- a/commands/resend.js +++ b/commands/resend.js @@ -27,6 +27,11 @@ module.exports = { return interaction.reply({ embeds: [res], flags: MessageFlags.Ephemeral }) } + if (!dj.nowPlaying) { + res.setDescription('目前沒有正在播放的歌曲,遙控器沒東西可以遙控') + return interaction.reply({ embeds: [res], flags: MessageFlags.Ephemeral }) + } + await interaction.deferReply({ flags: MessageFlags.Ephemeral }) try { diff --git a/commands/search.js b/commands/search.js index 9b26baa..2b8de5e 100644 --- a/commands/search.js +++ b/commands/search.js @@ -116,7 +116,6 @@ module.exports = { } const index = i.values[0] - message.delete() return results[index] }).catch(() => { message.delete() @@ -127,11 +126,11 @@ module.exports = { if (!result) return try { - dj.playWithAdapter(interaction, result.url, adapter) + await dj.playWithAdapter(interaction, result.url, adapter) } catch (e) { console.error(e) res.setDescription('無法播放此歌曲') - return interaction.followUp({ embeds: [res] }) + return interaction.editReply({ embeds: [res], components: [] }) } } diff --git a/music/GuildMusicManager.js b/music/GuildMusicManager.js index 4c91fd5..338ff1a 100644 --- a/music/GuildMusicManager.js +++ b/music/GuildMusicManager.js @@ -49,7 +49,7 @@ class GuildMusicManager { if (!this.canAutoUnsuppress(interaction)) return if (this.queue.length >= this.maxQueueSize) { - interaction.followUp(`隊列已超過上限 ${this.maxQueueSize} 首,請等待目前的歌曲播放完畢,或是移除一些歌曲後再試`).then(msg => { + interaction.editReply({ content: `隊列已超過上限 ${this.maxQueueSize} 首,請等待目前的歌曲播放完畢,或是移除一些歌曲後再試`, components: [], embeds: [] }).then(msg => { setTimeout(() => msg.delete(), 5000) }) return @@ -71,10 +71,10 @@ class GuildMusicManager { const track = new Track(this.client, inputURL, metadata, interaction.member, adapter) this.queue.push(track) - await interaction.followUp({ embeds: [track.getQueuedEmbed()] }) + await interaction.editReply({ embeds: [track.getQueuedEmbed()], components: [] }) } catch (e) { console.error(e) - return interaction.followUp('目前無法正確播放這首歌曲') + return interaction.editReply({ content: '目前無法正確播放這首歌曲', components: [], embeds: [] }) } if (!this.isPlaying) { @@ -87,7 +87,7 @@ class GuildMusicManager { } async playlistWithAdapter(interaction, query, adapter) { - const message = await interaction.followUp('解析播放清單中,若播放清單過長,可能會花上幾分鐘,請耐心等候......') + const message = await interaction.editReply({ content: '解析播放清單中,若播放清單過長,可能會花上幾分鐘,請耐心等候......', components: [], embeds: [] }) try { const data = await adapter.getBulkTrackInfo(query) @@ -98,10 +98,10 @@ class GuildMusicManager { if (!data.length) { res.setDescription('很遺憾,這個播放清單中沒有我可以播放的樂曲') - return message.edit({ content: '', embeds: [res] }).catch(console.error) + return message.edit({ content: '', embeds: [res], components: [] }).catch(console.error) } - await message.edit('播放清單解析完成,正在加入隊列中......').catch(console.error) + await message.edit({ content: '播放清單解析完成,正在加入隊列中......', components: [], embeds: [] }).catch(console.error) const tracks = data.map(({ inputURL, metadata }) => new Track(this.client, inputURL, metadata, interaction.member, adapter)) const thumbnail = data.find(track => track.metadata.thumbnail)?.metadata?.thumbnail @@ -112,10 +112,10 @@ class GuildMusicManager { if (thumbnail) res.setThumbnail(thumbnail) - await message.edit({ content: '', embeds: [res] }).catch(console.error) + await message.edit({ content: '', embeds: [res], components: [] }).catch(console.error) } catch (e) { console.error(e) - return message.edit('出現未知錯誤,已停止').catch(console.error) + return message.edit({ content: '出現未知錯誤,已停止', components: [], embeds: [] }).catch(console.error) } if (!this.isPlaying) { diff --git a/music/Track.js b/music/Track.js index b106ae5..b288fa4 100644 --- a/music/Track.js +++ b/music/Track.js @@ -31,7 +31,7 @@ class Track { this.startMs = startTimeMs const mediaURL = await this.adapter.getResourceURL(this.inputURL) - const FFMPEG_OPUS_ARGUMENTS = ['-i', mediaURL, '-ss', ~~(this.starTimeMs)/1000, '-analyzeduration', '0', '-loglevel', '0', '-acodec', 'libopus', '-f', 'opus', '-ar', '48000', '-ac', '2'] + const FFMPEG_OPUS_ARGUMENTS = ['-i', mediaURL, '-ss', ~~(this.startMs)/1000, '-analyzeduration', '0', '-loglevel', '0', '-acodec', 'libopus', '-f', 'opus', '-ar', '48000', '-ac', '2'] const RECONNECT_ARGUMENTS = ['-reconnect', '1', '-reconnect_streamed', '1', '-reconnect_delay_max', '5'] const stream = new prism.FFmpeg({ args: [...RECONNECT_ARGUMENTS, ...FFMPEG_OPUS_ARGUMENTS] diff --git a/music/adapters/YoutubeAdapter.js b/music/adapters/YoutubeAdapter.js index 5234792..81d9a87 100644 --- a/music/adapters/YoutubeAdapter.js +++ b/music/adapters/YoutubeAdapter.js @@ -30,7 +30,7 @@ const YoutubeAdapter = { async getBulkTrackInfo(url) { const stdout = await execute('yt-dlp', [ - '-i', '-x', '--dump-json', '--skip-download', '--geo-bypass', '--', url + '--js-runtimes', 'node', '-i', '-x', '--dump-json', '--skip-download', '--geo-bypass', '--', url ]) return stdout.split('\n') @@ -57,6 +57,7 @@ const YoutubeAdapter = { _search(query, limit) { if (isNaN(+limit)) throw Error('limit must be a number') return execute('yt-dlp', [ + '--js-runtimes', 'node', `ytsearch${limit}:${query}`, '--dump-json', '--flat-playlist', @@ -65,11 +66,12 @@ const YoutubeAdapter = { return stdout.split('\n') .filter(line => line.trim()) .map(line => JSON.parse(line)) + .filter(result => result.ie_key === 'Youtube') }) }, getResourceURL(url) { - return execute('yt-dlp', ['-i', '-x', '--get-url', '--geo-bypass', '--', url]) + return execute('yt-dlp', ['--js-runtimes', 'node', '-i', '-x', '--get-url', '--geo-bypass', '--', url]) .then(stdout => stdout.trim()) }, @@ -94,13 +96,13 @@ const YoutubeAdapter = { _getDumpData(url) { return execute('yt-dlp', [ - '-i', '-x', '--dump-json', '--flat-playlist', '--skip-download', '--geo-bypass', '--', url + '--js-runtimes', 'node', '-i', '-x', '--dump-json', '--flat-playlist', '--skip-download', '--geo-bypass', '--', url ]).then(stdout => JSON.parse(stdout)) }, _resolvePlaylistToURL(url) { return execute('yt-dlp', [ - '-i', '-x', '--get-url', '--flat-playlist', '--skip-download', '--geo-bypass', '--', url + '--js-runtimes', 'node', '-i', '-x', '--get-url', '--flat-playlist', '--skip-download', '--geo-bypass', '--', url ]).then(stdout => stdout.split('\n').filter(line => line.trim())) } };