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

#0233(2025/09/04)Google Cloud Text-to-Speech入門

Posted at

実戦で使うGoogle Cloud Text-to-Speech入門

Google Cloud Text-to-Speechとは、テキストやSSMLを自然な音声に変換するAPIである。

なにができるのか(概要)

Google Cloud Text-to-Speech(以下、Google Cloud TTS)は、クラウド上でテキストを音声データに変換するサービスだ。日本語を含む多言語の音声合成、速度やピッチの調整、SSML(Speech Synthesis Markup Language)による細かな発話制御、複数コーデック(MP3/OGG_OPUS/LINEAR16)での出力などを備える。サーバーサイドでスクリプトやバッチから使いやすく、動画のナレーション生成、アプリ内読み上げ、IVR(音声応答)やEラーニング素材の量産などに向いている。

このガイドは「まずは最小コードで動かし、仕組みと選択肢を掴む」ことを目的に、準備→コード→実行方法→オプション比較→SSMLの要点→トラブルシュートの順で駆け足で押さえる。

使い始める準備(ライブラリ・認証・必要ファイル)

Google Cloud TTSはAPIキーではなく、原則サービスアカウント認証で使うのが基本だ(サーバー側の自動処理に適し、権限管理も明確)。手順はつぎのとおり。

  1. GCPプロジェクト作成:Billingを有効化しておく。
  2. Text-to-Speech APIを有効化:Cloud Consoleで当該APIを有効にする。
  3. サービスアカウント発行:最低限「Text-to-Speech管理・利用」に必要なロールを付与。
  4. 鍵(JSON)をダウンロード:安全な場所に保存する。
  5. 環境変数を設定:PythonクライアントはGOOGLE_APPLICATION_CREDENTIALSを見る。
pip install google-cloud-texttospeech

# macOS / Linux
export GOOGLE_APPLICATION_CREDENTIALS=/abs/path/to/service-account.json

# Windows(PowerShell)
$env:GOOGLE_APPLICATION_CREDENTIALS=\"C:\\path\\to\\service-account.json\"

音声ファイルを置く場所の準備

生成される音声をまとめるフォルダを用意しておくと後の運用が楽だ。ここでは例として./outを使う。

最小のPythonコード(プレーンテキスト/SSML両対応)

以下は最小限で読みやすいサンプルだ。入力がSSMLかどうかを自動判定し、希望のエンコーディングで保存する。サンプルは日本語ボイスを例示するが、後述の表を見ながら自由に差し替えられる。

from google.cloud import texttospeech
import re, os, html


def is_ssml(s: str) -> bool:
    return \"<speak\" in s and \"</speak>\" in s


def synthesize_to_file(text_or_ssml: str, outfile: str,
                       language_code: str = \"ja-JP\",
                       voice_name: str = \"ja-JP-Standard-C\",
                       speaking_rate: float = 1.0,
                       pitch: float = 0.0,
                       audio_encoding: str = \"MP3\",
                       sample_rate_hz: int | None = None) -> None:
    client = texttospeech.TextToSpeechClient()

    if is_ssml(text_or_ssml):
        synthesis_input = texttospeech.SynthesisInput(ssml=text_or_ssml)
    else:
        synthesis_input = texttospeech.SynthesisInput(text=text_or_ssml)

    voice = texttospeech.VoiceSelectionParams(
        language_code=language_code,
        name=voice_name
    )

    encoding_map = {
        \"MP3\": texttospeech.AudioEncoding.MP3,
        \"OGG_OPUS\": texttospeech.AudioEncoding.OGG_OPUS,
        \"LINEAR16\": texttospeech.AudioEncoding.LINEAR16,
    }
    config_kwargs = {
        \"audio_encoding\": encoding_map[audio_encoding],
        \"speaking_rate\": speaking_rate,
        \"pitch\": pitch,
    }
    if sample_rate_hz:
        config_kwargs[\"sample_rate_hertz\"] = sample_rate_hz

    audio_config = texttospeech.AudioConfig(**config_kwargs)

    response = client.synthesize_speech(
        input=synthesis_input, voice=voice, audio_config=audio_config
    )

    os.makedirs(os.path.dirname(outfile) or \".\", exist_ok=True)
    with open(outfile, \"wb\") as f:
        f.write(response.audio_content)

使い所と差し替えポイント

  • voice_name:日本語ならja-JP-Standard-*ja-JP-Wavenet-*など。品質・提供状況は時期により増減するので実際に試して選ぶ。
  • audio_encoding:用途で選択。編集前提ならLINEAR16、配信用ならMP3/OGGが軽い。
  • sample_rate_hz:未指定でも各ボイス既定のサンプルレートで返る。動画編集パイプラインに合わせたいときに指定する。

実行方法(プレーンテキスト→音声)

最小コードをtts_min.pyとして保存したら、次のように実行する。

python -c \"from tts_min import synthesize_to_file as run; run('こんにちは、世界。これはテストです。','out/hello.mp3')\"

ファイルとして与えたいときはPython側で読み込んで文字列にして渡せばよい。長文の場合でも、まずは一発で試し、必要に応じて文章を分割しよう(上限はおおむね数KBのリクエスト本文)。

実行方法(SSML→音声)

SSMLを使うと、休符(ポーズ)・読み上げ速度・句読点の扱いなどを細かく指定できる。最小構成は次のとおり。

<speak>
  <p>本日はご参加ありがとうございます。<s>最初に概要を説明します。</s></p>
  <p><s>速度を少し上げます。</s><break time=\"300ms\"/><s>それでは次へ。</s></p>
</speak>
python - <<'PY'
from tts_min import synthesize_to_file
ssml = """<speak><p><s>SSMLのサンプルです。</s></p><p><s>短く区切って発話します。</s></p></speak>"""
synthesize_to_file(ssml, "out/ssml_sample.ogg", audio_encoding="OGG_OPUS")
PY

オプション比較(同階層の選択肢)

エンコーディングとボイス種別は、最初に決める分岐点になりやすい。性質の違いをまとめておく。

選択肢 主な用途 特徴 ファイルサイズ 編集耐性 備考
MP3 配信・Web埋め込み 互換性が広い可逆ではない 小さめ ビットレートは自動設定
OGG_OPUS 配信・長尺 低ビットレートでも自然 とても小さい 音声向けに強い
LINEAR16 編集・DAW 非圧縮PCMで劣化なし 大きい サンプルレート合わせ推奨
ボイス種別 ねらい 備考
Standard コスト重視 基本品質で十分なことも多い
WaveNet 品質重視 自然さと子音の抜けが良い
Neural など 最新系 提供状況は随時拡充される

SSMLの最小パターン集(覚えるのはこれだけ)

  • <speak>…</speak>:SSML文書のルート。これがないとSSMLとして処理されない。
  • <p>…</p>:段落。ポーズを大きめに取りたいときに使う。
  • <s>…</s>:文。自然な切れ目でリズムが整う。
  • <break time=\"300ms\"/>:休符。timeはmsまたはsで指定。
  • <prosody rate=\"1.1\" pitch=\"-2st\">…</prosody>:速度・ピッチの微調整。

SSMLに不慣れなら、まずはプレーンテキストで自然さを確認し、次に必要な箇所にだけ<break><s>を足す、という段階的な作り方が扱いやすい。

トラブルシュート(つまずきやすい点)

  • 認証エラーGOOGLE_APPLICATION_CREDENTIALSが未設定、パスのタイプミス、権限不足を順に疑う。ローカルでgcloud auth application-default loginを使う方法もあるが、サーバー運用はサービスアカウント鍵が定番だ。
  • 文字数・長文エラー:リクエスト本文が大きすぎるとエラーになる。長文は段落や文で自然に分割し、複数回に分けて合成する。
  • 音量差・ノイズ:複数ファイルの音量が揃わないときは、DAWやffmpeg正規化する。PCMで受けてから最終段でエンコードすると劣化が一回で済む。
  • ボイスが見つからない:言語コードとボイス名の組み合わせが不一致の可能性。language_codeだけ指定してボイス一覧を取得し、存在するnameに差し替える。

一歩先へ(最小から実運用へ)

  • 分割と連結:長文を自然に分けて合成し、ffmpegのconcatで一本化すると扱いやすい。分割ロジックは段落→文→句読点の順で細かくすると聴感が滑らかだ。
  • キャッシュ:同じテキストはハッシュを鍵にして音声をキャッシュすれば、コスト・レイテンシが下がる。
  • パラメータ探索speaking_ratepitch耳で決める。小さい差でも印象が変わるので、A/Bで短く試すのが近道。

まとめ

Google Cloud TTSは、短いコードで実用的な音声をすばやく得られるのが強みだ。まずはサービスアカウントを用意し、最小の関数でプレーンテキストとSSMLを往復してみよう。出力のフォーマットとボイスを早めに決め、要件に合う最小構成から始めれば、量産や自動化への拡張も難しくない。

ボイスを探す(最短)

実装では「ボイス名は結局どれを指定すればいいのか」で迷いがちだ。TextToSpeechClient().list_voices(language_code='ja-JP')利用可能なボイス名を取得し、実際に数秒の文を合成して耳で決めるのが最短距離になる。とくに句読点の処理や子音の抜けはボイスごとに差が出る。

認証手段の比較(Pythonクライアント)

手段 用途 セットアップ 備考
サービスアカウント鍵 本番・バッチ 環境変数にJSONへのパスを設定 権限を最小化しやすい
ADC(アプリ既定認証) ローカル開発 gcloud auth application-default login 検証や試行に便利
APIキー 単純なREST キー文字列のみ クライアントでは非推奨傾向

実務の第一歩は、フォーマット・ボイス・発話速度を仮決めし、小さな素材で素早く耳合わせすること。迷ったら「MP3」「Standard」「既定レート」から始め、必要箇所だけ個別最適すればよい。
音量正規化と出力先の統一も効く。
命名規則も早めに決めよう。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?