Alexaの最新ライブラリが発表されたのに便乗して
今や音声入力インターフェースが花盛り。
アメリカさんでは一家に一台AmazonEchoなんて言われるくらい浸透してて、GoogleもGoogleHomeで追随中。
もちろん、iOSにはSiriさんがいるし、Windowsにはcortanaくんが。
そして、日本でもLINEが「WAVE(Clova)」という音声インターフェースを発表したことが話題になった。
(先行申し込みした人にはそろそろ届き始めている頃かな。)
そんなこんなで、音声入力インターフェースが「ポスト・スマホの最有力」なんて言われたりするものだから、世界中で巨人達が熾烈な争いを繰り広げている。
そんなさなか、amazonが二週間ほど前に最新のAlexa用公式ライブラリ(SDK)を発表。
以前からずっとAlexaを使ってみたいと思っていたので、ちょうど良い機会だし「Amazon Echoもどき」を作ってみようかな、動かしてみたいし・・・という軽い動機にて。
「声」「音」のユーザーインターフェースの雄(英語圏で)となっているAmazon Echo(Alexa)をラズパイで自作(DIY)してみます。
(あと今後のAlexa SDKの勉強も兼ねて!)
ちなみに。
説明する必要も無いと思うけど、Amazon Echoってこれね。
でもって、最新Alexa SDKのGithubリポジトリはこちら。
https://github.com/alexa/avs-device-sdk
AVS(Alexa Voice Service)SDKリポジトリのwikiには、Amazonが最新SDK用の丁寧な”Quick Start Guide”を用意してくれているので、これをなぞるだけで、Alexaが動くよ!(らしいよ。)
なので、コマンドラインを少しでも扱える人なら誰でも簡単にラズパイでAlexaが作れちゃう。(らしいよ。)
いや、コピペするだけなので、最悪コマンドラインが分からなくても作れちゃう!(らしいよ。)
と思っていたら、結果的に「かなりの忍耐力」を要求されたことだけは先に言っておきます。
(エンジニアなら知っているはず、「道を知ることと道を行くことは全く違う(モーフィアス)」。そういうもんだよね。)
もう一度言っておきます。
「コピペ」するだけでラズパイを使ってAlexaを構築可能であることに間違いはない。
が、コンパイルの待ち時間などが超長かったりドキュメントに不備があったりで、「忍耐」が必要という覚悟を持って臨むべし。
前置きが長くなった・・・・。
さぁ、帆を上げろ!
Let’s go!!
何よりもまず、ラズパイを用意する
今回、私は手元に2年前くらいに買った「Raspberry Pi2」があったのでそれを使用します。
ただし、最新ラズパイはRaspberry Pi3で、2よりも随分と処理能力が上がっています。
なので、ラズパイ3を使うと、もしかしたら「私が苦しんだAlexa構築時間」がラズパイ2の半分くらいの時間で済むかも。
→ラズパイ3 5500円前後
ラズパイ自体のセットアップ等については、過去記事参照。
→Raspberry Pi 2(or 3)で楽しく格安ディスクトップPC構築
ちなみに、Alexaはマイクから音声を拾って、スピーカーを通して返事を返すので、上記説明とは別にラズパイに繋げる①マイクと②スピーカーは必須です。
私は、マイクとスピーカーをamaoznで激安で購入。(ちゃんと動いたよ)
あとインターネットにも繋がる必要があるので、有線LANケーブルかUSBのWifiを用意。
(ラズパイ3だと、WiFiが標準装備なのでWiFi子機は不要だね。)
- USBマイク 780円
- USBスピーカー 1290円
- BAFFALO USB WiFi子機 1000円
Alexa(AVS)動作までのステップを確認しておこう
Alexaを構築作業に着手する前に、構築のステップを大まかに把握ね。
- 手持ちのラズパイをAmazon Developerに登録する(オンライン)
- Alexa SDKを動かすために必要なライブラリをインストールする。(これが時間かかる)
- Alexaの実行環境が整ったら、公式サンプルをダウンロードしてきてビルドする。
- ビルドしたアプリを立ち上げて、マイクに向かって”Alexa!”と呼びかける。(すると、奇跡が・・・)
ラズパイをAmazon Developerに登録する
(以下の登録は、ラズパイでやってもいいし、PCで作業してもOK。私は普段使っているMacでやりました。)
まずは、Amazon Developerにアクセスし、ログインする(アカウントが無い人はアカウントを作ってログイン)。
https://developer.amazon.com/
Amazon Developerにログインしたら”Alexa”タブを選択して、”Alexa Voice Service”で”Get Started“!!
これ、全部スクショとってたらアップしてたら記事がめっちゃ読みづらくなりそう・・・。
あと、スクショ撮っても画面やUIって頻繁に更新されてすぐに参考にならなくなるしね、できるだけ文字で解説します。
上記”CREATE PRODUCT”をクリックすると入力フォームが出てくるので、各項目を解説しておきます。
- “Product Name”- 任意のプロダクト名を入力
- “Product ID”- 任意のプロダクトIDを入力
- “Is your product an app or a device?”- “Device”を選択
- “Product category”- “Other”を選択。”Rapsberry Pi Project on GitHub”と入力。(って公式ドキュメントに書いている)
- “Brief product description”- プロダクトの簡単な説明。(”My first Pi project.”とか入力。)
- “How will end users interact with your product?”- “Touch-initiated”と”Hands-free”を選択。
- “Upload an image”- プロダクトのアイコンね。私はスルーしました。(公式もスキップしてもOKって書いている)
- “Do you intend to distribute this product commercially?”- “No”選択。
- “Is this a children’s product or is it otherwise directed to children younger than 13 years old?”- “No”選択。
フォームを埋めたら”NEXT“ボタンを押して次へ。
セキュリティー設定を行う。
“CREATE NEW PROFILE“をクリック。
セキュリティー設定のフォーム入力項目はこれだけ。
- “Security Profile Name”- プロファイルの名前を入力。(ex.Alexa Voice Service Sample App Security Profile)
- “Security Profile Description”- プロファイルの説明。(ex.Alexa Voice Service Sample App Security Profile)
“NEXT”を押すと”Client ID“と”Client Secret“の二つが生成されてます。
で、”Client ID”と”Client Secret”の下に
“Allowed Origins”と”Allowed Return URLs”の入力項目が現れるので、それぞれに
“http://localhost:3000″、”http://localhost:3000/authresponse”と入力して”UPDATE”。
ちなみに、最後に入力したURL二つは、ラズパイでAlexaSDKをインストールした後に、認証するために必要になります。
これで、プロダクト登録完了!!
この後、”Client ID“、”Client Secret“、”Product ID“などはラズパイの設定ファイルに書き込むことになります。
ほい!ではAVS-SDKの必須ライブラリインストール
もうすでにぐったりしている人もいるかもしれないが、ぐったりするのはこれからだから。
とはいえ、この先、コピペで行けるから気は楽に。
Take It Easy.
ということで、ここからは、ラズパイのコマンドラインを立ち上げてひたすらコピペ。
本当にコピペだけでAlexaのサンプルアプリ動作まで行けてしまうんだけど、先に述べたように「忍耐力」は必要だからね。
(あと、公式ドキュメントだけだとハマった部分もあったんだけど、ハマらないようにガイドします。)
では、行きましょう!
1.まずはラズパイに作業フォルダと環境変数を設定
定番ですが。
Linuxのパッケージ管理システムも使うので、まずはapt-get update!
$ sudo apt-get update
環境変数等設定。
$ echo "export SOURCE_FOLDER=$HOME/sources" >> $HOME/.bash_aliases
$ echo "export LOCAL_BUILD=$HOME/local-builds" >> $HOME/.bash_aliases
$ echo "export LD_LIBRARY_PATH=$HOME/local-builds/lib:$LD_LIBRARY_PATH" >> $HOME/.bash_aliases
$ echo "export PATH=$HOME/local-builds/bin:$PATH" >> $HOME/.bash_aliases
$ echo "export PKG_CONFIG_PATH=$HOME/local-builds/lib/pkgconfig:$PKG_CONFIG_PATH" >> $HOME/.bash_aliases
$ source $HOME/.bashrc
$ mkdir $SOURCE_FOLDER
2.Buildツール類をインストール
apt-getだけでなく、ソースからmake(コンパイル)しないといけないライブラリ類もあるので。
$ sudo apt-get install git gcc cmake build-essential
3.ネットワーク系ライブラリ
OpenSSL/HTTP2/libcurlをインストール
・http2 ダウンロード&インストール
$ cd $SOURCE_FOLDER
$ wget https://github.com/nghttp2/nghttp2/releases/download/v1.0.0/nghttp2-1.0.0.tar.gz
$ tar xzf nghttp2-1.0.0.tar.gz
$ cd $SOURCE_FOLDER/*nghttp2*/
$ ./configure --prefix=$LOCAL_BUILD --disable-app
$ make -j3
$ sudo make install
この辺りはまあまあ余裕。
・openssl ダウンロード&インストール
$ cd $SOURCE_FOLDER
$ wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2a.tar.gz
$ tar xzf openssl-1.0.2a.tar.gz
$ cd *openssl*/
$ ./config --prefix=$LOCAL_BUILD --openssldir=$LOCAL_BUILD shared
$ make -j3
$ sudo make install
このあたりからいきなりコンパイル時間が長い!
ぶっちゃけ、腹筋30回(インターバル30秒)×3セットやっても、全然時間が余ったので、25kgのハンドグリップをニギニギしつつ待つ。
長すぎて握力死んだ。
・libcurl ダウンロード&インストール
$ cd $SOURCE_FOLDER
$ wget https://curl.haxx.se/download/curl-7.50.2.tar.gz
$ tar xzf curl-7.50.2.tar.gz
$ cd *curl*/
$ ./configure --with-ssl=$LOCAL_BUILD --with-nghttp2=$LOCAL_BUILD --prefix=$LOCAL_BUILD
$ make -j3
$ sudo make install
プッシュアップバーを使った腕立て深めで10回×3セットでは時間が余りまくったので、水曜日のダウンタウンみてた。
4.データベース系
・sqlite インストール
$ sudo apt-get install sqlite3 libsqlite3-dev
apt-getが癒し。
やっぱりサクッとインストールできるね。
5.マルチメディア系
マルチメディア系ライブラリのgstreamerをインストールする前に、依存関係のライブラリをインストール
$ sudo apt-get install bison flex libglib2.0-dev libasound2-dev pulseaudio libpulse-dev
$ sudo apt-get install libfaad-dev libsoup2.4-dev libgcrypt20-dev
・gstreamer-1.10.4 ダウンロード&インストール
$ cd $SOURCE_FOLDER
$ wget https://gstreamer.freedesktop.org/src/gstreamer/gstreamer-1.10.4.tar.xz
$ tar xf gstreamer-1.10.4.tar.xz
$ cd *gstreamer*/
$ ./configure --prefix=$LOCAL_BUILD
$ make -j3
$ sudo make install
まだまだ続くよ。
ぶっちゃけ、夜から構築作業し始めたから、make放置して寝ようかと思った。
・gst-plugins-base-1.10.4 ダウンロード&インストール
$ cd $SOURCE_FOLDER
$ wget https://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-1.10.4.tar.xz
$ tar xf gst-plugins-base-1.10.4.tar.xz
$ cd *gst-plugins-base*/
$ ./configure --prefix=$LOCAL_BUILD
$ make -j3
$ sudo make install
ここらあたりになってくると、なんのライブラリを入れているのかよくわからない。
・gst-libav-1.10.4 ダウンロード&インストール
$ cd $SOURCE_FOLDER
$ wget https://gstreamer.freedesktop.org/src/gst-libav/gst-libav-1.10.4.tar.xz
$ tar xf gst-libav-1.10.4.tar.xz
$ cd *gst-libav*/
$ ./configure --prefix=$LOCAL_BUILD
$ make -j3
$ sudo make install
記憶が定かではないが、確かこの辺りでお風呂に入ったけど、出てきてもまだmake終わってなかった。
・gst-plugins-good-1.10.4 ダウンロード&インストール
$ cd $SOURCE_FOLDER
$ wget https://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-1.10.4.tar.xz
$ tar xf gst-plugins-good-1.10.4.tar.xz
$ cd *gst-plugins-good*/
$ ./configure --prefix=$LOCAL_BUILD
$ make -j3
$ sudo make install
プラグインのGoodってなんやねん。
・gst-plugins-bad-1.10.4 ダウンロード&インストール
$ cd $SOURCE_FOLDER
$ wget https://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad-1.10.4.tar.xz
$ tar xf gst-plugins-bad-1.10.4.tar.xz
$ cd *gst-plugins-bad*/
$ ./configure --prefix=$LOCAL_BUILD
$ make -j3
$ sudo make install
プラグインのBadってなんやねん。
待ち疲れて、make放置して寝た。
また明日〜。
6.サンプルアプリ用音声録音・再生
・portaudio ダウンロード&インストール
$ cd $SOURCE_FOLDER
$ wget http://www.portaudio.com/archives/pa_stable_v190600_20161030.tgz
$ tar xf pa_stable_v190600_20161030.tgz
$ cd *portaudio*/
$ ./configure --prefix=$LOCAL_BUILD
$ make -j3
$ sudo make install
インプットされた音声を録音したり再生したりするライブラリらしい。
なるほど、SDKでは、話しかけた音声をストリーミングで解析するのではなく、一度音声ファイルに保存して、保存したファイルを音声解析するのかな。
7.Sensory wake word engine
音声検出エンジン "Sensory"
これ結構重要なんだよね。
たとえば、Siriって、ホームボタンを押して音声入力モードにしてから話かけるわけじゃん。
音声入力インターフェースって、なんらかのトリガーで音声入力モードにすることで音声認識をスタートさせるわけだけど、Siriはホームボタン長押しがトリガー。
Alexaはその起動に物理的なボタンではなくてAlexaと呼びかける「音声」をトリガーにしている。
実はこれって結構大変で、それを担ってくれるのがSensory。
(間違ってたらごめん。)
・Sensoryの依存ライブラリインストール
$ sudo apt-get -y install libasound2-dev
$ sudo apt-get -y install libatlas-base-dev
$ sudo ldconfig
apt-getは癒し。
・Sensory ダウンロード&インストール
$ cd $SOURCE_FOLDER
$ git clone git://github.com/Sensory/alexa-rpi.git
$ bash alexa-rpi/bin/license.sh
$ cp alexa-rpi/lib/libsnsr.a $LOCAL_BUILD/lib
$ cp alexa-rpi/include/snsr.h $LOCAL_BUILD/include
$ mkdir $LOCAL_BUILD/models
$ cp alexa-rpi/models/spot-alexa-rpi-31000.snsr $LOCAL_BUILD/models
また、魔のconfigure & make。
やーっと、AVS本体のビルドー!
1.AVS Device SDK ダウンロード
$ cd $HOME
$ mkdir AVS_SDK
$ cd AVS_SDK
$ git clone git://github.com/alexa/avs-device-sdk.git
$ echo "export SDK_SRC=$HOME/AVS_SDK/avs-device-sdk" >> $HOME/.bash_aliases
$ source $HOME/.bashrc
2.Sensory, GStreamer, PortAudioとともにSDKをビルド
$ cd $HOME
$ mkdir BUILD
$ cd BUILD
$ cmake $SDK_SRC -DSENSORY_KEY_WORD_DETECTOR=ON -DSENSORY_KEY_WORD_DETECTOR_LIB_PATH=$LOCAL_BUILD/lib/libsnsr.a -DSENSORY_KEY_WORD_DETECTOR_INCLUDE_DIR=$LOCAL_BUILD/include -DGSTREAMER_MEDIA_PLAYER=ON -DPORTAUDIO=ON
-DPORTAUDIO_LIB_PATH=$LOCAL_BUILD/lib/libportaudio.a -DPORTAUDIO_INCLUDE_DIR=$LOCAL_BUILD/include -DCMAKE_PREFIX_PATH=$LOCAL_BUILD -DCMAKE_INSTALL_PREFIX=$LOCAL_BUILD
3.設定ファイルに設定を書き込む
(ここどハマりポイント)
viでもvimでもnanoでもなんでもいいですが、設定ファイルを編集します。
設定ファイルは以下のパスに。
~/BUILD/Integration/AlexaClientSDKConfig.json
ちなみに、ここは私がどハマりしたポイントです。
設定ファイルの項目に何を書き込めばいいかわからない部分がいくつかあって悩んだ。
(公式ドキュメントに書いていない。)
{
"authDelegate":{
"clientSecret":"${SDK_CONFIG_CLIENT_SECRET}",
"deviceSerialNumber":"${SDK_CONFIG_DEVICE_SERIAL_NUMBER}",
"refreshToken":"${SDK_CONFIG_REFRESH_TOKEN}",
"clientId":"${SDK_CONFIG_CLIENT_ID}",
"deviceTypeId":"${SDK_CONFIG_DEVICE_TYPE_ID}"
},
"alertsCapabilityAgent":{
"databaseFilePath":"${SDK_SQLITE_DATABASE_FILE_PATH}",
"alarmSoundFilePath":"${SDK_ALARM_DEFAULT_SOUND_FILE_PATH}",
"alarmShortSoundFilePath":"${SDK_ALARM_SHORT_SOUND_FILE_PATH}",
"timerSoundFilePath":"${SDK_TIMER_DEFAULT_SOUND_FILE_PATH}",
"timerShortSoundFilePath":"${SDK_TIMER_SHORT_SOUND_FILE_PATH}"
}
}
まず"authDelegate"内の値。
"refreshToken"は、後の認証作業で自動的に書き込まれるので今は空欄にしておいてOK。
(これは公式にそう書いていたので安心。)
"clientSecret"、"clientId"の二つは、上記ラズパイのデバイス登録したときに表示された値を書き込みます。
で、"deviceTypeId"ですが、こんな値はデバイス登録したときに与えられおらず、Amazon Developersで登録したデータをあちこち探してもそんな値はない。
"deviceTypeId"とは何なのか、さっぱりわからなかったが、登録データに載っていて考えられそうな値としては"Product ID"あたり。
ということで、"deviceTypeId"には"Product ID"の値を書き込んでおく。
(結果、これで正解。)
次に、"deviceSerialNumber"。
これが一体何なのかさっぱりわからない、Amazon Developersのデータを見ていても「それらしい」雰囲気のものすらない。
一体どんな値を設定すればいいのかさっぱりわからないので、適当に”12345678”といれたら通った。
(のちに、何処かのサイトでIDはなんでもいいと書いていた。とりあえずサンプルなので。)
次に、"alertsCapabilityAgent"内の値。
"databaseFilePath"は、データベースのファイルパスなんだけど、とりあえず任意の場所でOK。
ex./home/pi/alexa/database.db
データベースがなければ、そのパス上にDBが作成されるので、ご安心を。
で、問題はその下。
"alarmSoundFilePath","alarmShortSoundFilePath","timerSoundFilePath","timerShortSoundFilePath"
これらの値の意味がわからない。
意味がわからないので、空でいいや、と全部の値を空文字に設定してコンパイルしたら以下のようなエラーがでるし。
Failed to create default SDK client!
(SampleApp:12043): GStreamer-CRITICAL **: gst_element_get_state: assertion 'GST_IS_ELEMENT (element)' failed
2017-08-25 06:15:24.808 [ 2] E MediaPlayer:doStopFailed:reason=gstElementGetStateFailed
つまり、上記4つの値は空にはできないと思い、公式githubのissueを手当たり次第に当たっていたら、アラームとタイマー用の音声ファイルを設定しないといけないってことが判明。
https://developer.amazon.com/public/solutions/alexa/alexa-voice-service/content/alexa-voice-service-ux-design-guidelines
ここからタイマーとアラームの4つの音声をラズパイ上の任意の場所にダウンロード。
でもって、4つのファイルパスを上記の設定ファイルに書き込む。
これで、設定ファイルの編集は完了!
4.いよいよAVS-SDKのインストール
$ cd $HOME/BUILD
$ make -j3
$ make install
またこのmakeが長い。
5.SDKの認証
python AuthServer/AuthServer.py
上記コマンドで、ラズパイ内にWEBサーバーが立ち上がる。
その後、ラズパイのWEBブラウザを立ち上げて、http://localhost:3000 にアクセスする。
すると、ページがリダイレクトされて、Amazonの認証ページに進むので
認証ボタンを押す。
認証に成功すると以下のような画面が現れて、先ほどの設定ファイルに"refreshToken"が自動的に書き込まれる。
祝!Alexaインストール完了!
ということで、こんな感じでDIY Alexa誕生。
(ちょっとブサイクなAlexaだけど)
いよいよAlexa on RaspberryPiとお話
よし!Alexa起動!
TZ=UTC ./SampleApp ~/BUILD/Integration/AlexaClientSDKConfig.json $LOCAL_BUILD/models
早速、Alexaに話しかけてみる。
私:"Alexa!"
A:"Yes"
私:"How are you?"
A:"Great! Ready to help."
私:(よし!やったー!うまくいったどー!)
いやー、ラズパイちゃんにAlexaさんが載って、ちゃんとお返事してくれています!
難しいことはしていないけど非常に時間がかかっただけに、Alexaさんの反応を聞けて嬉しい限り。
ま、ここまではね。
・・・・・・。
ええ、ここまではね。
この先、話しかけるとなぜかアプリが落ちる。
"hello!"と、挨拶のやりとりまではいいんだけど、その後"What's the weather in Kyoto now?"とか、Alexaさんと別の会話をしようとすると一気に機嫌を損ねてしまうようで。
急にブチ切れて、落ちちゃう。
う〜ん・・・。
公式のGithubにもissueが結構溜まってきてるし、Sampleアプリの不具合なのか、私の設定がどこかでミスっているのか・・・。
とりあえず、今回は一旦この辺りにしておいて、近いうちに修正していきます。
おまけ(費用のお話)
昔買ったラズパイを使いまわしているので、現在の価格と相違があるかもしれませんが、予算的なことを。
ちなみに、ラズパイ本体以外は、全部格安のもので揃えました。
- RaspberryPi 2 Model B 5140円 (2年以上前の2015年に購入)
- SDカード 360円
- USBマイク 790円
- USBスピーカー 1290円
- WiFi 1000円
合計 8580円
※今回はリモートディスクトップ(VNC)を使ってラズパイを操作したので、モニター等は使っていません。
ということで、9000円以内であなたもAlexaをDIYできちゃいます!(^^)
すっげー!!
ただし、ebayとかだと、本体4000円+送料3000円くらいで正規のAmazon Echo(Dot)が買えるんだけどね(^^)
orz