クマは森で用を足しますか?

アウトプットは重要です。

APL の SpeakItem コマンドで効果音を鳴らせなくて困る

APL (Alexa Presentation Language) の SpeakItem コマンドで効果音を鳴らしたいのですが、これが何故かうまくいかなくて困っています。ここまで、躓いてはコードを書き直すこと数回。

これがうまくいかない

APL トレーニングシリーズ第 3 回でも、アイテムの speech プロパティに「MP3 ファイルの URL を直接指定」して SpeakItem で再生することが可能だと言われています。

developer.amazon.com

フォーラムでも「できるよ(でも実機だけ)」と書かれていましたので、Fire HD 10 の「Show モード」で試してみたのですが、駄目でした。まだ何か、正しく理解できていないところがあるようです。

forums.developer.amazon.com

やりたいこと

SpeakItem コマンドと SetPage コマンドを使い、下記のような動作を実現したいと考えています。

  1. 音声を喋らせる
  2. 効果音を鳴らす
  3. 次のページに進む
  4. ステップ 1 へ(繰り返し)

トランスフォーマーの ssmlToSpeech は現在 audio タグをサポートしていないそうで、バックログで計画されてはいるのだとか。確かにうまく再生してもらえなかったので、音声部分についてのみ SSML で書いたものをトランスフォーマーに MP3 化させて、効果音については MP3 で用意することにしました。

forums.developer.amazon.com

何故なんだろう

長いので URL の途中を省略していますが、Alexa Hosted スキルで S3 に置いてある効果音 sound.mp3 が下記 "sound" で、SSML で書いた音声部分をトランスフォーマーの ssmlToSpeech で変換したものが "speech" です。

    "properties": {
        "sound": "https://amzn1-ask-skill- ... .s3.amazonaws.com/Media/sound.mp3? ... &X-Amz-SignedHeaders=host",
        "speech": "https://kopytko.amazon.com/3/ ... 74b88bbb69a18cdd47a3b1da8c5ccba5ed287e60/resource.mp3"
    },

結局のところどちらも MP3 のはずなのですが、前者の効果音 MP3 を SpeakItem で再生しようとすると ExecuteCommands がそこで止まってしまう一方、後者の音声 MP3 は問題なく再生することができます。この動作の違いが腑に落ちていません。

    "items": [
        {
            "type": "Text",
            "id": "soundItem",
            "speech": "${payload.data.properties.sound}",
            "position": "absolute",
            "width": 0,
            "height": 0
        },
        {
            "type": "Text",
            "id": "speechItem",
            "speech": "${payload.data.properties.speech}",
            "position": "absolute",
            "width": 0,
            "height": 0
        },

この効果音 MP3 を単純に ResponseBuilder の speak() にかけてみると、そちらでは普通に再生されます。同じところに置いてある背景画像もちゃんと表示されることから、S3 からファイルを取り出す方法が間違っているわけではないようです。

    const sound = Util.getS3PreSignedUrl('Media/sound.mp3')
    handlerInput.responseBuilder.speak(`<audio src="${Escape(sound)}"/>`)

むむ。