15
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ElixirAdvent Calendar 2023

Day 17

Amazon Polly による「文書の読み上げ」を Livebook から実行する

Last updated at Posted at 2023-12-12

はじめに

Amazon Polly は AWS 上で使える AI による音声合成 = 文書の読み上げサービスです

ブラウザからお手軽に試す場合、以下の記事を参考にしてください

本記事では Elixir の Livebook から Polly を使い、文章の読み上げを実装します

実装したノートブックはこちら

Livebook とは

Livebook は Elixir のコードをブラウザから実行し、結果を表示してくれるツールです

Python における Jupyter のようなもので、 Elixir 入門や Elixir を使ったデータ分析、データの視覚化などに適しています

はじめ方は以下の記事を参考にしてください

セットアップ

Livebook で新しいノートブックを開いたら、先頭のセットアップセルに以下のコードを入力し、実行してください

Mix.install([
  {:aws, "~> 0.13"},
  {:hackney, "~> 1.20"},
  {:kino, "~> 0.11"}
])

AWS サービスの操作用に AWS Elixir というモジュールをインストールしています

クライアントの準備

AWS の認証情報を入力するためのテキストボックスを準備します

access_key_id_input = Kino.Input.password("ACCESS_KEY_ID")
secret_access_key_input = Kino.Input.password("SECRET_ACCESS_KEY")
region_input = Kino.Input.text("REGION")

[
  access_key_id_input,
  secret_access_key_input,
  region_input
]
|> Kino.Layout.grid(columns: 3)

セルを実行して表示されたテキストボックスにそれぞれ入力してください

スクリーンショット 2023-12-10 15.13.58.png

AWS の API と通信するためのクライアントを用意します
この際、先ほどの認証情報を受け渡します

client =
  AWS.Client.create(
    Kino.Input.read(access_key_id_input),
    Kino.Input.read(secret_access_key_input),
    Kino.Input.read(region_input)
  )

音声合成

Polly には standard と neural の2種類のエンジン(音声合成を処理するプログラム)があります

まずは standard を試してみます

describe_voices で standard エンジンの日本語( js-JP )で使える声の一覧を取得しましょう

voice_list =
  client
  |> AWS.Polly.describe_voices("standard", nil, "ja-JP")
  |> elem(1)
  |> Map.get("Voices")
  |> Enum.map(fn voice ->
    Map.take(voice, ["Id", "Gender", "Name", "LanguageName"])
  end)

Kino.DataTable.new(voice_list)

実行結果
スクリーンショット 2023-12-09 22.41.18.png

男性の Takumi と女性の Mizuki が使えるようです

今回は Takumi を使ってみましょう

次に読み上げる文章を入力するため、テキストエリアを作ります

text_input = Kino.Input.textarea("TEXT")

表示されたテキストエリアに読み上げさせたい文章を入力します

スクリーンショット 2023-12-09 22.55.54.png

本記事では「オオカミと七ひきの子ヤギ」の冒頭を読ませてみます

synthesize_speech にエンジン、言語、声の ID 、出力フォーマット、読ませたい文章を指定します

通常の AWS の API は実行結果が JSON で返ってきますが、 synthesize_speech の場合、音声のバイナリデータが返ってきます

そのため、 JSON として結果を読み込まないよう、オプション(第3引数)に receive_body_as_binary?: true を指定しています

result =
  client
  |> AWS.Polly.synthesize_speech(
    %{
      "Engine" => "standard",
      "LanguageCode" => "ja-JP",
      "VoiceId" => "Takumi",
      "OutputFormat" => "mp3",
      "Text" => Kino.Input.read(text_input)
    },
    receive_body_as_binary?: true
  )
  |> elem(1)
  |> Map.get("Body")

実行結果

<<73, 68, 51, 4, 0, 0, 0, 0, 0, 35, 84, 83, 83, 69, 0, 0, 0, 15, 0, 0, 3, 76, 97, 118, 102, 53, 56,
  46, 55, 54, 46, 49, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 243, 96, 196, 0, ...>>

このバイナリデータを Base64 形式に変換することで、 Web 上で再生できるようになります

result
|> Base.encode64()
|> then(fn base64 ->
  Kino.HTML.new("""
  <audio controls src="data:audio/mp3;base64,#{base64}">
  </audio>
  """)
end)

実行結果
スクリーンショット 2023-12-09 23.01.31.png

表示されたコントロールの再生ボタンをクリックすると、以下の動画のように音声が再生されます

多少ぎこちなくはありますが、きちんと読み上げています

neural エンジンも試してみましょう

neural エンジンの日本語で使用可能な声の一覧を取得します

voice_list =
  client
  |> AWS.Polly.describe_voices("neural", nil, "ja-JP")
  |> elem(1)
  |> Map.get("Voices")
  |> Enum.map(fn voice ->
    Map.take(voice, ["Id", "Gender", "Name", "LanguageName"])
  end)

Kino.DataTable.new(voice_list)

スクリーンショット 2023-12-09 23.03.44.png

Takumi は neural エンジンでも付き合えるようなので、引き続き Takumi に喋ってもらいます

client
|> AWS.Polly.synthesize_speech(
  %{
    "Engine" => "neural",
    "LanguageCode" => "ja-JP",
    "VoiceId" => "Takumi",
    "OutputFormat" => "mp3",
    "Text" => Kino.Input.read(text_input)
  },
  receive_body_as_binary?: true
)
|> elem(1)
|> Map.get("Body")
|> Base.encode64()
|> then(fn base64 ->
  Kino.HTML.new("""
  <audio controls src="data:audio/mp3;base64,#{base64}">
  </audio>
  """)
end)

実行結果

さっきより滑らかになりました

まとめ

Livebook から Amazon Polly による音声合成が実行できました

Livebook は音声や画像などのデータも簡単に扱えるのが便利ですね

Transcribe と Polly を組み合わせれば、音声での自動応答システムも簡単に作れそうです

15
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
15
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?