薬剤師が教えるGoogleHomeアプリにアスナとシリカの歌声を実装する方法


GoogleHomeアプリにストリーミングを実装したい

薬局お茶の水ファーマシーで薬局薬剤師をしながら、薬局向けサービスをつくっている薬剤師です(株式会社ファーマクラウド: エンジニア募集中)。pythonとJSがちょっとだけ書けます。薬局でこんなのがあればいいなというものがあったら、本職のエンジニアにお願いする前に簡単に動くものをつくってみるように心がけています。今回はGoogleHomeアプリでradiko的なものをつくってみたいと思い立ちました。
ということで、色々説明は省略しますが、界隈で人気のアスナをGoogleHomeで歌わせてみることにしました。去年購入した「劇場版ソードアート・オンライン-オーディナル・スケール-」完全生産限定版DVDの特典CDにある「Ubiquitous dB –special ver.-」をmp3にして、自作したGoogleHomeアプリ「ファーマシストオンライン」(注意: 薬剤師でないと使いこなせません)に実装してみた手順をつらつらと書いていきます。技術的に難しいことは一切やってないので予めご了承ください。
一応「薬剤師が教えるGoogle Homeのデモ用botのつくりかた」の続編的な記事なので、Actions on googleとかDialogFlowとかわかんない方は、手前味噌で恐縮ですが前回記事をご覧頂くか、適宜ググっていただくようお願いします。

Cloud Storageに音声ファイルをアップロードする

自分が管理するサーバにアップロード(https必須)しておけばいいでしょうが、せっかくなのでActions on googleで作成したプロジェクトにひもづいたGoogle Cloud Storageに保存してみましょう。GCPのコンソールにアクセスして、左メニュー -> Storage -> ブラウザに移動します。

バケットの作成

Cloud Strageに遷移したら「バケットの作成」をクリックして、バケット名を入力、デフォルトのストレージクラス・ロケーションを指定して「作成」を押します。ちなみにバケットというのは要はフォルダのことだ、と雑に理解しています。

アップロード

バケットが作成されました。名前をクリックしてバケット内に入ります。<your-project>.appspot.comstaging.<your-project>.appspot.comはプロジェクトを作ったときに勝手に生成されるようです。今回、この2つは無視して進めます。

当然ですが中には何もありません。用意したmp3をここにアップロードします。アップロードしたら「公開リンク」にチェックを入れておきます。これで下準備は終わりです。

Intentをつくる

今回はサクッと実装するのが目的なので、複雑なことはしません。Webhookは使わずにDialogflow内で完結させます。アプリを起動して、あるフレーズに反応してmp3が流れればそれでOKです。ということで、Dialogflowの左メニューのIntentsの+をクリックして、Intent nameに適当な名前を入力します。

User saysは適当に

気の利いたことはしません。「ソードアートオンラインを流して」「ソードアートオンラインを聞きたい」としました。

Text responseにSSMLを記述する

本記事の目玉はここかなと思います。SSML(speech-synthsis-markup-language)をText responseに記述します。ちなみに2018年2月10日現在で、QiitaでSSMLのタグが付いた記事はこの記事この記事のみ。本記事が3つ目です。関係ないですが、スマートスピーカーがもっと普及したらSSML職人なる方々が登場するんじゃないかと思っています。

audioタグ

アプリ起動後、「ソードアートオンラインを流して」と言ったら「SAOを再生します。」と返事して曲が流れる・・・という流れを考えました。User saysで「ソードアートオンラインを流して」まではできているので、その後の返事をText responseに書いていきます。リンクは保存したmp3ファイルを右クリック -> リンクのアドレスをコピーで取得します。

<speach>
  SAOを再生します。
  <audio src="https://storage.cloud.google.com/<your-bucket-name>/<your-mp3-file-name1>.mp3" />
</speach>

これでSAVEして、早速GoogleHomeでアプリを起動、「ソードアートオンラインを流して」と言ってみたら2点問題が。
1. そもそも再生されない。
2. SAOの記述が「さお」と発音される。

ドメインを修正

結論から言うとドメインが違う。ブラウザでは再生されるのに理由は不明。以下のようにstorage.cloud.google.comstorage.googleapis.comに変更すると再生されるようになりました。

<speach>
  SAOを再生します。
  <audio src="https://storage.googleapis.com/<your-bucket-name>/<your-mp3-file-name1>.mp3" />
</speach>

次は「さお」問題をやっつけます。

SAOをエスエーオーと読ませる

say-asタグを使います。<say-as interpret-as="characters">SAO</say-as>とすると、ローマ字読みではなくアルファベットを1文字ずつ読み上げてくれるようになります。

<speach>
  <say-as interpret-as="characters">SAO</say-as>を再生します。
  <audio src="https://storage.googleapis.com/<your-bucket-name>/<your-mp3-file-name1>.mp3" />
</speach>

audioタグを続けたらどうなるか?

audioタグを連続したら続けて再生されるか興味が湧いたので書いてみました。結果、隙間なく再生されました。ダウンロードというより、やはりストリーミングのようです。

<speach>
  <say-as interpret-as="characters">SAO</say-as>を再生します。
  <audio src="https://storage.googleapis.com/<your-bucket-name>/<your-mp3-file-name1>.mp3" />
  <audio src="https://storage.googleapis.com/<your-bucket-name>/<your-mp3-file-name2>.mp3" />
</speach>

Text responseの最終型

ガーッと書いたので汚いですがこんなかんじです。

End conversationにチェックを入れる

曲が終わったらアプリも終了させる。というときは、一番下のGoogle Assistantの右にある矢印をクリックするとEnd conversationが出現するのでチェックを入れます。ここはお好みで。

最後にどうでもいい情報

ぼくはリズ推しです。

参考

Actions on GoogleのSSMLドキュメント
ねぇ Google、 Rebuild.fmを流して(がやりたかった話)