# Discord音樂機器人 ### 前置步驟 1. 安裝python, 記得要包含pip 2. Discord帳號 ### 申請Discord bot 前往 Discord官網 -> 開發人員 -> Application 可以找到應用程式的介面 建立一個新的應用程式後, 可以看到這個頁面 ![](https://i.imgur.com/Qr1DDVH.png) 1. 點入Bot的選項, 可以看到機器人的Token, 點擊 **Click to Reveal Token**可以查看自己機器人的Token, 將Token 儲存下來備用。 2. 點入OAuth2選項, 將**Client ID**的地方也複製下來, 接著利用[這個連結](https://discordapp.com/oauth2/authorize?permissions=301001759&scope=bot&client_id=你的機器人的clientID)把client_id的地方改成你自己的機器人client_id, 就可以將機器人邀請進自己的伺服器了 **注意**\ **機器人的Token不能在網路上洩漏, 一旦洩漏Discord官方會自動幫你重新建立, 到時候就要去自己的程式把Token換掉, 記得在網路上存程式(如: Github)的時候要把Token刪掉。** ### 讓機器人上線並出入語音頻道 利用Windows上的cmd, 輸入下列指令 ``` pip install discord.py ``` 如果這行指令輸入時出現錯誤, 例如說pip不是可以call的指令的話, 請重新安裝(Repair也可以)python, 並記得將pip選入安裝的部分。 安裝完後就可以開始寫程式囉~開啟新的檔案來寫吧 ``` import discord from discord.ext import commands client = commands.Bot(command_prefix = "!") @client.event async def ready_on(): #這裡是機器人上線後預計會執行的程式 print('目前登入身分', client.user) #也可以利用指令, 更改機器人目前在玩的遊戲 game = discord.Game('輸入你想讓機器人顯示的狀態') await client.change_presence(status=discord.Status.idle, activity=game) @client.command() async def join(ctx): #這裡的指令會讓機器人進入call他的人所在的語音頻道 voice = discord.utils.get(client.voice_clients, guild=ctx.guild) if ctx.author.voice == None: await ctx.send("You are not connected to any voice channel") elif voice == None: voiceChannel = ctx.author.voice.channel await voiceChannel.connect() else: await ctx.send("Already connected to a voice channel") @client.command() async def leave(ctx): #離開call他那個伺服器的所在頻道 voice = discord.utils.get(client.voice_clients, guild=ctx.guild) if voice == None: await ctx.send("The Bot is not connected to a voice channel") else: await voice.disconnect() #把你的Token輸入在這邊 client.run("Input Your Token") ``` **注意**\ **這個步驟中可能會缺一些套件, 在cmd使用 "pip install 缺少的套件名稱" 就可以解決** 到這裡為止,已經做好了一個機器人, 並且可以隨意進出call他的使用者所在的語音頻道內了。 ### 讓機器人播放音樂 **重要 : 這個部分請包含上面的程式共同使用** ``` from pytube import YouTube import os def endSong(path): #播放完後的步驟, 進行前一首歌刪除, 抓取一首清單內的歌進行播放 os.remove(path) if len(playing_list) != 0: voice = discord.utils.get(client.voice_clients) url = playing_list[0] del playing_list[0] YouTube(url).streams.first().download() for file in os.listdir("./"): if file.endswith(".mp4"): os.rename(file,"song.mp4") voice.play(discord.FFmpegPCMAudio(executable="ffmpeg/bin/ffmpeg.exe", source="song.mp4"),after = lambda x: endSong("song.mp4")) playing_list = [] async def play(ctx, url :str = ""): #取得目前機器人狀態 voice = discord.utils.get(client.voice_clients, guild=ctx.guild) #如果機器人正在播放音樂, 將音樂放入播放清單 if voice.is_playing(): playing_list.append(url) print(playing_list) await ctx.send("insert song into playing_list") #如果機器人沒在播放, 開始準備要播放的音樂 else: #如果還有找到之前已經被播放過的音樂檔, 進行刪除 song_there = os.path.isfile("song.mp4") try: if song_there: os.remove("song.mp4") except PermissionError: await ctx.send("Wait dor the current playing music to end or use the 'stop' command") #找尋輸入的Youtube連結, 將目標影片下載下來備用 YouTube(url).streams.first().download() #將目標影片改名, 方便找到它 for file in os.listdir("./"): if file.endswith(".mp4"): os.rename(file,"song.mp4") #找尋要播放的音樂並播放, 結束後依照after部分的程式進行後續步驟 voice.play(discord.FFmpegPCMAudio(executable="ffmpeg/bin/ffmpeg.exe", source="song.mp4"),after = lambda x: endSong("song.mp4")) ``` 除了播放之外,一樣重要的便是音樂的操作 1. 音樂暫停 ``` @client.command() async def pause(ctx): voice = discord.utils.get(client.voice_clients, guild=ctx.guild) if voice.is_playing(): voice.pause() else: await ctx.send("Currently no audio is playing") ``` 2. 音樂繼續 ``` @client.command() async def resume(ctx): voice = discord.utils.get(client.voice_clients, guild=ctx.guild) if voice.is_paused(): voice.resume() else: await ctx.send("The audio is not pause") ``` 4. 跳過這首歌 ``` @client.command() async def skip(ctx): voice = discord.utils.get(client.voice_clients, guild=ctx.guild) voice.stop() ``` ### 總結 這次實作完的整套Discord機器人, 程式碼只能在自己電腦上執行, 如果要使用必須要執行電腦上的程式才能使用。 如果要利用其他在網路上的雲端平台來Deploy 你的服務的話, 請千萬不要忘記將Token設定成環境變數,並且將client.run的部分改成取得環境變數來啟動。 另外, 如果使用雲端平台來deploy的話, requirement.txt、runtime.txt 跟 Procfile三個文件是必要的, 請務必參考更多資料再進行實作 最後, 這份程式有一些問題, 例如播放清單的部分沒有解決如果多人同時輸入play的問題, 有可能會播放到其他人的清單, 但因為我是寫給自己用的, 這部分我就沒有特別作修正, 如果要給親朋好友使用的話, 記得要在這裡做一些改動。 參考資料 : [Discord版本問題轉換表](https://discordpy.readthedocs.io/en/stable/migrating.html)、[Discord.py 機器人從0到1超詳細教學](https://hackmd.io/@kangjw/Discordpy%E6%A9%9F%E5%99%A8%E4%BA%BA%E5%BE%9E0%E5%88%B01%E8%B6%85%E8%A9%B3%E7%B4%B0%E6%95%99%E5%AD%B8)、[discord.py - Command raised an exception: OpusNotLoaded](https://stackoverflow.com/questions/55919924/discord-py-command-raised-an-exception-opusnotloaded)、[[Python] 如何開發 Discord 機器人並且部屬至 Heroku](https://fightwennote.blogspot.com/2017/10/python-discord-heroku.html)、[Make a Discord Bot with Python (Part 7: Music Bot) | Latest Discord Py Version](https://www.youtube.com/watch?v=ml-5tXRmmFk)