question

kun432 avatar image
kun432 asked

Alexa Hostedスキルでmp3ファイルを再生する場合のTIPS

Alexa Hostedスキルでは、Hostedが用意してくれるS3に各種メディアファイルをアップロードして使えますが、メディアのパスを指定する際、以下のように署名付きURLにする必要があります。(以下はカードに画像を表示する場合)

const Util = require('util.js');
...
  handle(handlerInput){
    const pictureUrl = Util.getS3PreSignedUrl("Media/picture.jpg");
    return handlerInput.responseBuilder
        .speak('画像付きのハローワールドです')
        .withStandardCard('card title', 'card text', pictureUrl)
        .getResponse();
  }


音声ファイル(mp3等)をSSMLに含めて再生する場合も同じだよね、と思って、以下のようにするとエラーになります。

const Util = require('util.js');
...
  handle(handlerInput){
    const soundUrl = Util.getS3PreSignedUrl("Media/sample.mp3");
    const speechText = `音声ファイルを再生します。<audio src='${soundUrl}'/>`;
    return handlerInput.responseBuilder
        .speak(speechText)
        .getResponse();
  }

結果:

「スキルがリクエストに正しく応答できませんでした」


この理由は、署名付きURLにすると、通常SSMLでは使えない文字が含まれてしまい、SSMLとして解釈ができなくなるためです。これを回避するにはこれらの文字をエスケープさせてあげればよいです。以下は "lodash" というJavaScriptのユーティリティライブラリを使ってみました。

package.jsonに1行追加して、一旦、保存・デプロイするとライブラリが配置されます。

  "dependencies": {
    "ask-sdk-core": "^2.0.7",
    "ask-sdk-model": "^1.4.1",
    "aws-sdk": "^2.326.0",         // 最後にカンマ追加(忘れないように!)
    "lodash": "^4.17.11"           // 追加
  }

コードはこんな感じです。

const Util = require('util.js');
const Escape = require('lodash/escape');  // 追加

...
  handle(handlerInput){
    const soundUrl = Util.getS3PreSignedUrl("Media/sample.mp3");
    const speechText = `音声ファイルを再生します。<audio src='${Escape(soundUrl)}'/>`; // Escapeで署名付きURLをエスケープ
    return handlerInput.responseBuilder
        .speak(speechText)
        .getResponse();
  }


音声ファイルのフォーマットにもご注意ください。


参考)


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

https://developer.amazon.com/ja/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html#audio


Alexa Skills Kitサウンドライブラリ

https://developer.amazon.com/ja/docs/custom-skills/ask-soundlibrary.html


Alexa-hostedスキルを使用してスキルをエンドツーエンドで作成する

https://developer.amazon.com/ja/docs/hosted-skills/build-a-skill-end-to-end-using-an-alexa-hosted-skill.html

testingssmlhosted skillalexaskillawards2019
10 |5000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

@takatama_jp avatar image
@takatama_jp answered

ask-adk-core ver. 2.5.0 以上だと、Alexa.escapeXmlCharacters() が使えるので、わざわざ lodash を import しなくて良くなりました。

まず、package.json でバージョンを上げて、

 "dependencies": {
    "ask-sdk-core": "^2.6.0",

index.js で以下のように使います。

handle(handlerInput){
    const soundUrl = Util.getS3PreSignedUrl("Media/sample.mp3");
    const speechText = `音声ファイルを再生します。<audio src='${Alexa.escapeXmlCharacters(soundUrl)}'/>`;
1 comment
10 |5000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

ご指摘ありがとうございます!これ以外にも使えない機能があるので、hostedのデフォルトのバージョン、上げてほしいですね、、、

0 Likes 0 ·
aki avatar image
aki answered

参考になります。
これのpython版はございませんでしょうか。

1 comment
10 |5000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.