LineBot網路MP3播放器

之前寫了一篇「LineBot千里傳音」,讓7688播放Line傳來的文字訊息,今天再將它修改一下,讓我們可以透過Line看到7688記憶卡上的mp3歌曲,並網路遠端選歌播放,停止播放音樂。另外,也可以透過Line輸入某個網路上的mp3的連結點,7688收到後便可以自動下載音樂儲存到記憶卡上播放。至於這個可以應用在什麼地方?在辦公室就可以播放音樂給在教室的學生聽、在教室可以控制全校的音樂播放系統,或是神不知鬼不覺的播放恐佈音樂嚇人?這些似乎都可以用這個功能來達成。真心覺得有作業系統的開發板其實也很方便的,如果用Raspberry PI來做的話應該也可以達到更多功能,但以大小來說,7688小巧一些,麻雀雖小,五臟俱全......

7688外接USB音效卡,並加上喇叭,如果用自製的喇叭音箱,把板子都藏在音箱裡就更棒了

也可以把喇叭換成耳機的型式

LineBot遠端MP3播放的相關步驟請參考以下步驟:

一、將7688的LineBot環境設定好,安裝localtunnel,以及python的相關套件,請參閱之前的文章「如何將LineBot裝在7688上」。

二、準備USB音效卡,或是有7688的grove擴展板,上面也有音源接孔也行,安裝驅動程式,此步驟請參閱之前的文章「用LineBot千里傳音」。

三、準備一張記憶卡,建立一個music的資料夾,裡面可以先放上幾首mp3,歌曲的檔名請依序用數字當主檔名,例如第一首歌叫1.mp3,第二首叫2.mp3,依此類推,並將這個記憶卡插入7688的記憶卡擴充槽中,這個記憶卡會被7688自動mount到/tmp/run/mountd/mmcblk0p1/這個資料夾上。

準備MicroSD卡,建立music資料夾,並放入幾首歌曲

四、建立停止播放的指令檔:

1.在/root/app下,建立一個執行檔,檔名叫做stopMp3,這個指令檔是要給python呼叫的外部指令,用來停止目前播放的mp3用的,檔案內容如下:

ps | grep 'playMp3 ' | grep -v grep | awk '{print$1}' | xargs kill -9
ps | grep 'aplay -D' | grep -v grep | awk '{print$1}' | xargs kill -9
ps | grep 'madplay ' | grep -v grep | awk '{print$1}' | xargs kill -9

2.建立完成後要記得將這個檔案變成可執行,指令:chmod 744 stopMp3

五、建立改換歌曲的指令檔:

1.在/root/app下,建立一個執行檔,檔名叫做playMp3,這個指令檔是要給python呼叫的外部指令,用來停止目前播放的mp3歌曲,並換過新選取的歌曲並播放,檔案內容如下:

ps | grep 'aplay -D' | grep -v grep | awk '{print$1}' | xargs kill -9
ps | grep 'madplay ' | grep -v grep | awk '{print$1}' | xargs kill -9
madplay ${1} -o wave:- | aplay -D plughw:1,0 &

2.建立完成後要記得將這個檔案變成可執行,指令:chmod 744 playMp3

六、在/root/app底下建立line_mp3.py這支程式,程式碼內容如下:

# coding=utf-8
import requests,os
import subprocess,time
from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

#這邊的port可以修改成你要想run的port
myPort=8090

myPath='/tmp/run/mountd/mmcblk0p1/music/'
myFilesStr=''
mp3_counts=0
for file in os.listdir(myPath):
    if file.endswith(".mp3"):
       myFilesStr+=(file+'\n')
       mp3_counts+=1

app = Flask(__name__)

#請修改以下的程式,加入自己Line的channelAccessToken以及channelSecret
line_bot_api = LineBotApi('這裡改成自己Line的channelAccessToken')
handler = WebhookHandler('這裡改成自己Line的channelSecret')

@app.route("/", methods=['POST'])
def index():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    myText=event.message.text;
    global myFilesStr
    global mp3_counts
    if myText=='stop':
       subprocess.call(os.getcwd()+'/stopMp3 &' ,shell=True)
       line_bot_api.reply_message(event.reply_token,TextSendMessage(text=u'已停止播放歌曲!'))
    elif myText.startswith('http://') or myText.startswith('https://'):
       r = requests.get(myText, stream=True)
       userId=event.source.user_id
       line_bot_api.reply_message(event.reply_token,TextSendMessage(text=u'正在下載MP3,請耐心等候,並在下載結束前勿執行其他指令!'))
       with open(myPath+str(mp3_counts+1)+'.mp3', 'wb') as f:
          try:
             for block in r.iter_content(1024):
                 f.write(block)
             f.close()
             mp3_counts+=1
             myFilesStr+=(str(mp3_counts)+'.mp3\n')
             line_bot_api.push_message(userId, TextSendMessage(text=(u'已下載完畢,儲存為'+str(mp3_counts)+'.mp3')))
          except KeyboardInterrupt:
             pass
    elif myText.isdigit()!=True:
       line_bot_api.reply_message(event.reply_token,TextSendMessage(text=(myFilesStr+u'輸入歌名數字,即可遠端播放MP3!\n輸入stop可停止播放歌曲!')))
    else:
       if os.path.exists(myPath+myText+'.mp3'):
          line_bot_api.reply_message(event.reply_token,TextSendMessage(text=u'正在播放'+myText+'.mp3'))
          subprocess.call(os.getcwd()+'/playMp3 '+myPath+myText+'.mp3 &',shell=True)
       else:
          line_bot_api.reply_message(event.reply_token,TextSendMessage(text=u'沒有'+myText+u'.mp3這首音樂!'))

if __name__ == "__main__":
    app.run(host='0.0.0.0', port= myPort)

七、執行下列指令,將程式run起來,並且透過localtunnel讓Line識別得到這片7688,localtunnel取得的網址,必須要在Line上重新設定,相關步驟請參閱前一篇文章「如何將LineBot裝在7688上」的步驟六、七。

  • python line_mp3.py &
  • lt --port 8090 --subdomain XXXXX &

八、大功告成,現在透過Line傳送文字給7688上的LineBot時,便會顯示MP3歌曲,輸入數字便可以播放歌曲了。