AmazonからAlexa Voice Service(AVS)の使い方についてのサンプルが公開されていたので、試してみました。
https://github.com/amzn/alexa-avs-raspberry-pi
追記(2017/3/31)
この記事を書いた頃はボタン押してAlexaを使っていましたが、その後ウェイクワードに対応したサードパーティー製のサービスが組み込まれ、ボタン押さなくても Alexa, what is the weather
みたいな感じで、動くようになっています。
インストールの手順もコマンドライン一発みたいに改善されているので、↑のgithubを参照ください。
raspberry piを利用する場合は、こちらのページになっています。https://github.com/alexa/alexa-avs-sample-app/wiki/Raspberry-Pi
サンプル動画
出来上がりはこんな感じで、Alexaが質問に反応して、答えてくれるようになります。
いきなり感想
Raspberry Pi用のサンプルでは、GUIでクライアントを起動する必要があり、音声の認識には事前にボタンを押してといった操作が必要なので、Amazon Echoみたいに好きなタイミングで話しかけて、反応するといったことが出来ませんでした。
Amazon Echoのようにトリガーキーワードである Alexa
を言わなくても反応するのは、ボタンで音声認識を開始させているからだと思います。
音声だけで反応させるには、常時オーディオを監視して、特定のキーワードが見つかったら、それ以降の音声を認識させるといった作りこみを、クライアントアプリで出来るようにすれば、よりAmazon Echoの様なデバイスが作れるのではないでしょうか。
Amazon Fire Stickのリモコンも、Alexaを使う時はボタンを押してる間だけ音声認識させるので、実装するデバイスの用途次第で、トリガーをどうするか決めれば良さそうです。
サンプルを元に進めます
準備するもの
- Raspberry Pi 2
- マイク
- スピーカー(私の例では、HDMIでTVに繋いだので、音声はTVから出力されます)
Raspberry PiのOS
$ uname -a
Linux raspberrypi 4.1.17-v7+ #838 SMP Tue Feb 9 13:15:09 GMT 2016 armv7l GNU/Linux
VNCサーバの設定
AVSのサンプルを動かす際にはGUIが必要となりますので、別途モニターを用意しない場合は、元の手順のようにVNCサーバのセットアップをしてリモートデスクトップを使ってサンプルを動かす必要があります
VLCをセットアップ
sudo apt-get update
sudo apt-get install vlc-nox vlc-data
VLCの場所を確認
$ whereis vlc
vlc: /usr/bin/vlc /usr/lib/vlc /usr/share/vlc /usr/share/man/man1/vlc.1.gz
環境変数の設定
export LD_LIBRARY_PATH=/usr/lib/vlc
export VLC_PLUGIN_PATH=/usr/lib/vlc/plugins
nodejsのインストール
curl -sL https://deb.nodesource.com/setup | sudo bash -
sudo apt-get install nodejs
$ node -v
v0.10.43
JDKのインストール
こちらからJDKをダウンロードします。
今回ダウンロードしたのは、Linux ARM 32 Soft Float ABI(jdk-8u77-linux-arm32-vfp-hflt.tar.gz 新しいバージョンを使う場合は適宜ファイル名を置き換えて進めてください)
注:2016/6/5) リンク先からLinux ARM 32 Soft Float ABI
がない場合がありますが、Oracleが数週間毎にSoft/Hardと名称を変えるので、最新のLinux ARM 32 Hard Float ABI
or Linux ARM 32 Hard Float ABI
をダウンロードして使ってください。 (@jhotta さんありがとうございます)
sudo tar zxvf jdk-8u77-linux-arm32-vfp-hflt.tar.gz -C /opt
sudo update-alternatives --install /usr/bin/javac javac /opt/jdk1.8.0_77/bin/javac 1
sudo update-alternatives --install /usr/bin/java java /opt/jdk1.8.0_77/bin/java 1
インストールしたものを使うように設定
sudo update-alternatives --config javac
sudo update-alternatives --config java
確認
$ java -version
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) Client VM (build 25.77-b03, mixed mode)
$ javac -version
javac 1.8.0_77
Mavenのインストール
こちら ダウンロードしてくる
sudo tar zxvf apache-maven-3.3.9-bin.tar.gz -C /opt
export M2_HOME=/opt/apache-maven-3.3.9
export PATH=$PATH:$M2_HOME/bin
確認
mvn -version
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T01:41:47+09:00)
Maven home: /opt/apache-maven-3.3.9
Java version: 1.8.0_77, vendor: Oracle Corporation
Java home: /opt/jdk1.8.0_77/jre
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "4.1.17-v7+", arch: "arm", family: "unix"
Alexa Voice Serviceの準備
手順ページ(3 - Getting started with Alexa Voice Service)に書かれている通りにデバイスを追加します
https://github.com/amzn/alexa-avs-raspberry-pi#3---getting-started-with-alexa-voice-service
サンプルをRaspberry上にダウンロード
wget https://github.com/amzn/alexa-avs-raspberry-pi/archive/master.zip
unzip master.zip
sudo mv alexa-avs-raspberry-pi-master /opt/alexa-avs-raspberry-pi
自己証明書の準備
sudo apt-get install openssl
cd /opt/alexa-avs-raspberry-pi/samples/javaclient
ssl.cnfを編集して証明書の情報を入力します
countryName
は2文字じゃないと証明書の生成に失敗します。
commonNameは、/opt/alexa-avs-raspberry-pi/samples/companionService/config.js
のcompanionService.serviceUrlと一致させておく必要があります。(デフォルトからいじらなければOK)
[req]
distinguished_name = req_distinguished_name
prompt = no
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1
IP.2 = 10.0.2.2
[req_distinguished_name]
commonName = $ENV::COMMON_NAME
countryName = JP
stateOrProvinceName = Tokyo
localityName = tokyo
organizationName = sparkgene
organizationalUnitName = dev
証明書生成スクリプトに実行権限を付けて実行する
chmod +x generate.sh
./generate.sh
Product ID: pi2_alexa
Serial Number: 123456
Password for Keystores (won't echo): Generating RSA private key, 4096 bit long modulus
.................................................................................................................................++
...............................................................................................................................................................................++
e is 65537 (0x10001)
Generating RSA private key, 2048 bit long modulus
.+++
...................................+++
e is 65537 (0x10001)
Signature ok
subject=/CN=sparkgene/C=JP/ST=Tokyo/L=tokyo/O=SPARKGENE/OU=development
Getting CA Private Key
Generating RSA private key, 2048 bit long modulus
...............................+++
...............................................................................................................................................+++
e is 65537 (0x10001)
Signature ok
subject=/CN=sparkgene/C=JP/ST=Tokyo/L=tokyo/O=SPARKGENE/OU=development
Getting CA Private Key
Generating RSA private key, 2048 bit long modulus
..................+++
................................................+++
e is 65537 (0x10001)
Signature ok
subject=/CN=sparkgene/C=JP/ST=Tokyo/L=tokyo/O=SPARKGENE/OU=development
Getting CA Private Key
nodejsの設定ファイルに生成した証明書のパスを指定する。
sslKey: '/opt/alexa-avs-raspberry-pi/samples/javaclient/certs/server/node.key',
sslCert: '/opt/alexa-avs-raspberry-pi/samples/javaclient/certs/server/node.crt',
sslCaCert: '/opt/alexa-avs-raspberry-pi/samples/javaclient/certs/ca/ca.crt',
javaクライアントの設定ファイルに生成した証明書のパスを指定する。
パスワード指定していないので、Passphraseは空にしてます。
{
"productId":"",
"dsn":"",
"provisioningMethod":"",
"companionApp":{
"localPort":8443,
"sslKeyStore":"/opt/alexa-avs-raspberry-pi/samples/javaclient/certs/server/jetty.pkcs12",
"sslKeyStorePassphrase":"",
"lwaUrl":"https://api.amazon.com"
},
"companionService":{
"serviceUrl":"https://localhost:3000",
"sslClientKeyStore":"/opt/alexa-avs-raspberry-pi/samples/javaclient/certs/client/client.pkcs12",
"sslClientKeyStorePassphrase":"",
"sslCaCert":"/opt/alexa-avs-raspberry-pi/samples/javaclient/certs/ca/ca.crt"
}
}
Raspberry Piをデバイス登録するためのアプリを準備
cd /opt/alexa-avs-raspberry-pi/samples/companionService
npm install
Security Profileを有効にする
https://github.com/amzn/alexa-avs-raspberry-pi#6---enable-security-profile
を参考に、有効にします。
各種configファイルに設定する
/opt/alexa-avs-raspberry-pi/samples/companionService/config.jsを編集して、clientId、clientSecret、productsを設定します。
元のサンプル通りの命名で進めるとproductsは products: {"my_device": ["123456"]}
と指定します。
/opt/alexa-avs-raspberry-pi/samples/javaclient/config.jsonを編集して、productId、dsn、provisioningMethodを設定します。
/opt/alexa-avs-raspberry-pi/samples/javaclient/pom.xmlのdependenciesに以下を追加する
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.1.0</version>
<scope>compile</scope>
</dependency>
Companion Serviceサーバを実行する
cd /opt/alexa-avs-raspberry-pi/samples/companionService/
npm start
# サーバが実行され、ポート3000でリッスンを開始します
> alexa-voice-service-sample-companion-service@1.0.0 start /opt/alexa-avs-raspberry-pi/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
クライアントを起動
別のターミナルウィンドウを起動してクライアントを実行します
cd /opt/alexa-avs-raspberry-pi/samples/javaclient/
chmod +x install-java8.sh
./install-java8.sh
mvn validate
mvn install
mvn exec:exec
アクティベーションする
クライアントが起動すると、デバイスを登録するためのURLが表示されるので、それをブラウザに貼り付けて、有効にします。
アクティベーションがされると、クライアントの画面でStart Listening
をクリックして音声認識させます。