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

#追記(2018/3/21)
[Alexa Skills Kit Sound Library](https://developer.amazon.com/ja/docs/custom-skills/ask-soundlibrary.html)というものが公開されました。
Alexaスキル開発用に、効果音や背景音などのアセットを準備したようです。日本語環境でも使えます。
こちらを使えば、音楽ファイルを準備することなくSkillを作れちゃいますね！
もちろん、Sound Libraryの音を組み合わせて何か作る、ということもできそうです。

```Javascript: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
```Javascript: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）のリファレンス](https://developer.amazon.com/ja/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html)

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](https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/blob/master/lib/response.js)にいます。

```Javascript: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関数を確認します。

```Javascript: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で指定する単語にタグをはめこむだけか！**というのがわかりますね。

```Javascript: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](https://developer.amazon.com/ja/docs/custom-skills/ask-soundlibrary.html)を使うと簡単にお試しできます。

#おわりに

Alexa-sdkで音楽ファイルを鳴らす方法を書いてみました。
誰かの参考になれば幸いです。
筆者もかなり初心者なので、間違ってる点などありましたらお知らせください。:disappointed_relieved: