Alexaでもparタグ使いたい!〜Alexaで発話とサウンドを並列再生する〜 / Speak with Background Music on Alexa

Alexaでもparタグ使いたい!〜Alexaで発話とサウンドを並列再生する〜 / Speak with Background Music on Alexa

【AAJUG 京都】 スキル企画・開発アドバンスド で発表したLT資料です。発話とサウンドの並列再生について話しました。

https://aajug.connpass.com/event/152201/

5caee8d2ccdb42a940545c47c6c01373?s=128

Kuniaki Shimizu

November 09, 2019
Tweet

Transcript

  1. Alexaでもparタグ使いたい! 〜Alexaで発話とサウンドを並列再生する〜 AAJUG KYOTO 11/9 LT

  2. About Myself 1

  3. Kuniaki Shimizu (@kun432) - シナジーマーケティング株式会社 - インフラエンジニア - Twitter/Facebook/Github/Hatena/Alexa -

    ポートフォリオ: https:/ /kun432.github.io/ 3 Hello!
  4. My Skills & Actions 4 - Alexa (JP): 12 -

    Google: 1 - Clova: 1 #スキル開発100チャレンジ - Alexa (US): 1
  5. • 本資料内における意見・発言等は個人の 見解であり、所属する組織・団体の見解 を代表するものでは、ありません。 • 今日はVoiceflowの話はしません • このLTは小ネタです。過度の期待はしないで ください。 5

    Disclaimer
  6. parタグについて 2

  7. Alexaスキル開発者が 一度はやりたいと思ったこと 7

  8. 8 発話させながら サウンドをBGMとして 流したい

  9. イメージ 9 BGM 効果音② 効果音① 発話

  10. 10 Googleならできる!

  11. <par>タグ 11 • Google Cloud Text-to-Speech で使える SSMLタグ • <par></par>で囲まれた中に<media>コンテナを

    複数並べると並列で再生される • <media>コンテナに<speak>や<audio>を入れる • <media>タグの属性で細かい制御が可能 ◦ xml:idでラベルを付けて、ラベルで指定 ◦ begin/endで開始・終了時間を設定 ◦ faceInDur/fadeOutDurでフェードイン・フェー ドアウト などなど
  12. </speak> 日本昔ばなしスキルです。今日のお話は、桃太郎。<break time="1s"/> <par> <media xml:id="bgm" end="obaasan_story.end+2s" fadeOutDur="2s"> <audio src="https://dl.dropboxusercontent.com/s/xxxxxxxxxx/momotaro.mp3"

    soundLevel="-20dB"/> </media> <media xml:id="intro" begin="0.7s"> <speak>むかーしむかし、あるところに、おじいさんとおばあさんが住んでいました。毎日、</speak> </media> <media xml:id="ojiisan_story" begin="intro.end+0.2s"> <speak>おじいさんは、山に芝刈りに、</speak> </media> <media xml:id="ojiisan_sound" begin="ojiisan_story.end-0.5s"> <audio src="https://dl.dropboxusercontent.com/s/xxxxxxxxxx/shibakari.mp3" repeatCount="2"/> </media> <media xml:id="obaasan_story" begin="ojiisan_story.end+0.5s"> <speak>おばあさんは、川に洗濯に、いっていました。</speak> </media> <media xml:id="obaasan_sound" begin="obaasan_story.end-2.0s" fadeOutDur="2s"> <audio src="https://dl.dropboxusercontent.com/s/xxxxxxxxxx/sentaku.mp3" clipEnd="3s"/> </media> </par> </speak>
  13. 13 デモ

  14. 14 BGMは「甘茶の音楽工房(https://amachamusic.chagasi.com)」様、効果音は「効果音ラボ( https://soundeffect-lab.info)」様のものを 使用させていただいております。ありがとうございます。

  15. 15 参考) https://medium.com/google-developers/advanced-ssml-for-actions-on-google-5cea45d868c9

  16. <par>タグで並列再生のメリット 16 • 表現力が豊か ◦ 楽しい・にぎやか・臨場感 ◦ ユースケースいろいろ • SSMLだけで書ける

    ◦ お手軽 ◦ 動的な発話生成とBGMをミックスできる • サウンド編集が不要 ◦ 音量や再生時間、フェードアウトやフェードイン をSSMLで制御
  17. 17 Alexaでは?

  18. Alexaでは・・・ 18 • SSMLでは、発話とオーディオはシーケン シャルに再生される ◦ 発話→サウンド→効果音→発話 ◦ 並列で再生させる方法がない •

    どうするか? ◦ サウンドと発話をミックスしたmp3作成 ▪ Polly/GarageBandとか • でも発話は動的に生成したい ◦ 複数パターンのmp3を用意する? ◦ いくつ用意するんや・・・
  19. 19 Alexaでは SSMLで並列再生は できない・・・

  20. 20 大事なことなのでもう一度

  21. 21 Googleなら できる!

  22. 22 Alexaではできない・・・

  23. 23 Alexaでもやりたい!

  24. Alexaでやってみた 3

  25. 25 alexa-polly-background-mixing-nodejs https://github.com/DanMittendorf/alexa-polly-background-mixing-nodejs/

  26. 26 alexa-polly-background-mixing-nodejs • digivoice.io の Daniel MittendorfさんによるPoC • Pollyで生成した発話mp3と予め用意したサウンドmp3を ミックスして、S3に生成

    ◦ SoX(Sound eXChange) → コマンドラインの音声加工ツール ◦ lambda-audio → SoXをLambdaで動かすためのライブラリ   - /tmpでバイナリを配置してを実行 • S3に生成して、URLをaudioタグで出力 • neuralにも対応(Joanna/Mathew, us-west-1, eu-west-1 のみ)
  27. const LaunchHandler = { canHandle(handlerInput) { const request = handlerInput.requestEnvelope.request;

    return request.type === 'LaunchRequest'; }, async handle(handlerInput) { let pollyVoice = await generatePollyUrl("<speak>むかーしむかし、あるところに、 おじいさんとおばあさんが住んでいました。毎日、おじいさんは山に芝刈りに、おばあさんは 川に洗濯に、いっていました。 </speak>", "Mizuki", background_sfx); let speechOutput = '日本昔ばなしスキルです。今日のお話は、「桃太郎」。 ' + pollyVoice + 'おしまい。'; return handlerInput.responseBuilder .speak(speechOutput) .getResponse(); }, };
  28. const mix_polly_with_background = (background_mp3, polly_voice_mp3, resulting_mp3, duration) => lambdaAudio.sox ('-m

    ' + background_mp3 + ' ' + polly_voice_mp3 + ' -C 48.01 ' + resulting_mp3 + ' rate 22050 gain -l 16 trim 0 '+duration).then(() => { return resulting_mp3 }).catch(err => console.error("mix error: "+err)) async function generatePollyUrl (ssml, voice, background_sound) { ・・・ try { ・・・ } catch (err) { let polly_voice = "polly_tmp_"+Math.round(+new Date() / 10)+".mp3"; if (fs.existsSync('/tmp/sox') && fs.existsSync('/tmp/lame')) { console.log('Found’); } else { await copyFiles(); } const pollyVoice = await generatePollyAudio(ssml, voice); await fs.outputFile('/tmp/'+polly_voice, pollyVoice.AudioStream); const duration = await mp3Duration('/tmp/'+polly_voice); var file = await mix_polly_with_background(background_sound, '/tmp/'+polly_voice, '/tmp/'+sound_mix_result, duration); const uploadFile = await fs.readFile(file); var writeToS3 = await writeAudioStreamToS3Bucket(uploadFile, sound_mix_result); return '<audio src="'+writeToS3.url+'"/>'; } }
  29. 29 デモ

  30. 30

  31. 31 課題 • Pollyの声になる、Alexaの声ではない。 • audioタグはPollyでは使えない。BGMとのミックスが限界 • 初回アクセス時は、Polly mp3生成+BGMミックス処理が 行われるため、応答までに時間がかかる

    ◦ Lambda側はタイムアウトを緩和 ◦ Alexa側はプログレッシブ応答で緩和がベター ◦ 2回目以降はキャッシュを使う(即応答する) • 動的に発話を生成する場合 ◦ 毎回ミックスが発生するので応答に時間がかかる ◦ 溜まったS3上のmp3ファイルは一定期間で削除等必要 • 細かいタイミングまでは制御できない ◦ Pollyの発話時間に合わせてミックスされるが、最後は いきなり切れる(フェードアウト設定追加がベター)
  32. 32 できなくはない

  33. 33 日本語向けに修正したfolk https://github.com/kun432/alexa-polly-background-mixing-nodejs

  34. 34 ここで残念なお知らせ

  35. 35 Lambdaのランタイム、 nodejs 10.xでは 動かない・・・

  36. 36 ランタイムはnodejs 8.xのみ

  37. 37 _人人人人人人人人人人_ > あと2ヶ月の命! <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

  38. 38 残された道・・・

  39. 39 方法は色々・・・ • Amazon Pollyで発話mp3生成、Amazon Elastic Trancoderでサウンドmp3とミックス • Google Cloud

    Text-to-Speech APIなら、SSML でparタグそのまま使えるけど、違和感 SSMLだけでサラッと・・・ というわけには行かない
  40. 40 もう一つの方法

  41. 41 alexa.uservoice.com

  42. 42 http://bit.ly/31IVpWK alexa.uservoice.com(US)

  43. 43 alexa.uservoice.com(JP) http://bit.ly/2WhNUVX

  44. 44 parタグ • <par>, <media>, <seq>は、Google独自の規格ではない。 ◦ SSMLでは他のマークアップとの相互運用性のサポートが 明記されている(VoiceXML・SMIL等) •

    SMIL(Synchronized Multimedia Integration Language) ◦ WWWでマルチメディアコンテンツを表現するためのマーク アップ言語 ◦ 静止画/動画/音声/文字などの、位置及び時間軸での レイアウトをXMLで記述し再生 ◦ <par>, <media>, <seq>はSMIL3で定義されている ◦ Googleはこの仕様に素直に従っているだけに見える つまり・・・
  45. 45 Alexaでもできるはず!

  46. 46 Please Vote!!!

  47. 47 https://techcrunch.com/2019/11/04/top-vcs-on-voice/

  48. 48 VCの目線 • VUIアプリの普及に必要な要素 ◦ Anchor / GimletなどのPodcastサービスの次の波 ◦ パーソナライズ

    ▪ 位置情報。自宅の外 ▪ カスタマイズされたオーディオ体験 • Resemble.io / Descript ◦ 新しいインタフェースや挙動 ▪ airpodそのものではなく、airpod-firstなプロダクト ◦ マネタイズ ▪ 広告ではなく、サブスクリプションモデル • Shine / Headspace / Calm
  49. まとめ 4

  50. 50 まとめ • SSMLでサウンドと音声を並列再生できるparタグ はとても良い! • Alexaでもできなくはないけど、SSMLで手軽に できるのが理想 • Alexaでできない理由はない。要望あげよう!

    • 「カスタマイズされた音声コンテンツ」がVUI普及 の一つのキー 開発者が、豊かな音声コンテンツを 手軽に作れることが重要な要素の一つ
  51. 51 おまけ • 時間軸での制御は便利だけど・・・ ◦ 「アレクサ、ゆっくり話して」でどうなる? ▪ Googleにはその機能はない(と思う) ◦ 時間の動的制御とかやりだしたらSSML沼

    ◦ 予め作成したmp3だとこの影響受けない(はず) ▪ GarageBandワークショップの機運・・・! • AlexaとGoogleのSSMLの違いも興味深い ◦ GoogleだとPollyみたいな音声使い分けはできない? ◦ audioタグとかsay-asのオプションが豊富 ▪ audioタグ単体で再生時間の制御とかできる ▪ say-asでunitを使うと、単数形・複数形を吸収して くれる(Alexaもやってくれる?)
  52. Thanks! Any questions?