7
5

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 3 years have passed since last update.

Text to Speech REST API(Azure)を使ってみる(Elixir)

Last updated at Posted at 2021-03-12

はじめに

2021/03/20 追記

ドキュメント

依存関係

mix.exs
  defp deps do
    [
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
      {:httpoison, "~> 1.8"},
      {:jason, "~> 1.2"}
    ]
  end
$ mix deps.get

ソースコード

lib/azure/text_to_speech.ex
defmodule Azure.TextToSpeech do
  @subscription_key "ひみつ"

  def run!(text) do
    access_token()
    |> voice(text)
  end

  def access_token do
    headers = [
      "Ocp-Apim-Subscription-Key": @subscription_key,
      "Content-type": "application/x-www-form-urlencoded"
    ]

    "https://japaneast.api.cognitive.microsoft.com/sts/v1.0/issuetoken"
    |> HTTPoison.post!("", headers)
    |> Map.get(:body)
  end

  def voices_list(token) do
    "https://japaneast.tts.speech.microsoft.com/cognitiveservices/voices/list"
    |> HTTPoison.get!(authorization_header(token))
    |> Map.get(:body)
    |> Jason.decode!()
  end

  def voice(token, text) do
    headers =
      authorization_header(token)
      |> Keyword.merge(
        "Content-Type": "application/ssml+xml",
        "X-Microsoft-OutputFormat": "riff-24khz-16bit-mono-pcm",
        "User-Agent": "awesome"
      )

    locale = "ja-JP"
    gender = "Female"

    %{"Name" => name} =
      voices_list(token)
      |> Enum.filter(fn %{"Locale" => l} -> l == locale end)
      |> Enum.filter(fn %{"Gender" => g} -> g == gender end)
      |> Enum.random()

    body = """
    <speak version='1.0' xml:lang='#{locale}'>
      <voice xml:lang='#{locale}' xml:gender='#{gender}' name='#{name}'>
        <prosody volume="100.0">
          #{text}
        </prosody>
      </voice>
    </speak>
    """

    "https://japaneast.tts.speech.microsoft.com/cognitiveservices/v1"
    |> HTTPoison.post!(body, headers)
    |> Map.get(:body)
  end

  defp authorization_header(token) do
    [Authorization: "Bearer #{token}"]
  end
end
  • User-Agentは必須って書いてあるけど、サンプルにはないし、実際なくても動いたしどうなんだろう?
  • という件はIssueを書いてみました
  • どうなるでしょう:interrobang::interrobang::interrobang:

サブスクリプションキーの取得方法

スクリーンショット 2021-03-12 21.48.45.png

  • 飛んだ先のフォームでは、価格レベルは、Free F0を選びました
  • Cognitive Services の価格—Speech Servicesにあるように、standardの使い方なら、1 か月あたり 5 million 文字まで無料とのことらしいです
  • (5 million 文字とか言われてもピンときていません)
  • 毎朝ちょっとした天気予報をしゃべらせるくらいならきっと範囲内でしょう

Run

$ iex -S mix

iex> Azure.TextToSpeech.run!("こんにちは Azure awesome") |> (&(File.write("output.wav", &1))).()
  • output.wavというファイルに書き出しています
  • (&(File.write("output.wav", &1))).()はカッコばかり書いて
  • $\huge{カッコつけているだけです}$

macOSなら

$ afplay output.wav

Wrapping Up :lgtm::lgtm::lgtm::lgtm::lgtm:

最後の最後に

Elixirってなによ:interrobang:という方へ

image.png

EsvA7uQU0AEoTuX.jpeg

(@piacerex さん作 :pray::pray_tone1::pray_tone2::pray_tone3::pray_tone4::pray_tone5:)

7
5
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
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?