【Webサーバ不要】PythonでGoogle Home(Nest)に任意のテキストをしゃべらせてみる!

スピーカー

Google Home(2019年にGoogle Nestというブランドに改称)にしゃべりかけると応答してくれるのはとても便利です!我が家でも、天気を聞いたり、エアコンをつけたり、電気を消したり、色々とGoogle Homeを活用しています。

が、そんなに賢いなら自分で能動的にしゃべって色々教えて下さいよ!!

と思ってしまうのは私だけではないでしょう!

今回は、Pythonを使ってGoogle Homeに任意のテキストを音声としてしゃべってもらえるようにしたいと思います。

 

なぜPythonを使うのか??

今回はPythonを使って、Google homeに喋らせてみます。

なぜPythonを使うのかというと、Windows WSLでも、ChromeOS Linuxでも、CentOSでも、UbuntuでもPythonはデフォルトでインストールされていることが多く、追加でパッケージをインストールする必要がないことが一つ。

もう一つは、機械学習などが得意なPythonで実装できれば、将来的に人工知能っぽくGoogle Homeに喋らせやすいのでは?と思ったことです。

個人的に仕事でPythonばかり使っているので、なんとかPythonで実装したかった!というのも大きな理由です。

もちろん、次で紹介するようにnodeで実装する方法もあります!が、追加でnodeをインストールする必要もあるので、すでにpythonが使える環境があるのであれば、ここの記事で紹介する方法のほうがお手軽にできます!

 

既存の実装例を解説

すでにGoogle Homeに自発的に喋らせることを実現している人はいっぱいいますので、既存の実装例ということで二つ紹介したいと思います!

Node.jsのgoogle-home-notifierを使う

有名なのは、node.jsのgoogle-home-notifierを使った実装例です。google-home-notifierは、Google TTS (Text To Speech)  APIにアクセスするURLの生成からGoogle Home へのキャストまで全部やってしまう結構便利なライブラリです!

分かりやすくするために、google-home-notifierの内部動作を絵にしてみました。

google home notifierの構成

google-home-notifierは、Google TTS APIからmp3音声ファイルをダウンロードするためのURLを生成し、Castv2というプロトコルを使ってGoogle Homeに通知します。

音声ファイルをダウンロードを受け取ったGoogle Homeは、Google TTS APIに対して、リクエストを発行し、実際に音声ファイルをダウンロードして再生する、という動きになります。

参考記事はこちら。

 

PythonでgTTS+PyChromecast+WEBサーバを用いて実装!

一方で、Pythonを使ったものは結構面倒な実装しかありませんでした。

これも絵にしてみるとこんな感じです。

google home download from local web server

この実装では、まずGoogle TTS APIを用いて、mp3音声ファイルをダウンロードし、ローカルに保存しておきます。そして、一時的にローカルにWebサーバを立ち上げ、ダウンロードしたmp3ファイルをhttpでダウンロードできるようにしてあげます。

その上で、ダウンロードURLをGoogle Homeに通知して、Google Homeにmp3ファイルを再生させます。

音声ファイルのダウンロードが二回もある上に、ローカルでWEBサーバを立ち上げないといけないので、かなり面倒ですね。

参考にしたのは以下のページです。

 

 

Pythonを使ったWebサーバ不要の実装

今回の記事で目標とする実装は、Pythonでgoogle-home-notifierのようなシンプルな構成で実装することです!

Pythonを使ってnode.jsのgoogle-home-notifierのような実装するためには、PythonのgTTSライブラリの実装に問題がありました。

何が問題だったかというと、google TTS APIのURLが取得できない(できなかった)ということ!!音声ファイルをダウンロードしてローカルに保存することしかできませんでした。

 

Python gTTSライブラリにPR出して修正

ということで、今回この記事を書くために、gTTSのオーナーさんに直接修正のPRを出して、URLを取得できるようにしてもらいました。実際に出したPRはこれ。

オーナーさんの本業が忙しかったようで、マージされるまで時間がかかりましたが、gTTSのv2.1.0以降では、get_urls()というメソッドでURLを取得できるようになっています。

 

pychromecastとgTTSの使い方

まず実装のサンプルは、以下のページで公開しています。

以下でこの公開しているコードを少し詳しく解説します。

まずは、pychromecastとgTTSをimportします。

import pychromecast
from gtts import gTTS

pychromecastは、Google Home に音声ファイルをキャストするためのライブラリで、gTTSは、Google TTS APIを用いて、テキストを音声ファイルに変換するためのものです。

まずは、pychromecastを使って、chromecast用のクライアントを作成します。今回は以下のように書いてみました。なお、ここのコードは以下の記事を参考にしています。

def get_speaker(ip_addr=None, name=None):
    if ip_addr:
        return pychromecast.Chromecast(str(ip_addr))

    speakers = pychromecast.get_chromecasts()
    if len(speakers) == 0:
        print('No devices are found')
        raise Exception
    if name:
        return next(s for s in speakers if s.device.friendly_name == name)
    return next(speakers)

ip_addrが渡された場合には、固定IPでGoogle Homeを指定します。IP指定の場合は、pychromecast.Chromecast(ip)のように記述します。

ip_addrではなくnameが渡された場合は、pychromecast.get_chromecasts()で返ってきたリストのうち、device.friendly_nameが一致するものを選択して返します。

Google Homeに割り振られているIPの調べ方ですが、Google Homeアプリのデバイスの設定画面の一番下で確認することができます。

Google Home IPアドレス 確認方法

あとは、ここで作成したchromecastクライアントのplay_mediaというメソッドを使うと音声ファイルを再生させることができます。

speaker.media_controller.play_media(url, 'audit/mp3')

urlには、mp3音声ファイルのダウンロードURLを渡します。

ここで渡すurlを生成するために、gTTSライブラリを使用します。使い方は、以下のような感じです。

tts = gTTS(text=text, lang=lang)
urls = tts.get_urls()

上にも書きましたが、gTTS v2.0以前では、このget_urls()というメソッドがなく、URLを生成することができませんでしたが、v2.1.0以降では、URLを生成することができるようになっています。

get_urls()のメソッドが返すのは、URLのリストになっています。

これはなぜかというと、無償でGoogle TTS APIを使う場合の制限として、一度のAPIリクエストでは100文字までしか音声ファイル化できないため、長いテキストの場合には、複数のAPIリクエストに分割する仕様になっているからです。

短いテキストであれば、リストの要素は一つだけですので、その要素を取り出せばOKです!

これらの処理を一つにまとめて以下のように記述してみました。

def speak(text, speaker, lang='en'):
    try:
        tts = gTTS(text=text, lang=lang)
        urls = tts.get_urls()
        if not speaker.is_idle:
            print("Killing current running app")
            speaker.quit_app()
            time.sleep(5)
        speaker.wait()
        speaker.media_controller.play_media(urls[0], 'audit/mp3')
        speaker.media_controller.block_until_active()
    except Exception as error:
        print(str(error))
        raise Exception

最後に、これを使ってGoogle Homeにしゃべらせている動画を載せます。

 

PythonでGoogle Homeをしゃべらせてみよう!

gTTS v2.1.0以降では、今までNode.jsでしかできなかった構成で、PythonでもGoogle Homeにしゃべらせられるようになりました!

pythonは、あらかじめインストールされている環境が多いので、わざわざnodeをインストールしたくない!という人や、pythonが得意な機械学習と組み合わせてAIっぽくしゃべらせてみたい!という人は、この記事で紹介する方法でGoogle Homeにおしゃべりさせてみてください!

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です