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に通知します。

音声ファイルのダウンロードURLを受け取った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にしゃべらせられるようになりました!

これでわざわざnodeをインストールすることなく、Pythonで好きなテキストをGoogle Homeにしゃべらせることができます。

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

  • 宮崎空港で買える オススメ美味しいお土産ランキング!宮崎空港で買える オススメ美味しいお土産ランキング! 妻の実家が宮崎の都城市なので、宮崎空港を利用する機会がとても多くなりました。宮崎は、地鶏、宮崎牛、マンゴーなどなど美味しいものがたくさん!!そんな宮崎の出入り口である宮崎空港で買える美味しいお土産を個人的ランキング形式で1〜5位までご紹介したいと思います! 宮崎空港のお土 […]
  • 【体験談】ひと味違う結婚式を目指して!私達の結婚式準備&演出!【体験談】ひと味違う結婚式を目指して!私達の結婚式準備&演出! 今回は私たちが実際にやった結婚式準備・演出をご紹介します! これから結婚式の準備を始めるプレ花さんの中には、 準備なにしよう? なんか面白い演出ないかな? と考えている人も多いと思います!この記事はそんなプレ花さんの参考になること間違いなしです! 注)「プレ花」にはプレ […]
  • 二子玉川の隠れ家多国籍ダイニングでディナー!二子玉川の隠れ家多国籍ダイニングでディナー! 二子玉川の隠れ家多国籍ダイニング「バニラビーンズ」に行ってきました!二子玉川で映画を見る予定があったので、美味しそうなお店がないか食べログで探していると、このバニラビーンズを発見! 結構な人気店のようで、週末は予約必須ということで、週末の土曜日の19:30~2人で […]
  • WordPress記事内にA-Frameを使ってVRコンテンツを作ってみるWordPress記事内にA-Frameを使ってVRコンテンツを作ってみる VRに興味があったので、VRコンテンツをHTMLで記述できるA-Frameを使ってみました。A-Frameを使えばとても簡単に3DのVRコンテンツをページに表示することができヘッドマウントディスプレイを使えば、3D空間の中に入ったかのように空間内を見渡すことができます。 […]
  • そこそこ漫画好きの私がおすすめするファンタジー系漫画!!そこそこ漫画好きの私がおすすめするファンタジー系漫画!! 私は小学校のころからアニメや漫画が大好きな小学生でした。今ではもう30近い大人ですが、今でも単行本で新刊が出れば買う!くらいの漫画好きです! 今回は、そこそこの漫画好きの私が読んでいるオススメ漫画の紹介をやってみようと思います! 私が読んでいるおすすめ漫画それぞれ […]
  • 不動産屋のペースに流されない!資料請求する前に絶対注意してほしいこと不動産屋のペースに流されない!資料請求する前に絶対注意してほしいこと 不動産業界って素人にはよく分からないことが非常に多いですよね。仲介業者を挟むのが普通になっているくらいですから、そうとうややこしいのでしょう。一方で、住宅は一般の人のもっとも重要で大きな買い物であることも事実。 これから不動産購入を考えている人には、 こんなことに絶対な […]

コメントを残す

メールアドレスが公開されることはありません。