Alexa Skills Kit(ASK)の実装は以前試してみましたが、 Alexa Voice Service(AVS) はまだ試してみていなかったので、今回は AVS のサンプルアプリを Raspberry Pi で動かしてみました。基本的には下記のチュートリアルの内容をトレースしたものです。
Alexa は主に ASK と AVS で構成されていて、 ASK がクラウド上で動作して処理を返すのに対して、 AVS はデバイス上で動作して、入力された音声データの処理と ASK へのリクエストとレスポンスの仲介を行います。
使用デバイス
今回使用したデバイスは Raspberry Pi 3 Model B と、下記のUSBマイクです。
https://www.amazon.co.jp/gp/product/B01KZPF1U8/
スピーカーは 3.5mm ステレオジャックの手持ちのものがなかったので、とりあえず手持ちのヘッドホンを使用して試してみました。
また、 microSDカードも新しい 16GB のものを用意してセットアップしました。
Raspberry Pi のセットアップ
まずは Raspberry Pi のセットアップを下記で紹介されている手順に従ってNOOBSを使用して行います。
特に難しいことはありませんが、注意点としては、 micro SD カードは購入時のままでも大抵は Mac で読み書きできますが、改めてフォーマットしてから使用しないと Raspberry Pi でインストーラが起動したところからずっと待ち状態のまま進みませんでした。
あと追加で raspi-config から Wi-Fi アクセスのセットアップと、 GUI 上から SSH と VNC の有効化を行いました。
Amazon Developer アカウントの作成
まだ Amazon Developer アカウントを作成していない場合は developer.amazon.com から登録します。私は以前 ASK の実装を試した時に作成していたのでそれを使用しました。詳細な登録手順は割愛します。
製品とセキュリティプロファイルの作成
Amazon Developer コンソールから AVS を動かす製品(デバイス)の登録とセキュリティプロファイルの作成を行います。手順については下記ページで紹介されています。
Create Security Profile · alexa/alexa-avs-sample-app Wiki · GitHub
まず製品の登録です。コンソール上部のメニューから ALEXA
をクリックし、 Alexa Voice Service の 始める
をクリックします。
登録済みの製品の一覧ページに遷移しますので、右上の 製品を作成する
をクリックします。
製品情報の入力フォームが表示されますので、チュートリアルで紹介されている通り、下記の画像のように入力して、 次へ
をクリックします。ここで入力している製品ID はあとでサンプルアプリを動かす際に必要になります。
Amazon へログインするためのセキュリティプロファイルの選択画面が表示されますので、 プロフィールを新規作成する
リンクをクリックします。
セキュリティプロファイル名とセキュリティプロファイル記述の入力フォームが開きますので、ここもチュートリアルの内容に従って下記のように入力して、 次へ
をクリックします。
さらに画面下部にプラットフォーム情報の入力フォームが開きます。ここで表示されているクライアントIDとクライアントシークレットはあとでサンプルアプリを動かす際に必要になりますのでメモしておきます。「許可された出荷地」のフォームにURLを入力して 追加
をクリックするとURLが追加されますので、 http://localhost:3000 と https://localhost:3000 を追加します。また、「許可された返品 URL」の方にも同様の手順で http://localhost:3000/authresponse と https://localhost:3000/authresponse を追加し、規約への同意のチェックボックスにチェックを入れて 完了する
をクリックすると製品が追加されます。
続いて、作成したセキュリティプロファイルを有効化します。 Developer コンソールの Amazon でログイン のページに移動し、プルダウンから先ほど作成したセキュリティプロファイルを選択して Confirm
をクリックします。
プライバシーポリシーの入力フォームが表示されますので、ダミーのURLを入力しておき、 Save
をクリックします。
サンプルアプリの clone
GitHub からサンプルアプリを clone します。
$ cd ~/デスクトップ $ git clone https://github.com/alexa/alexa-avs-sample-app.git Cloning into 'alexa-avs-sample-app'... remote: Counting objects: 1488, done. remote: Total 1488 (delta 0), reused 0 (delta 0), pack-reused 1488 Receiving objects: 100% (1488/1488), 19.94 MiB | 1.57 MiB/s, done. Resolving deltas: 100% (638/638), done. Checking connectivity... done.
インストールスクリプトの編集
インストールスクリプトを編集し、先ほど作成した製品とセキュリティプロファイルの製品ID(ProductID)、クライアントID(ClientID)、クライアントシークレット(ClientSecret)を記載します。
$ cd ~/デスクトップ/alexa-avs-sample-app/ $ vi automated_install.sh $ head -20 automated_install.sh #!/bin/bash #------------------------------------------------------- # Paste from developer.amazon.com below #------------------------------------------------------- # This is the name given to your device or mobile app in the Amazon developer portal. To look this up, navigate to https://developer.amazon.com/edw/home.html. It may be labeled Device Type ID. ProductID=my_device # Retrieve your client ID from the web settings tab within the developer console: https://developer.amazon.com/edw/home.html ClientID=amzn1.application-oa2-client.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Retrieve your client secret from the web settings tab within the developer console: https://developer.amazon.com/edw/home.html ClientSecret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx #------------------------------------------------------- # No need to change anything below this... #------------------------------------------------------- #-------------------------------------------------------
インストールスクリプトの実行
それでは下記のようにインストールスクリプトを実行します。
$ . automated_install.sh
いくつか質問のプロンプトが表示されますが、yes で回答するとインストールが始まります。
サンプルアプリの実行
ここまでで一通り準備はできたのでサンプルアプリを実行してみます。サンプルアプリは下記3つの要素で構成されています。
Companion Service:サンプルアプリの認証を行うためのWebサービス
AVS Sample App:AVSサンプルアプリ本体
Wake Word Engine:"Alexa" というフレーズでサンプルアプリとのインタラクションを開始するためのエンジン
上記をそれぞれ別ターミナルで動作させます。インストールスクリプトの実行までは ssh 等での CLI からの実行でも問題ないかと思いますが、サンプルアプリでは GUI やブラウザを使用しますので、直接 Raspberry Pi にログインするか、 VNC Viewer などで Raspberry Pi の GUI デスクトップにアクセスして実行します。まずは Companion Service を起動します。 Companion Service は node.js のサーバアプリになっています。
$ cd ~/デスクトップ/alexa-avs-sample-app/samples $ cd companionService && npm start > alexa-voice-service-sample-companion-service@1.0.0 start /home/pi/デスクトップ/alexa-avs-sample-app/samples/companionService > node ./bin/www This node service needs to be running to store token information memory and vend them for the AVS app. Listening on port 3000
これでポート 3000 で接続を待ち受けます。続いてサンプルアプリ本体を起動します。Companion Service とは別のターミナルで下記コマンドを実行します。サンプルアプリ本体は Java アプリになっています。
$ cd ~/デスクトップ/alexa-avs-sample-app/samples $ cd javaclient && mvn exec:exec [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Alexa Voice Service Sample Java Client 20160207.7 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- exec-maven-plugin:1.2.1:exec (default-cli) @ sample-java-client ---
サンプルアプリを起動すると下記のような Window が表示されます。
これはデバイスを登録するためにデフォルトブラウザを起動して表示されているURLにアクセスするかどうかということなので、 はい
をクリックするとブラウザが起動します。起動しない場合は手動でブラウザを起動して表示されているURLにアクセスします。プライバシー保護の警告が表示されますが、問題ないので 詳細設定
をクリックします。
localhost にアクセスする
をクリックして続行します。
Amazon のログインページに遷移しますのでメールアドレスとパスワードでログインします。
認証に成功すると https://localhost:3000/authresponse
で始まるURLに遷移し、ブラウザには下記のように表示されます。
device tokens ready
これで認証は完了です。 Java アプリの方に戻ると下記のような Window が表示されていますので、 OK
をクリックして Window を閉じます。
するとサンプルアプリのGUIが表示されます。
ここまでで GUI のマイクマークをクリックすることで Alexa とのインタラクションをスタートすることはできるようになっていますが、 Wake Word を使用するために Wake Word Engine を起動します。このサンプルアプリのプロジェクトではサードパーティの Wake Word Engine として Sensory の TrulyHandsFree と KITT.AI の Snowboy がサポートされています。今回は下記のように Sensory の TrulyHandsFree を使用してみます。
$ cd ~/デスクトップ/alexa-avs-sample-app/samples $ cd wakeWordAgent/src && ./wakeWordAgent -e sensory INFO:main: Starting Wake Word Agent INFO:WakeWordAgent: State set to IDLE(2) INFO:Initializing Sensory library | library name: TrulyHandsfree | library version: 5.0.0-beta.10.2 | model file: ../ext/resources/spot-alexa-rpi.snsr WARNING:Library expires on: License expires on 28 Mar 2018 00:00:00 GMT INFO:SensoryWakeWordEngine: mainLoop thread started INFO:WakeWordIPCSocket::mainLoop thread started INFO:WakeWordIPCSocket: init socket on port:5123 INFO:WakeWordAgent: thread started INFO:===> Connected to AVS client <===
動作確認
それではサンプルアプリの動作を確認してみます。 GUI のマイクマークをクリックするか、 "Alexa" と話しかけるとインタラクションが開始します。「今何時?』「今日の天気は?」などと質問すると Amazon Echo と同じように Alexa が応答してくれます。 Wake Word Engine を動かしているターミナルには下記のような出力があります。
INFO:===> WakeWordAgent: wake word detected <=== INFO:WakeWordAgent: State set to WAKE_WORD_DETECTED(3) INFO:WakeWordAgent: State set to SENT_WAKE_WORD_DETECTED(4) INFO:WakeWordAgent: IPC Command received:3 INFO:WakeWordAgent: State set to WAKE_WORD_PAUSE_REQUESTED(5) INFO:SensoryWakeWordEngine: handling pause INFO: *** THREAD JOINING: Sensory *** INFO:SensoryWakeWordEngine: mainLoop thread ended INFO:WakeWordAgent: State set to WAKE_WORD_PAUSED(6) INFO:WakeWordAgent: IPC Command received:4 INFO:WakeWordAgent: State set to WAKE_WORD_RESUME_REQUESTED(7) INFO:SensoryWakeWordEngine: handling resume INFO:SensoryWakeWordEngine: mainLoop thread started INFO:WakeWordAgent: State set to IDLE(2)
ちなみに Wake Word Engine については、 Amazon Echo Dot ではカタカナ発音の「アレクサ」でも十分検知してくれましたが、今回のケースでは英語っぽく "Alexa" と発音しないと検知してくれませんでした。
まとめ
今回はチュートリアルの内容をトレースすることで Raspberry Pi と Alexa を統合することができましたが、ここまでの内容だけでは Amazon Echo をそのまま使うのと変わらないので、 Raspberry Pi の自由度を活かして色々なデバイスと連携させたりしてみたいと思っています。ただ、サンプルアプリで Java アプリが公開されているものの、実装方法の詳細についての説明は見つからず、 C++ の SDK である AVS Device SDK も見てみましたが詳細な部分はよくわからなかったので、今後わかりそうであれば Raspberry Pi 上で動かす独自アプリを実装してみたいと思います。