1. Home>
  2. memo>
  3. GoogleHomeのSpeaker Group に プッシュで喋らせる

GoogleHomeのSpeaker Group に プッシュで喋らせる

Google Home にプッシュで喋らせるのに、google-home-notifier-python をつかうと簡単にできるのだれど、いくつか改善したいところがあったので、その記録。課題はおもに以下3つ
  1. 発話までの遅延を減らす
  2. 複数台のGoogleHome同時発話(Speaker Group対応)
  3. Voice Text 対応

1. 発話までの遅延を減らす

低遅延化についてはほぼ、この記事を参考に...

2. 複数台のGoogleHome同時発話(Speaker Group対応)

zeroconf でネットワーク上のホスト名を取得して、その中からgoogle cast group を拾って、ipアドレスで指定 …と思ったらうまくいかない。ipアドレスでのデバイス指定ではスピーカーグループを選べないっぽい。google home はデバイス単体ではポート8005を利用し、スピーカーグループだとポート4xxxxを使う。 pychromecast.Chromecast(ip) でデバイスを指定するとポート8005決め打ちでつながってしまう。なので、デバイス名(Google-Cast-Group)を手がかりにデバイスを探し、 ip,uuid,modelname,friendrynameでcast先を指定する。これでスピーカーグループに参加しているGoogle Homeが一斉にしゃべってくれる。というわけで、こんな感じ。
class MyListener(object):
    def remove_service(self, zeroconf, type, name):
                print("Service %s removed" % (name,))

    def add_service(self, zeroconf, type, name):
        global host,info
        info = zeroconf.get_service_info(type, name)
        if 'Google-Cast-Group' in info.name :
            ip = info.server
            port = info.port
            md = info.properties[b'md'].decode()
            fn = info.properties[b'fn'].decode()
            uu = uuid.UUID(info.properties[b'cd'].decode())
            host = ip, port, uu, md, fn
            #見つかったことを通知
            discover_complete.set()

googleHomeName = 'cast'
discover_complete = Event() #待ち合わせ用
zeroconf = Zeroconf()
listener = MyListener()

# GoogleHomeを探す(非同期実行)
browser = ServiceBrowser(zeroconf, "_googlecast._tcp.local.", listener)
discover_complete.wait(5)
cast = pychromecast._get_chromecast_from_host(host)

3. Voice Text 対応

おまけ程度に。テキストをVoiceText(Google の Text-to-Speech でもよい)で音声ファイル化し、play_mp3 に渡す。VoiceTextの場合はAPI Keyを取得すること。ファイル名でキャッシュを作成し、テキストが同じ内容の場合はキャッシュから再生するようになっている。

def play_mp3(mp3_url):
    print(mp3_url)
    mc = cast.media_controller
    cast.wait()
    mc.play_media(mp3_url, 'audio/mp3')
    mc.block_until_active()
    del mc
    
def play_tts(text):

    # VoiceText
    url = 'https://api.voicetext.jp/v1/tts'
    API_KEY ="**********"  # VoiceText API Key
    payload = {
        'text': text,
        'speaker': 'hikari',
        'speed': '90',
        'format' : 'mp3'
        }

    filename = slugify(text) + ".mp3"
    path = "/static/cache/"
    cache_filename = '.'+path + filename 
   
    tts_file = Path(cache_filename)
    
    if not tts_file.is_file():
        s = requests.Session()
        r = s.post(url, params=payload, auth=(API_KEY,''))
        with open(f"{cache_filename}", 'wb') as f:
            f.write(r.content)
    
    urlparts = urlparse(request.url)
    mp3_url = "http://" +urlparts.netloc + path + filename 
    logging.info(mp3_url)
    play_mp3(mp3_url)
    audio = MP3(cache_filename)
    time.sleep(audio.info.length)

ホニャプランについて

パッケージ・工作・ノベルティ・飛び出す絵本など、紙器設計の技術を生かした平面と立体の意匠設計・構造設計の専門家です。要望に応じてアイデアからご提案致します。企画、設計の段階から、加工、納品、その先の使い勝手まで視野にいれた、そのまま大量生産可能な省コスト設計でお応えします

service
業務用の「折る・切る・貼る」をおまかせください。

作品制作とはちょっとちがった、安価に大量(数千〜数百万部)の製造を前提にした設計に対応が可能です。実積等お問い合わせください。オンデマンド印刷+カッティングプロッタを利用した小ロット(~数百部)での製造も承ります。ご相談ください。

法人様/ 小売店様向けサービス
オーダーメイドでのアイテム開発支援、各種アイテムの卸売

法人向けの紙器・パッケージ設計、ポップアップ等オリジナル紙製アイテムの製造や、国立天文台アイテムのミュージアムショップ、書店等小売店様への直接卸し 詳細、取引条件などはフォームよりお問い合わせください