Python
gcp

Google Cloud Text-to-SpeechをGoogle Cloud SDKなしのpythonで実行する

はじめに

Google Cloud Platform(GCP)に登録して1年半余り。2018年3月にText-to-Speechリリースされていたが、ようやく試してみた。

なるべく汎用なライブラリでコードを書きたいので、Cloud SDKは使わずに記述した。

ラズパイでも何でも、python環境と必要なライブラリがインストールできていれば動く。

pythonプラグラム

参考文献

Text-to-Speechのjson記述を参考にしたが、下手に自分のうまくいっている別プログラムを流用したことで正しく実装できず、、、

いろいろ情報を探すと、curlで成功している事例を見つけたので、そこからjsonがらみのコードを起こした。curlの記述をpythonコードに変換してくれる情報をググったらドンピシャのサイトがあって、大前進。

結局、Text-to-Speechで参照できるjson記述を素直に使えばよかったというオチ。。。

ライブラリ

ライブラリはrequestsを使用。音を鳴らすために、mpg321をラズパイにインストールした。

sudo apt install mpg321

auth key情報

GCPの自分のAPI key情報を、gcpapikey.pyに記載する。

gcpapikey.py
str_api_key = "1234567890ABCDEFGHIJKLMNOPQRSTUVXYZ"

メインプログラム側で、gcpapikey.pyの変数をimportする。

from gcpapikey import(
    str_api_key
)

GCPアクセス

お決まりの記述があり、使用するAPIでURLが変わる。key=の後ろにAPI key情報をつけるのがお約束。このURLとヘッダの記述は、参考文献で分かった。

    str_url = "https://texttospeech.googleapis.com/v1beta1/text:synthesize?key="
    str_headers = {'Content-Type': 'application/json; charset=utf-8'}
    url = str_url + str_api_key

jsonデータ

ここが一番悩んだところ。以下でOKになった。これは日本語の発話用。audioEncodingはLINEAR16もあるようだが、試していない。

    str_json_data = {
        'input':{
            'text':text
        },
        'voice':{
            'languageCode': 'ja-JP',
            'name': 'ja-JP-Wavenet-A',
            'ssmlGender':'FEMALE'
        },
        'audioConfig':{
            'audioEncoding':'MP3'
        }
    }

リクエストを投げる

これもお決まりの記述。jsonデータを整形して、指定のURLにヘッダをつけて投げる。この書式は大体のものに使えるのが分かってきた。

    jd = json.dumps(str_json_data)
    #print(jd)
    print("begin request")

    s = requests.Session()
    r = requests.post(url, data=jd, headers=str_headers)

    print("status code : ", r.status_code)
    print("end request")

音声ファイルの再生

ステータスコードが200ならアクセス成功! jsonデータのaudioContentを抜き出して、base64でデコード、data.mp3に保存してmpg321に渡す。

    if r.status_code == 200:
        parsed = json.loads(r.text)
        with open('data.mp3', 'wb') as outfile:
            outfile.write(base64.b64decode(parsed['audioContent']))
            mpg321 = ['mpg321','data.mp3']
            wr = subprocess.Popen(mpg321)

        return r.text
    else:
        return "error"

作成結果

プログラム全体は以下。あらかじめ準備したテキストファイルを読み込んで、読み上げる。

gglt2s.py
#coding:utf-8
import base64
import json
import requests
import sys
import subprocess

from gcpapikey import(
    str_api_key
)

def getRecogSpeech(text):

    str_url = "https://texttospeech.googleapis.com/v1beta1/text:synthesize?key="
    str_headers = {'Content-Type': 'application/json; charset=utf-8'}
    url = str_url + str_api_key

    str_json_data = {
        'input':{
            'text':text
        },
        'voice':{
            'languageCode': 'ja-JP',
            'name': 'ja-JP-Wavenet-A',
            'ssmlGender':'FEMALE'
        },
        'audioConfig':{
            'audioEncoding':'MP3'
        }
    }

    """
    # save to file:
    with open('postdata.json', 'w') as f:
        json.dump(str_json_data, f)
    """

    jd = json.dumps(str_json_data)
    #print(jd)
    print("begin request")

    s = requests.Session()
    r = requests.post(url, data=jd, headers=str_headers)

    print("status code : ", r.status_code)
    print("end request")

    if r.status_code == 200:
        parsed = json.loads(r.text)
        """
        print (r.text)
        print (parsed)
        print('parsed:{}'.format(parsed['audioContent']))
        with open('data.json', 'w') as outfile:
            json.dump(parsed, outfile, sort_keys=True, indent=2)
        """
        with open('data.mp3', 'wb') as outfile:
            outfile.write(base64.b64decode(parsed['audioContent']))
            mpg321 = ['mpg321','data.mp3']
            wr = subprocess.Popen(mpg321)

        return r.text
    else:
        return "error"

if __name__ == '__main__':

    args =sys.argv

    if len(args) < 2:
        print("Usage: python gglt2s.py <text file>")
        exit()
    else:
        pass

    text = open(args[1], 'r').read()
    getRecogSpeech(text)

発話

以下を実行し、テキストファイルtestj.txtに記載した文章が発話されることを確認した。英単語や固有名詞も、自然なイントネーションでうまく読めていた。発話はgoogleのスマートスピーカと同等の品質のはず。

$ python3 gglt2s.py testj.txt

さいごに

Text-to-Speechで発話できるようになったので、IoTデバイスの情報や画像認識結果を音声で伝えるとか、出力のインターフェースが広がった。

GCPCloud Vision APIを使って、ラズパイカメラで画像認識、結果を発話するとか、できそう。