Gemini Live API を使用したリアルタイム翻訳

Gemini Live API は、gemini-3.5-live-translate-preview モデルを使用して、70 以上の言語間の低レイテンシのリアルタイム音声翻訳をサポートしています。翻訳設定で Live API を構成すると、ある言語の音声をストリーミングし、別の言語で翻訳されたオーディオ出力を受け取ることができるため、シームレスなリアルタイムの音声から音声への翻訳が可能になります。

ライブチャットとリアルタイム翻訳

どちらも Live API を使用しますが、リアルタイム翻訳のメンタルモデルは、会話型のリアルタイム エージェントのインタラクションとは異なります。

ライブ対応のエージェント リアルタイム翻訳
モデルはアシスタントとして機能します。ユーザーの代わりに、リスニング、推論、アクションを実行します。 モデルは通訳として機能します。リアルタイムの翻訳パイプラインとして動作します。
ターンベースのインタラクションを使用します。一時停止とインテント検出に依存し、割り込みを処理します。 継続的なストリーム処理を使用します。順番を待たずに、話者が話している間に翻訳します。
ツールとエージェントをサポートします。関数呼び出し、Google 検索、指示をネイティブにサポートします。 翻訳のみをサポートします。純粋な低レイテンシ翻訳。ツールや手順はサポートされていません。
完全なマルチモーダル。テキスト、音声、動画、画像の入力をサポートします。 音声が制限されています。厳格なリアルタイム レイテンシのしきい値を確保するため、入力は音声に限定されます。
詳細な構成。生成、音声、ツール、システム メッセージを使用します。 構成の簡素化。target_language_codeecho_target_language などの切り替えを設定します。

始める

次の例は、クライアントを初期化し、翻訳構成を使用して Live API に接続する方法を示しています。

Python

import asyncio
from google import genai
from google.genai import types

client = genai.Client()

model = "gemini-3.5-live-translate-preview"
config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    input_audio_transcription=types.AudioTranscriptionConfig(),
    output_audio_transcription=types.AudioTranscriptionConfig(),
    translation_config=types.TranslationConfig(
        target_language_code="pl",
        echo_target_language=True
    )
)

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        print("Session started with translation")
        # Start receiving the translated audio stream
        async for response in session.receive():
            if response.server_content:
                if response.server_content.input_transcription:
                    print(f"Input transcript: {response.server_content.input_transcription.text}")
                if response.server_content.output_transcription:
                    print(f"Output transcript: {response.server_content.output_transcription.text}")
                if response.server_content.model_turn:
                    for part in response.server_content.model_turn.parts:
                        if part.inline_data:
                            audio_data = part.inline_data.data
                            # Play or process the translated audio chunk
                            print(f"Received audio chunk ({len(audio_data)} bytes)")

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({});
const model = 'gemini-3.5-live-translate-preview';
const config = {
    responseModalities: [Modality.AUDIO],
    inputAudioTranscription: {},
    outputAudioTranscription: {},
    translationConfig: {
        targetLanguageCode: 'pl',
        echoTargetLanguage: true
    }
};

async function main() {
  const session = await ai.live.connect({
    model: model,
    config: config,
    callbacks: {
      onopen: () => console.debug('Opened'),
      onmessage: (message) => {
        const content = message.serverContent;
        if (content?.inputTranscription) {
          console.log('Input transcript:', content.inputTranscription.text);
        }
        if (content?.outputTranscription) {
          console.log('Output transcript:', content.outputTranscription.text);
        }
        if (content?.modelTurn?.parts) {
          for (const part of content.modelTurn.parts) {
            if (part.inlineData) {
              const audioData = part.inlineData.data;
              // Play or process the translated audio chunk (base64 encoded)
              console.debug(`Received audio chunk (${audioData.length} bytes)`);
            }
          }
        }
      },
      onerror: (e) => console.debug('Error:', e.message),
      onclose: (e) => console.debug('Close:', e.reason),
    },
  });

  console.debug("Session started with translation");
}

main();

WebSocket

const API_KEY = "YOUR_API_KEY";
const MODEL_NAME = "gemini-3.5-live-translate-preview";
const WS_URL = `wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent?key=${API_KEY}`;

const websocket = new WebSocket(WS_URL);

websocket.onopen = () => {
  console.log('WebSocket Connected');

  const setupMessage = {
    setup: {
      model: `models/${MODEL_NAME}`,
      generationConfig: {
        responseModalities: ['AUDIO'],
        inputAudioTranscription: {},
        outputAudioTranscription: {},
        translationConfig: {
          targetLanguageCode: 'pl',
          echoTargetLanguage: true
        }
      }
    }
  };
  websocket.send(JSON.stringify(setupMessage));
};

websocket.onmessage = (event) => {
  const response = JSON.parse(event.data);
  if (response.serverContent) {
    const content = response.serverContent;
    if (content.inputTranscription) {
      console.log('Input transcript:', content.inputTranscription.text, `(${content.inputTranscription.languageCode})`);
    }
    if (content.outputTranscription) {
      console.log('Output transcript:', content.outputTranscription.text, `(${content.outputTranscription.languageCode})`);
    }
    if (content.modelTurn?.parts) {
      for (const part of content.modelTurn.parts) {
        if (part.inlineData) {
          const audioData = part.inlineData.data;
          // Play or process the translated audio chunk (base64 encoded)
          console.debug(`Received audio chunk (${audioData.length} bytes)`);
        }
      }
    }
  }
};

音声を送信する

翻訳用の音声入力をストリーミングするには、リトル エンディアンの 16 ビット PCM 音声の RAW データを送信します。

  • 入力音声形式: 16 kHz の RAW 16 ビット PCM(モノラル、リトル エンディアン)。
  • 出力音声形式: RAW 16 ビット PCM、24kHz(モノラル、リトル エンディアン)。
  • チャンクサイズとレイテンシ: 100 ミリ秒のチャンクで音声を送信します。

次の例は、音声チャンクをセッションに送信する方法を示しています。

Python

# Assuming 'chunk' is your raw PCM audio bytes
await session.send_realtime_input(
    audio=types.Blob(
        data=chunk,
        mime_type="audio/pcm;rate=16000"
    )
)

JavaScript

// Assuming 'chunk' is a Buffer of raw PCM audio
session.sendRealtimeInput({
  audio: {
    data: chunk.toString('base64'),
    mimeType: 'audio/pcm;rate=16000'
  }
});

WebSocket

// Assuming 'chunk' is a Buffer of raw PCM audio
function sendAudioChunk(chunk) {
  if (websocket.readyState === WebSocket.OPEN) {
    const audioMessage = {
      realtimeInput: {
        audio: {
          data: chunk.toString('base64'),
          mimeType: 'audio/pcm;rate=16000'
        }
      }
    };
    websocket.send(JSON.stringify(audioMessage));
  }
}

構成

翻訳を有効にするには、セッションのセットアップ時に generationConfig 内で translationConfig を指定する必要があります。

設定メッセージの構成

generationConfig は、文字起こしを有効にするために次のフィールドをサポートしています。

  • inputAudioTranscription: このオブジェクトが存在する場合、モデルは入力音声のテキスト文字起こしを送信できます。
  • outputAudioTranscription: このオブジェクトが存在する場合、モデルは出力(翻訳された)音声のテキスト文字起こしを送信できます。

translationConfig は次のフィールドをサポートしています。

  • targetLanguageCode: モデルで翻訳する言語の BCP-47 言語コード(ポーランド語の場合は "pl"、スペイン語の場合は "es" など)。デフォルトは "en" です。
  • echoTargetLanguage: ターゲット言語ですでに入力されている音声をどのように処理するかを示すブール値。true に設定すると、モデルはすでにターゲット言語になっている入力音声をエコー(オウム返し)します。false に設定すると、入力音声がすでにターゲット言語である場合、モデルは無音のままになります。デフォルトは false です。

セットアップ メッセージの構造の例を次に示します。

"setup": {
    "model": "models/gemini-3.5-live-translate-preview",
    "generationConfig": {
      "responseModalities": [
        "AUDIO"
      ],
      "inputAudioTranscription": {},
      "outputAudioTranscription": {},
      "translationConfig": {
        "targetLanguageCode": "pl",
        "echoTargetLanguage": true
      }
    }
}

クライアントサイド アプリケーション用の一時トークン

クライアントからサーバーへのアプリケーションでは、エフェメラル トークン(現在は v1alpha)を使用して、API キーの公開を回避できます。

リアルタイム翻訳で一時トークンを使用する場合:

  1. v1alpha エンドポイントを使用する必要があります。
  2. 構成のロック: デフォルトでは、サーバーのトークン作成制約で translationConfig を指定する必要があります。これにより、変換構成がロックされ、クライアントによる改ざんを防ぐことができます。
  3. 構成のロック解除: クライアントサイドで translationConfig を設定できるようにする(ユーザーが独自のターゲット言語を選択できるようにするなど)には、トークン作成リクエストから translationConfig を省略し、代わりに "lock_additional_fields": [] を設定する必要があります。これにより、クライアントサイドで translationConfig を設定できるようになります。

制約付きのエフェメラル トークンを作成する

次の例は、変換制約を使用してエフェメラル トークンを作成する方法を示しています。

Python

import datetime
from google import genai

now = datetime.datetime.now(tz=datetime.timezone.utc)

client = genai.Client(
    http_options={'api_version': 'v1alpha'}
)

token = client.auth_tokens.create(
    config = {
        'uses': 1,
        'expire_time': now + datetime.timedelta(minutes=30),
        'live_connect_constraints': {
            'model': 'gemini-3.5-live-translate-preview',
            'config': {
                'translation_config': {
                    'target_language_code': 'pl',
                    'echo_target_language': True
                }
            }
        },
        'http_options': {'api_version': 'v1alpha'},
    }
)

JavaScript

import { GoogleGenAI } from "@google/genai";

const client = new GoogleGenAI({});
const expireTime = new Date(Date.now() + 30 * 60 * 1000).toISOString();

const token = await client.authTokens.create({
    config: {
        uses: 1,
        expireTime: expireTime,
        liveConnectConstraints: {
            model: 'gemini-3.5-live-translate-preview',
            config: {
                responseModalities: ['AUDIO'],
                inputAudioTranscription: {},
                outputAudioTranscription: {},
                translationConfig: {
                    targetLanguageCode: 'pl',
                    echoTargetLanguage: true
                }
            }
        },
        httpOptions: {
            apiVersion: 'v1alpha'
        }
    },
});

制限事項

  • 入力モード: 翻訳では音声入力のみがサポートされています。テキスト入力は対象外です。
  • 音声の複製: 音声の複製は一貫性がない場合があります。長い一時停止の後に音声が変化したり、発話の開始方法に基づいて性別が誤って割り当てられたり、複数の話者がすばやく会話しているときに音声が 1 つの音声でスタックしたりすることがあります。
  • 言語検出: 言語検出は、強いアクセント、類似した言語(スペイン語とポルトガル語など)、言語の急速な切り替えに苦労します。注: これは入力文字起こしにのみ影響します。言語コードと最終的な翻訳は正確である必要があります。
  • 背景音: モデルはノイズや音楽を除去してクリアな音声を生成するように設計されていますが、すべての背景音が無視されるとは限りません。
  • Echo Target Language: echoTargetLanguage: true の場合、入力音声がすでにターゲット言語であるときに、バックグラウンド ノイズや音楽によって翻訳された音声にアーティファクトが生じる可能性があります。

サポートされている言語

リアルタイム翻訳でサポートされている言語は次のとおりです。

言語 BCP-47 コード 言語 BCP-47 コード
アフリカーンス語 af カザフ語 kk
アカン語 ak クメール語 km
アルバニア語 sq キニヤルワンダ語 rw
アムハラ語 am 韓国語 ko
アラビア語 ar ラオ語 lo
アルメニア語 hy ラトビア語 lv
アゼルバイジャン語 az リトアニア語 lt
バスク語 eu マケドニア語 mk
ベラルーシ語 be マレー語 ミリ秒
ベンガル語 bn マラヤーラム語 ml
ブルガリア語 bg マラーティー語 mr
ビルマ語(ミャンマー) my モンゴル語 mn
カタルーニャ語 ca ネパール語 ne
中国語(簡体) zh-Hans ノルウェー語 no、nb
中国語 (繁体) zh-Hant ペルシャ語 fa
クロアチア語 時間 ポーランド語 pl
チェコ語 cs ポルトガル語(ブラジル) pt-BR
デンマーク語 da ポルトガル語 (ポルトガル) pt-PT
オランダ語 nl パンジャブ語 pa
英語 en ルーマニア語 ro
エストニア語 et ロシア語 ru
フィリピン語 fil セルビア語 sr
フィンランド語 fi シンド語 sd
フランス語 fr シンハラ語 si
ガリシア語 gl スロバキア語 sk
ジョージア語 ka スロベニア語 sl
ドイツ語 de スペイン語 es
ギリシャ語 el スンダ語 su
グジャラート語 gu スワヒリ語 sw
ハウサ語 ha スウェーデン語 sv
ヘブライ語 タミル語 ta
ヒンディー語 hi テルグ語 te
ハンガリー語 hu タイ語 th
アイスランド語 = トルコ語 tr
インドネシア語 id ウクライナ語 uk
イタリア語 it ウルドゥー語 ur
日本語 ja ウズベク語 uz
ジャワ語 jv ベトナム語 vi
カンナダ語 kn ズールー語 zu

次のステップ