愛犬の声を再生するAmazon Echo (Alexa) スキルをノンコーディングでサクッと開発する

愛犬の声を再生するAmazon Echo (Alexa) スキルをノンコーディングでサクッと開発する:


0. はじめに

開発者待望のAlexaスキル内課金が米国で可能に!など、2019年は日本でもスマートスピーカーのスキル開発がより注目される予感がしています。本記事では、超初心者にもハードルが低くなるよう、MicrosoftAzureLogicAppsを使ってノンコーディングでAmazonEchoのスキルを開発してみます。実家に帰省しないと会うことができない愛犬の声をいつでも気軽AmazonEchoから聞くことができるスキルを開発しました。


1. 開発するスキル

今回開発するスキルのイメージはこちらです。呼び出されると、愛犬の声を再生するようにします。


image.png


鳴き声を使って、愛犬を #AmazonEcho のスキルで再現してみた。鳴き声の録音が難しい。笑 #VUI #駆け出しエンジニアと繋がりたい #100DaysOfCode pic.twitter.com/amaM7Hc6SK

— さいちゃん�� (@saisan78) 2019年1月1日


2. 開発の全体像と流れ

手順は、大きく以下の3ステップです。

①AlexaDeveloperConsoleでスキルの作成

②AzureLogicAppsで応答処理の作成

③自作音声ファイルの準備とDropboxでの共有



image.png



①AlexaDeveloperConsoleでスキルを作成

まず、https://developer.amazon.com/ja/にて、スキルを作成しましょう。AmazonEchoスキルの開発に必要な概念は、Amazon Echo (Alexa) のSkillの開発に必要な基本概念を押さえるを参照してください。今回は、「おさんぽ」とよんだら、音声を返すシンプルなスキルなので、インテントをひとつだけ登録します。おさんぽということで"walking"と命名しました。



image.png



②AzureLogicAppsでで応答処理の作成

続けて、AzureLogicAppsにて、AlexaSkillConsoleからIntentを受け取り、応答を返すAPIサーバをAzureLogicAppsで作成します。

AlexaからJSONをうけとりJSONをかえすAPIサーバです。

「もっと丁寧にAzureLogicAppsの使いたいを知りたい!」という方は、以下のLINEBotの作成記事を参考にしてください。
ノンコーディングで質問に自動回答するLINE BOTを作ってみよう

AzureLogicAppsで開発するAPIサーバの全体像ですが以下のイメージになります。


image.png



②-1.HTTP要求の受信時のモジュールを作成

まずはAlexaからPOSTでJSONを受け取れるように、「HTTP要求の受信時」のモジュールを用意します。

メソッドをPSOTに設定し、JSONのスキーマを登録しておきます。

また、HTTP POSTのURLは、先程のAlexaDeveloperConsoleでエンドポイントに登録しておきます。


image.png


「HTTP要求の受信時」のモジュールに登録するJSONスキーマ(クリックすると開きます)

request.json
{ 
    "properties": { 
        "request": { 
            "properties": { 
                "dialogState": { 
                    "type": "string" 
                }, 
                "intent": { 
                    "properties": { 
                        "confirmationStatus": { 
                            "type": "string" 
                        }, 
                        "name": { 
                            "type": "string" 
                        }, 
                        "slots": { 
                            "properties": { 
                                "anatanoslotname": { 
                                    "properties": { 
                                        "confirmationStatus": { 
                                            "type": "string" 
                                        }, 
                                        "name": { 
                                            "type": "string" 
                                        }, 
                                        "resolutions": { 
                                            "properties": { 
                                                "resolutionsPerAuthority": { 
                                                    "items": { 
                                                        "properties": { 
                                                            "authority": { 
                                                                "type": "string" 
                                                            }, 
                                                            "status": { 
                                                                "properties": { 
                                                                    "code": { 
                                                                        "type": "string" 
                                                                    } 
                                                                }, 
                                                                "type": "object" 
                                                            }, 
                                                            "values": { 
                                                                "items": { 
                                                                    "properties": { 
                                                                        "value": { 
                                                                            "properties": { 
                                                                                "id": { 
                                                                                    "type": "string" 
                                                                                }, 
                                                                                "name": { 
                                                                                    "type": "string" 
                                                                                } 
                                                                            }, 
                                                                            "type": "object" 
                                                                        } 
                                                                    }, 
                                                                    "required": [ 
                                                                        "value" 
                                                                    ], 
                                                                    "type": "object" 
                                                                }, 
                                                                "type": "array" 
                                                            } 
                                                        }, 
                                                        "required": [ 
                                                            "authority", 
                                                            "status", 
                                                            "values" 
                                                        ], 
                                                        "type": "object" 
                                                    }, 
                                                    "type": "array" 
                                                } 
                                            }, 
                                            "type": "object" 
                                        }, 
                                        "value": { 
                                            "type": "string" 
                                        } 
                                    }, 
                                    "type": "object" 
                                } 
                            }, 
                            "type": "object" 
                        } 
                    }, 
                    "type": "object" 
                }, 
                "locale": { 
                    "type": "string" 
                }, 
                "requestId": { 
                    "type": "string" 
                }, 
                "timestamp": { 
                    "type": "string" 
                }, 
                "type": { 
                    "type": "string" 
                } 
            }, 
            "type": "object" 
        }, 
        "version": { 
            "type": "string" 
        } 
    }, 
    "type": "object" 
} 


②-2.スキル起動時(IntentがLaunchRequestの際)の応答処理を作成

次に、スキル起動時(IntentがLaunchRequestの際)の応答処理を作成していきます。

Alexaから受信するJSONの中のtypeスキーマにLaunchRequestが含まれるので、それがあるかどうか条件式で判別しましょう。

Trueの場合の応答処理を応答モジュールで用意します。



image.png


応答用のJSON(クリックすると開きます)

response1.json
{ 
  "response": { 
    "outputSpeech": { 
      "ssml": "<speak><prosody pitch='x-high'>ごんただよ!</prosody></speak>", 
      "type": "SSML" 
    }, 
    "reprompt": { 
      "outputSpeech": { 
        "ssml": "<speak><prosody pitch='x-high'>なにしてあそぶ?</prosody></speak>", 
        "type": "SSML" 
      } 
    }, 
    "shouldEndSession": "False" 
  }, 
  "version": "1.0" 
} 


②-3.Intentごとの応答処理を作成

同様に、起動時以外のIntentごとの応答処理を作っていきます。

最小のnameというスキーマにwalkingという値が入って送られてくるので、条件式を用意して、応答処理を作ります。



image.png


応答用のJSON(クリックすると開きます)

response2.json
{ 
  "response": { 
    "outputSpeech": { 
      "ssml": "<speak><audio src='https://dl.dropboxusercontent.com/s/あなたの音声ファイルのURL/あなたの音声ファイル.mp3' /></speak>", 
      "type": "SSML" 
    }, 
    "reprompt": { 
      "outputSpeech": { 
        "ssml": "<speak><prosody pitch='x-high'>ほかになにしてあそぶ?</prosody></speak>", 
        "type": "SSML" 
      } 
    }, 
    "shouldEndSession": "False" 
  }, 
  "version": "1.0" 
} 


③自作音声ファイルの準備とDropboxでの共有

それでは、AmazonEchoのスキルで使う音声ファイルを用意しましょう。今回はiPhoneで再生した筆者の愛犬のなき声を利用します。


③-1.AmazonEchoで利用可能な形式へ「FFmpeg」を用いて変換

利用可能な形式が限られているため、音声ファイルを変換します。

 - 90秒以内である

 - 特定のビットレート・周波数にフォーマットされている

 - 個人情報や機密情報を含まない

今回は、「FFmpeg」という無料ソフトウェアで対応する形式に変換しました。

参考 AlexaスキルでMP3ファイルを流そう!効果音を入れてワンランクアップのスキル開発

$ ffmpeg -y -i before.mp3 -ar 16000 -ab 48k -codec:a libmp3lame -ac 1 after.mp3 


③-2.dropboxでMP3ファイルを共有し、URLを作成する

次に、完成した音声ファイル(MP3ファイル)をオンライン上に共有します。今回は無料で利用可能なDropboxに保存します。

ファイルをアップロードし、共有を行うと、以下のような共有URLが取得できます。

https://www.dropbox.com/s/[取得したURL]?dl=0 
しかしこのままではAmazonEchoのスキル上で再生できないので、以下のように少しURLを編集します。このURLを先程のAzureLogicAppsの中のSSML文の中に入れてあげると、Dropboxの音声ファイルをAmazonEchoのスキル上で再生することができるようになります。

https://dl.dropboxusercontent.com/s/[取得したURL] 


公式のサウンドライブラリを使う / 音声ファイルを用意できない方へ

今回、自分で用意できない場合は、以下の公式のサウンドライブラリから音源を使うことも可能です。
サウンドライブラリ - Animal Sounds(動物の声)

<speak> 
    これはアレクサの通常音声です。音響効果「クマのうなり声(1)」を再生します。 
    <audio src='soundbank://soundlibrary/animals/amzn_sfx_bear_groan_roar_01'/> 
</speak> 


3. まとめ

今回はAzureLogicAppsを使ってAmazonEchoのスキルを作ってみました。一般的にはAWSのLambdaを使った開発が多いですが、JSONの受け渡しができるAPIサーバを用意できれば簡単にAmazonEchoのスキルを開発することができます。ぜひみなさんも作ってみてくださいね!

AzureLogicAppsはオフィス系のモジュール(JiraやSalesforceなど)が多いので、オフィスでのスマートスピーカーアプリ開発にもぴったりです。



image.png


コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)