iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 23
0
AI & Data

用Node.js製作後台零負擔的DiscordBot系列 第 23

Day23 - 音樂系統的歌單批量載入(額外)

  • 分享至 

  • xImage
  •  

以下文章已於 2021/09/16 轉移至 微笑之家
對於discord.js更新,或是有其他問題,都歡迎到以下網址查看喔
本站
本主題
本文章


昨天我們把音樂系統的多群組支援做好了
今天想講一下怎麼直接導入歌單

首先請在專案目錄下的終端機安裝

npm install ytpl

23-1

安裝完成後,我們打開看package.json

23-2

最後一行出現了ytpl
請到這個網站比對ytpl的版本,如果像筆者一樣版本過低的話,請將package.json內的ytpl版本拉高,然後更新一次ytpl
https://www.npmjs.com/package/ytpl

23-3

官方文檔版本1.0.1

23-4

手動把0.3.0改成1.0.1然後下指令

23-5

npm update ytpl

這樣就會更新你的ytpl函式庫


一安裝完就去確認版本是否最新,是因為舊版本的ytpl在抓取歌單資料時十分不穩,甚至有可能直接被yt擋下

原因不明,但這道理可以套到ytdl-core上,之後同學們有任何問題都可以先更新版本看看


更新好後,我們在bot.js引用ytpl

23-6

在音樂指令底下加入歌單載入功能

23-7

//?playList
async function playListMusic(guildID, msg) {
    try {
        //沒在音樂廳不能使用此功能
        if (!client.voice.connections.get(guildID)) {
            msg.channel.send(`請先正常啟用音樂指令後,再使用歌單載入喔`);
            return false;
        }
        //網址
        const valueED = msg.content.split(' ');
        //先用library自帶的方式檢查一次能不能用
        const canPlay = await ytpl.validateID(valueED[1]);
        //讀取到幾首歌,上限默認100首
        let a = 0;
        //幾首成功放入歌單
        let b = 0;
        if (canPlay) {
            const listED = await ytpl(valueED[1]);
            await listED.items.forEach(async function(element) {
                a = a + 1;
                if (element.title !== '[Deleted video]') {
                    canPlay2 = await ytdl.validateURL(element.url_simple);
                    if (canPlay2) {
                        b = b + 1;
                        musicList.get(guildID).push(element.url_simple);
                    }
                }
            });
            //回傳統計資訊
            msg.channel.send(`歌單 ${listED.title}\n共載入${b}首歌曲\n${a-b}首載入失敗`);
        } else {
            msg.channel.send(`This Url isn't working in function.`);
        }
    } catch (err) {
        console.log(err, 'playListMusicError');
    }
}

由上而下依序說明…

23-8

因為歌單功能僅提供將yt歌單放入bot歌單的功能
正常使用play指令,不在語音廳的情況下是會直接進入語音廳並開始播放歌曲
筆者這邊寫成不能從歌單指令開始播歌

23-9

宣告了四份參數

valueED
第一個單純是使用空白做字串分割,valueED[0]是前綴字+playList
valueED[1]則是一格空白後加上網址

canPlay
使用ytpl自帶的檢查語法,會根據帶入的url回傳布林

a
載入迴圈的每一次都會+1,代表著載入幾首歌

b
載入迴圈的每一次,當成功將歌曲加入歌單時+1,表示成功抓取幾首歌

23-10

當canPlay等於ture後,正式查詢歌單並且將資料回傳給listED
listED底下有一items為JSONArray,他就是歌單的集合
對他使用迴圈,並在迴圈內用ytdl驗證一次網址是否可用
驗證全部通過後將歌曲加入該群組歌單
最後統計數字


因為加入批量歌曲載入的緣故,當機器人在列出queueShow時,極有可能回傳大量文字
discord單封文字的上限數是2000,我們取1900就好

23-11

都好了後,試著運行看看

23-12

23-13

23-14

這樣音樂系統也能做到批量載入音樂了
其餘還剩一些瑕疵,如歌單功能有限制,歌曲詳細資訊載入偏慢,沒有過濾私人影片還有更多可能的問題等…就讓各位自己嘗試看看吧

那音樂系統就教到這,我們明天見


上一篇
Day22 - 音樂系統的多群組化(額外)
下一篇
Day24 - 愛麗絲安靜!
系列文
用Node.js製作後台零負擔的DiscordBot31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
psyhayama
iT邦新手 5 級 ‧ 2022-03-09 14:21:55

您好有兩個問題想請教,
1.我能使機器人撥放音樂後停留於頻道不要進進出出的嗎 ? 該怎麼做
2.跟隨您的教學文章目前已經做出一隻可以正常運行的機器人,
今天在學習使用可以新增playlist功能時遇到問題。

出現

2022-03-09T06:15:08.145269+00:00 app[worker.1]: Logged in as 奈映千雪#1619!
2022-03-09T06:15:10.493143+00:00 app[worker.1]: WARNING: ytdl-core is out of date! Update with "npm install ytdl-core@latest".
2022-03-09T06:15:15.479205+00:00 app[worker.1]: TypeError: Cannot read properties of null (reading '4')
2022-03-09T06:15:15.479216+00:00 app[worker.1]: at Object.exports.getGeneralInfo (/app/node_modules/ytpl/lib/util.js:39:31)
2022-03-09T06:15:15.479217+00:00 app[worker.1]: at module.exports (/app/node_modules/ytpl/lib/firstpage.js:29:25)
2022-03-09T06:15:15.479218+00:00 app[worker.1]: at runMicrotasks (<anonymous>)
2022-03-09T06:15:15.479218+00:00 app[worker.1]: at processTicksAndRejections (node:internal/process/task_queues:96:5)
2022-03-09T06:15:15.479219+00:00 app[worker.1]: at async module.exports (/app/node_modules/ytpl/lib/main.js:13:20)
2022-03-09T06:15:15.479219+00:00 app[worker.1]: at async playListMusic (/app/bot.js:323:28) playListMusicError

附上code

//?playList
async function playListMusic(guildID, msg) {
    try {
        //沒在音樂廳不能使用此功能
        if (!client.voice.connections.get(guildID)) {
            msg.channel.send(`請先正常啟用音樂指令後,再使用歌單載入喔`);
            return false;
        }
        //網址
        const valueED = msg.content.split(' ');
        //先用library自帶的方式檢查一次能不能用
        const canPlay = await ytpl.validateID(valueED[1]);
        //讀取到幾首歌,上限默認100首
        let a = 0;
        //幾首成功放入歌單
        let b = 0;
        if (canPlay) {
            const listED = await ytpl(valueED[1]);
            await listED.items.forEach(async function(element) {
                a = a + 1;
                if (element.title !== '[Deleted video]') {
                    canPlay2 = await ytdl.validateURL(element.url_simple);
                    if (canPlay2) {
                        b = b + 1;
                        musicList.get(guildID).push(element.url_simple);
                    }
                }
            });
            //回傳統計資訊
            msg.channel.send(`歌單 ${listED.title}\n共載入${b}首歌曲\n${a-b}首載入失敗`);
        } else {
            msg.channel.send(`This Url isn't working in function.`);
        }
    } catch (err) {
        console.log(err, 'playListMusicError');
    }
}

謝謝

我要留言

立即登入留言