1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Gemini 3.1 Flash TTS入門 — 音声タグと多言語対応でAI音声生成をAPIで実装する

1
Last updated at Posted at 2026-06-09

Gemini 3.1 Flash TTSの概要イラスト — テキストから音声への変換フロー

はじめに

2026年4月15日、Googleは Gemini 3.1 Flash TTS(Text-to-Speech)をパブリックプレビューとして公開しました。従来のTTSモデルと異なる点は、音声タグ(Audio Tags) によるきめ細かな発話スタイル制御と、70言語以上のネイティブサポート、そして マルチスピーカー対話 の生成機能です。

この記事では、Gemini 3.1 Flash TTSの主要機能を整理し、Python SDKを使った実装例を紹介します。

この記事で学べること

  • Gemini 3.1 Flash TTSの特徴と既存TTSモデルとの違い
  • シングルスピーカー・マルチスピーカーの音声生成実装
  • 音声タグ(Audio Tags)による発話スタイル制御
  • API料金・制限事項と本番運用での注意点

前提条件

  • Python 3.9以上
  • Google AI Studioのアカウント(無料)
  • google-genai SDK: pip install google-genai

TL;DR

  • gemini-3.1-flash-tts-preview モデルで高品質なTTS生成が可能
  • [laughs][whispers] などの 200以上の音声タグ でリアルな発話制御
  • 最大2名のマルチスピーカー対話を生成できる
  • 70言語以上に対応(言語は入力テキストから自動検出)
  • 料金: テキスト入力$1/MTok、音声出力$20/MTok(バッチ処理は50%オフ)

Gemini 3.1 Flash TTSとは

Gemini 3.1 Flash TTS パイプライン — テキスト入力からPCM音声出力とSynthID透かし付与まで

Gemini 3.1 Flash TTSは、Googleが2026年4月15日に公開したテキスト読み上げ(TTS)モデルです。Google AI Studio・Vertex AI・Gemini APIで利用できます。

従来のTTSとの違い

機能 従来のTTS Gemini 3.1 Flash TTS
スタイル制御 限定的(速度・ピッチのみ) 200以上の音声タグで制御
言語 限定的 70言語以上に対応
マルチスピーカー 不可 最大2名まで対応
品質 標準 Elo 1,211(Artificial Analysis TTS Leaderboard)
SynthID なし 全出力に透かし入り

音声出力仕様

  • サンプルレート: 24,000 Hz
  • チャンネル: モノラル(1ch)
  • ビット深度: 16-bit PCM
  • コンテキストウィンドウ: 32,000トークン

TTS モデルはテキスト入力のみ受け付け、音声出力のみを生成します。画像・動画入力には対応していません。


環境セットアップ

pip install google-genai
import os
os.environ["GOOGLE_API_KEY"] = "YOUR_API_KEY"  # Google AI Studio で取得

シングルスピーカーの実装

最もシンプルな使い方です。generate_contentresponse_modalities=["AUDIO"] を指定します。

from google import genai
from google.genai import types
import wave

def save_wav(filename: str, pcm: bytes, channels: int = 1, rate: int = 24000, sample_width: int = 2) -> None:
    """PCM データを WAV ファイルに保存する"""
    with wave.open(filename, "wb") as wf:
        wf.setnchannels(channels)
        wf.setsampwidth(sample_width)
        wf.setframerate(rate)
        wf.writeframes(pcm)

client = genai.Client()

response = client.models.generate_content(
    model="gemini-3.1-flash-tts-preview",
    contents="Have a wonderful day!",
    config=types.GenerateContentConfig(
        response_modalities=["AUDIO"],
        speech_config=types.SpeechConfig(
            voice_config=types.VoiceConfig(
                prebuilt_voice_config=types.PrebuiltVoiceConfig(
                    voice_name="Kore",
                )
            )
        ),
    )
)

audio_data = response.candidates[0].content.parts[0].inline_data.data
save_wav("output.wav", audio_data)
print("音声ファイルを output.wav に保存しました")

音声タグ(Audio Tags)で発話スタイルを制御

Gemini 3.1 Flash TTSの最大の特徴が 音声タグ です。テキスト内にインラインで [タグ名] を挿入すると、その箇所の発話スタイルが変わります。

音声タグによる発話スタイル制御 — タグごとに異なる波形パターンを生成

主要な音声タグ一覧

カテゴリ タグ例
感情(ポジティブ) [excited], [cheerful], [happy], [amazed]
感情(ネガティブ) [sad], [crying], [panicked], [frustrated]
声の質 [whispers], [shouting], [whispering]
リアクション [laughs], [giggles], [sighs], [gasp]
スタイル [sarcastic], [dramatic], [serious]

実装例: 感情豊かなナレーション

# 音声タグを使った感情表現
script = """
[cheerful] Welcome to our product announcement!
[excited] Today, we're thrilled to share something incredible.
[whispers] But first, let me tell you a little secret...
[laughs] Actually, it's not a secret at all!
[serious] This is the most significant update we've ever shipped.
"""

response = client.models.generate_content(
    model="gemini-3.1-flash-tts-preview",
    contents=script,
    config=types.GenerateContentConfig(
        response_modalities=["AUDIO"],
        speech_config=types.SpeechConfig(
            voice_config=types.VoiceConfig(
                prebuilt_voice_config=types.PrebuiltVoiceConfig(
                    voice_name="Aoede",  # 表現力豊かな声に適したボイス
                )
            )
        ),
    )
)

audio_data = response.candidates[0].content.parts[0].inline_data.data
save_wav("narration_with_tags.wav", audio_data)

音声タグの効果は選択したボイスや文脈によって異なります。テキストの語調とタグが自然に一致するように記述すると、より一貫した出力が得られます。


マルチスピーカー対話の実装

複数の話者が登場する会話・ポッドキャスト・ダイアログを生成する場合は MultiSpeakerVoiceConfig を使います。

from google.genai import types

# 2名の話者を定義したダイアログ
dialogue = """
Joe: So what do you think about the new Gemini 3.1 Flash TTS model?
Jane: [excited] It's incredible! The audio tags feature is a game changer for content creators.
Joe: [curious] Really? Can you give me an example?
Jane: [laughs] Sure! You can make the AI whisper, laugh, or even sound sarcastic. 
Joe: [amazed] That's way more expressive than anything I've seen before.
Jane: [cheerful] And it supports over 70 languages natively!
"""

response = client.models.generate_content(
    model="gemini-3.1-flash-tts-preview",
    contents=dialogue,
    config=types.GenerateContentConfig(
        response_modalities=["AUDIO"],
        speech_config=types.SpeechConfig(
            multi_speaker_voice_config=types.MultiSpeakerVoiceConfig(
                speaker_voice_configs=[
                    types.SpeakerVoiceConfig(
                        speaker="Joe",
                        voice_config=types.VoiceConfig(
                            prebuilt_voice_config=types.PrebuiltVoiceConfig(
                                voice_name="Kore",
                            )
                        ),
                    ),
                    types.SpeakerVoiceConfig(
                        speaker="Jane",
                        voice_config=types.VoiceConfig(
                            prebuilt_voice_config=types.PrebuiltVoiceConfig(
                                voice_name="Puck",
                            )
                        ),
                    ),
                ]
            )
        ),
    )
)

audio_data = response.candidates[0].content.parts[0].inline_data.data
save_wav("dialogue.wav", audio_data)

マルチスピーカーモードでは voice_config の代わりに multi_speaker_voice_config を使います。両方を同時に指定するとエラーになります。


利用可能なボイス(30種類)

Gemini 3.1 Flash TTSには30種類のプリセットボイスが用意されています。

ボイス名 特徴
Kore クリーン、中性的
Puck 明るい、エネルギッシュ
Aoede 表現力豊か
Charon 落ち着いた、ディープ
Fenrir 力強い
Zephyr ソフト、温かみ

その他: Leda, Orus, Callirrhoe, Autonoe, Enceladus, Iapetus, Umbriel, Algieba, Despina, Erinome, Algenib, Rasalgethi, Laomedeia, Achernar, Alnilam, Schedar, Gacrux, Pulcherrima, Achird, Zubenelgenubi, Vindemiatrix, Sadachbia, Sadaltager, Sulafat


エラーハンドリングとリトライ実装

TTSリクエストは稀に500エラーを返すことがあります(モデルが音声トークンの代わりにテキストトークンを誤って出力するケース)。本番利用ではリトライロジックを実装することが推奨されています。

import time
from google.api_core import exceptions as google_exceptions

def generate_tts_with_retry(client, text: str, voice_name: str = "Kore", max_retries: int = 3) -> bytes:
    """リトライロジック付きTTS生成"""
    for attempt in range(max_retries):
        try:
            response = client.models.generate_content(
                model="gemini-3.1-flash-tts-preview",
                contents=text,
                config=types.GenerateContentConfig(
                    response_modalities=["AUDIO"],
                    speech_config=types.SpeechConfig(
                        voice_config=types.VoiceConfig(
                            prebuilt_voice_config=types.PrebuiltVoiceConfig(
                                voice_name=voice_name,
                            )
                        )
                    ),
                )
            )
            return response.candidates[0].content.parts[0].inline_data.data
        except (google_exceptions.InternalServerError, IndexError) as e:
            if attempt < max_retries - 1:
                wait_sec = 2 ** attempt  # 指数バックオフ
                print(f"リトライ {attempt + 1}/{max_retries} ({wait_sec}秒後)")
                time.sleep(wait_sec)
            else:
                raise e
    return b""

長文テキストの分割処理

公式ドキュメントによると、数分を超える長さの音声生成では品質が低下する場合があります。長いスクリプトはチャンクに分割して処理することが推奨されています。

import io

def split_text(text: str, max_chars: int = 500) -> list[str]:
    """テキストを文単位で分割する"""
    sentences = text.replace("", "\n").replace(". ", ". \n").split("\n")
    chunks, current = [], ""
    for sentence in sentences:
        if len(current) + len(sentence) > max_chars and current:
            chunks.append(current.strip())
            current = sentence
        else:
            current += sentence
    if current:
        chunks.append(current.strip())
    return chunks

def generate_long_audio(client, text: str, voice_name: str = "Kore", output_path: str = "output.wav") -> None:
    """長文を分割してTTS生成・結合する"""
    chunks = split_text(text)
    audio_parts = []
    
    for i, chunk in enumerate(chunks):
        print(f"チャンク {i+1}/{len(chunks)} を生成中...")
        audio_data = generate_tts_with_retry(client, chunk, voice_name)
        audio_parts.append(audio_data)
    
    # WAVファイルとして結合保存
    combined = b"".join(audio_parts)
    save_wav(output_path, combined)
    print(f"結合音声を {output_path} に保存しました")

API料金

公式料金ページによると以下の通りです(2026年4月時点)。

料金種別 通常 バッチ(50%オフ)
テキスト入力 $1.00 / MTok $0.50 / MTok
音声出力 $20.00 / MTok $10.00 / MTok

音声トークンのレートは 25トークン/秒 です。1分間の音声は約1,500音声トークンに相当します。

無料枠あり: Google AI Studioではレート制限付きで無料利用が可能です。開発・検証段階は無料枠で十分テストできます。


アクセス方法

Gemini 3.1 Flash TTSは以下の4つの経路でアクセスできます。

アクセス方法 用途
Google AI Studio コード不要のブラウザ体験・プロトタイピング
Gemini API(ai.google.dev 開発者向けAPI直接アクセス
Vertex AI エンタープライズ・大規模本番運用
Google Vids Workspaceユーザー向けドキュメント音声化

注意事項

SynthID 透かし

全ての生成音声にSynthIDの透かしが自動的に埋め込まれます。人間の耳には聞こえませんが、AI生成音声であることを識別するために使われます。

現在の制限

  • マルチスピーカーは 最大2名 まで
  • ストリーミング出力は 非対応(全音声を一括生成)
  • 数分を超える長文では品質が低下する可能性がある
  • 選択したボイスと異なる声になることがある

まとめ

Gemini 3.1 Flash TTSは、音声タグによる精細なスタイル制御・70言語対応・マルチスピーカーをシンプルなAPIで提供する新世代TTSモデルです。

  • gemini-3.1-flash-tts-preview で即日利用開始が可能
  • [excited][whispers] などのタグで感情豊かな音声を生成
  • 長文は分割処理とリトライロジックで安定した品質を維持
  • バッチモードで音声出力コストを50%削減できる

ポッドキャスト・ナレーション・ダイアログ生成など幅広いユースケースに対応できるモデルです。

参考リンク

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?