LoginSignup
0
0

More than 3 years have passed since last update.

Amazon Pollyで合成したmp3をHTML5 audioコンポーネントで再生するまで

Posted at

text -> Polly -> mp3 -> DynamoDB -> api response -> blob -> html5 audio
をやっていきたいと思います。
リアルタイムのAPIに音声合成を組み込む場合の実装例になります。

環境

  • AWS Lambda + Boto3
  • Vue.js

前提

S3にファイルを保存するのではなく、バイナリとしてDynamoDBに格納します。
合成音声が短い文章である場合、この方法は十分に有効です。

Pollyで音声を合成

lambdaからboto3で使っていきます。
リアルタイム変換を行いますが、200文字でもAPIに組み込めるレベルの応答時間(1,000ms程度)です。
ポイントはresponse['AudioStream']がStreamingBodyクラスになります。
https://botocore.amazonaws.com/v1/documentation/api/latest/reference/response.html

def text_to_speach(text):
    polly = boto3.client("polly")

    response = polly.synthesize_speech(
        Text=text,
        OutputFormat="mp3",
        VoiceId="Mizuki")

    return response["AudioStream"].read()

DynamoDBへの格納

Pollyで変換したmp3のバイナリデータをDynamoDBに格納すると、バイナリ型として格納されます。
これはBase64でエンコードされたバイナリデータになります。
image.png

BlobURLの作成

DynamoDBに格納されたデータを何らかのAPIを通じてクライアントで取得します。
この際まだ音声データはBase64でエンコードされたバイナリデータです。
これをBlob形式に変換するには、以下のようにします。
ポイントは
- base64をデコードしてUnit8Arrayを作る
- Unit8Arrayからaudio/mpegを指定してBlobを作る
- BlobからBlobURLを作る
となります。

private base64ToBlob(base64Data) {
    const byteCharacters = atob(base64Data)
    const byteNumbers = new Array(byteCharacters.length)
    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i)
    }
    const byteArray = new Uint8Array(byteNumbers)
    const blobUrl = URL.createObjectURL(
      new Blob([byteArray], {
        type: 'audio/mpeg',
      })
    )

    return blobUrl
  }

再生

あとはこのBlobURLをaudioコンポーネントのsrcに指定してください。(以下はVueの場合)
<audio v-bind:src="srcBlobUrl" autoplay />

まとめ

  • Pollyのリアルタイム音声合成はAPIに組み込めるくらい速い
  • DynamoDBにバイナリをBase64エンコードで格納することができる
  • Base64をオンメモリでBlobに変換してaudioコンポーネントに利用できる
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0