更新日: 2020-12-23
Google Home(2019年にGoogle Nestというブランドに改称)にしゃべりかけると応答してくれるのはとても便利です!我が家でも、天気を聞いたり、エアコンをつけたり、電気を消したり、色々とGoogle Homeを活用しています。
が、そんなに賢いなら自分で能動的にしゃべって色々教えて下さいよ!!
と思ってしまうのは私だけではないでしょう!
今回は、Pythonを使ってGoogle Homeに任意のテキストを音声としてしゃべってもらえるようにしたいと思います。
- この記事で紹介している方式は、2020年11月頃のgoogle TTS APIの仕様変更により利用できなくなりました。もともとは、google TTS APIはGETリクエストで利用できていたものが、POSTリクエストに変更され、pychromecastのメソッドにURLを渡すだけではaudioファイルをダウンロードできなくなったためです。詳しくは、Switch to the newer Google TTS APIを参照ください。
なぜ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 TTS APIから、mp3音声ファイルをダウンロードするためのURLを生成し、Castv2というプロトコルを使ってGoogle Homeに通知します。
音声ファイルのダウンロードURLを受け取ったGoogle Homeは、Google TTS APIに対して、リクエストを発行し、実際に音声ファイルをダウンロードして再生する、という動きになります。
参考記事はこちら。
PythonでgTTS+PyChromecast+WEBサーバを用いて実装!
一方で、Pythonを使ったものは結構面倒な実装しかありませんでした。
これも絵にしてみるとこんな感じです。
この実装では、まず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アプリのデバイスの設定画面の一番下で確認することができます。
あとは、ここで作成した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にしゃべらせている動画を載せます。
我が家のGoogle Home が好きなことをしゃべるようになりました😁
— まきたっと (@Makitat_tech) January 30, 2020
何に使えるのかって言うと
・遠隔から家族に話しかける
・アレクサを呼ぶ
・英語の発音の練習
・子供とおしゃべりさせて遊ぶ
・テキストを読み込んで音読させる
・風邪などで声が出ないとき
など、応用すればそこそこ使えるかな😅 pic.twitter.com/Rr0qsVTryr
PythonでGoogle Homeをしゃべらせてみよう!
gTTS v2.1.0以降では、今までNode.jsでしかできなかった構成で、PythonでもGoogle Homeにしゃべらせられるようになりました!
これでわざわざnodeをインストールすることなく、Pythonで好きなテキストをGoogle Homeにしゃべらせることができます。
Pythonは、あらかじめインストールされている環境が多いので、わざわざnodeをインストールしたくない!という人や、Pythonが得意な機械学習と組み合わせてAIっぽくしゃべらせてみたい!という人は、この記事で紹介する方法でGoogle Homeにおしゃべりさせてみてください!