用LineBot千里傳音

今天的要介紹的應用其實沒啥很大的實用性,但我覺得很好玩,所以就做了。Line是文字的訊息溝通,但是,如果我在Line上打的文字訊息傳給LineBot,LineBot能幫我唸出來的話,就會成為一個遠端的喊話系統或是成為網路大聲公。Google、IBM、微軟以及亞馬遜都有提供文字轉語音的功能,在這裡,我請到google姐來幫我把文字訊息轉為語音。google姐的聲音google不讓人直接抓取,甚至要付費,還好網路上有人做了這個抓取google姐聲音的服務,以下舉個例子,如果希望聽到google姐唸出「你好嗎」,可以在瀏覽器輸入以下的網址

如果想要聽別的句子的聲音,只要把上面連結的「你好嗎」改成別的句子就可以了,至於language則可以指定語言編碼,zh-tw則是繁體中文的編碼,所以以上的連結其實只要修改query以及language的參數,就可以聽到各國語言的聲音。相關語言的編碼,可以參考我之前的文章「LineBot多國語言翻譯」。

聯發科的7688其實就是一個很小的嵌入型系統,內部有作業系統可以做視訊串流、播放mp3,以及執行python、node.js等程式,所以把LineBot程式放在7688裡,Line傳來的文字透過網路下載google姐的聲音播放,就可以透過Line呼叫遠端的7688播放傳過去的文字的聲音了。

利用7688上的LineBot實作千里傳音功能

相關的步驟請參考:

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

二、準備USB音效卡,或是有7688的grove擴展板,上面也有音源接孔也行。

USB的音效卡加上OTG的線,插入7688的USB HOST的接孔

USB音效卡,喇叭線插入耳機插孔中

若有7688的grove擴展板,上面也有耳機插孔可用

三、若使用的是USB音效卡,需要在7688上安裝驅動程式。先用ssh登入7688:

1、安裝驅動程式

  • opkg update
  • opkg install kmod-usb-audio

2、執行以下指令,如果有看到如下的USB Audio Device的東西,表示音效卡已安裝完成

  • aplay -l

3、試試看是否能正常播放mp3音樂,音效卡播放mp3的指令

  • madplay stream.mp3 -o wave:- | aplay -D plughw:1,0

以上指令以播放stream.mp3這個檔案為例,若要播放其他mp3請自行修改,並將mp3的檔案傳上7688試播。

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

# coding=utf-8
import requests
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

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'

#當收到Line傳來的文字訊息後,將該文字訊息合併進要下載google姐聲音的網址內成為stream_url這個字串
#python連結進該網址將stream的聲音儲存成stream.mp3
#然後python呼叫外部指令madplay stream.mp3 -o wave:- | aplay -D plughw:1,0播放聲音
#最後再將傳來的文字回傳給Line,表示已經收到,並且已播放聲音完畢
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    stream_url = 'https://google-translate-proxy.herokuapp.com/api/tts?query='+event.message.text+'&language=zh-tw'
    r = requests.get(stream_url, stream=True)
    with open('stream.mp3', 'wb') as f:
       try:
          for block in r.iter_content(1024):
              f.write(block)
          f.close()
          subprocess.call('madplay stream.mp3 -o wave:- | aplay -D plughw:1,0',shell=True) 
       except KeyboardInterrupt:
          pass
    line_bot_api.reply_message(event.reply_token,TextSendMessage(text=event.message.text))


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

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

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

六、大功告成,現在透過Line傳送文字給7688上的LineBot時,7688就會轉成聲音訊息播放了。