Edited at

Alexa Skills Kit for Node.js (alexa-sdk) で音楽ファイルを鳴らす (2018/3/21 追記)

More than 1 year has passed since last update.


追記(2018/3/21)

Alexa Skills Kit Sound Libraryというものが公開されました。

Alexaスキル開発用に、効果音や背景音などのアセットを準備したようです。日本語環境でも使えます。

こちらを使えば、音楽ファイルを準備することなくSkillを作れちゃいますね!

もちろん、Sound Libraryの音を組み合わせて何か作る、ということもできそうです。


sample.js

let speechOut = '用意されている奴をコピペするだけ!簡単!';

speechOutput += "<audio src='https://s3.amazonaws.com/ask-soundlibrary/nature/amzn_sfx_rain_01.mp3'/>";

this.emit(':tell', speechOut);



前置き

これ、あんまり探しても分かりやすい情報がなかったので書いてみます。

対象者:

 ・JavaScript、Node.js初心者

 ・とりあえずサンプルなどでスキルを動かしてみた人


Sample Code


sample.js

let speechOut = '音楽はこのように鳴らします。';

speechOut += "<break time ='1s' />";
speechOut += "<audio src='https://xxx.mp3' />";
speechOut += "<break time ='1s' />";
speechOut += 'ね、簡単でしょ?';

this.emit(':tell', speechOut);



説明


SSMLについて

Alexa本体が文字を音声に変換する際、SSMLという言語を使用します。

Alexaの公式リファレンスに解説が載っています。

音声合成マークアップ言語(SSML)のリファレンス

SSMLには単純な出力以外にも、合成音声に装飾を加えることもできます。

HTMLの<h1><\h1>←みたいな奴の音声版ですね。


Alexaのレスポンスで音を鳴らす

上記の公式リファレンスにAlexaでのレスポンス方法が載っています。

"outputSpeech": {

"type": "SSML",
"ssml": "<speak>This output speech uses SSML.</speak>"
}


Alexa SDKで音を鳴らす

え...でもこれとサンプル等にあるthis.emitとかってどう繋がってるんだ?

SDKのReadmeにもなんか書いてあるけど・・・

全然わからん!(〇ャガー)

そこで、this.emitで使う場合の使い方を調べてみました。

つまりSDKの中身を追ってみます。

まず、emitというのはEventEmitterというNode.jsの機能です。

emit(イベント名, [arg1], [arg2], [...])という感じで、

Emitterに引数を渡して処理させます。

では、Alexa sdkでこのEmitter処理部はどこにいるのか、というと、

response.jsにいます。


response.js

        ':tell': function (speechOutput) {

if(this.isOverridden()) {
return;
}

this.handler.response = buildSpeechletResponse({
sessionAttributes: this.attributes,
output: getSSMLResponse(speechOutput),
shouldEndSession: true
});
this.emit(':responseReady');
},


さらにoutputを形成しているgetSSMLResponse関数を確認します。


response.js

function getSSMLResponse(message) {

if (message == null) { // jshint ignore:line
return null;
} else {
return {
type: 'SSML',
speech: `<speak> ${message} </speak>`
};
}
}

つまり、this.emitの引数に指定した言葉は

SSML形式でまるっと<speak>で囲って出力していることがわかりました。

ここまでわかれば、単純にemitで指定する単語にタグをはめこむだけか!というのがわかりますね。


sample.js

let speechOut = '音楽はこのように鳴らします。'; //なんか喋りたい文字

speechOut += "<break time ='1s' />"; //1秒休止
speechOut += "<audio src='https://xxx.mp3' />"; //音楽ファイルをはめこむ
speechOut += "<break time ='1s' />"; //1秒休止
speechOut += 'ね、簡単でしょ?'; //なんか喋りたい文字

this.emit(':tell', speechOut);


ちなみに、ReadMeによると、

this.emit(':tell', speechOut);



this.response.speak(speechOut);

this.emit(':responseReady');

の2つでも書けるみたいですね。

(自分もあまり詳しく調べていないが、SDKの中を見ればだいたい同じことをやってると思う。)


mp3について

Amazonが指定する形式に合わせる必要があります。

公式リファレンスに記載されていますが、ここにも書いておきます。


必要に応じて、変換ソフトウェアを使用してMP3ファイルを必要なコーデックバージョン(MPEGバージョン2)とビットレート(48 kbps)に変換してください。


Audacityとffmpegを使って変換すれば楽勝ですね。


音声を提供するために使用するMP3ファイルは、HTTPSを使用するエンドポイント上でホストされている必要があります。このエンドポイントでは、Amazon認定の認証局が署名したSSL証明書を提供する必要があります。


特にこだわりなければS3にupすれば問題ないでしょう。

また、音声ファイルを用意するのがめんどい・・という人は、Alexa Skills Kit Sound Libraryを使うと簡単にお試しできます。


おわりに

Alexa-sdkで音楽ファイルを鳴らす方法を書いてみました。

誰かの参考になれば幸いです。

筆者もかなり初心者なので、間違ってる点などありましたらお知らせください。:disappointed_relieved: