Gemini Live API mendukung transkripsi speech-to-text real-time dengan latensi rendah menggunakan model gemini-3.5-transcribe-live. Dengan terhubung ke Live API melalui WebSockets atau menggunakan Google Gen AI SDK, Anda dapat melakukan streaming input audio berkelanjutan dan menerima transkripsi teks inkremental secara real-time saat ucapan terjadi.
Dengan memanfaatkan Gemini Live API, platform developer seperti Agora, Fishjam, LiveKit, Pipecat, Vercel, dan Vision Agents memungkinkan developer membangun dan men-deploy antarmuka berbasis suara berperforma tinggi dengan mudah. Platform ini mengelola infrastruktur streaming media real-time yang kompleks di balik layar, sehingga developer dapat sepenuhnya berfokus pada pembuatan pengalaman pengguna.
Agen langsung versus Transkripsi langsung
Meskipun keduanya menggunakan koneksi streaming dua arah Live API, Transkripsi Instan beroperasi sebagai pipeline pengenalan ucapan khusus dengan latensi rendah, bukan sebagai agen percakapan.
| Fitur | Agen Langsung | Transkripsi Langsung |
|---|---|---|
| Peran utama | Asisten percakapan yang mendengarkan, memberikan alasan, dan berbicara kembali. | Pipeline speech-to-text real-time yang mentranskripsikan audio masuk. |
| Modalitas respons | Audio dan teks lisan (response_modalities=["AUDIO"]). |
Transkripsi teks streaming (response_modalities=["TEXT"]). |
| Gaya interaksi | Dialog berbasis giliran dengan deteksi jeda dan interupsi. | Pemrosesan streaming berkelanjutan saat penutur berbicara. |
| Fitur yang didukung | Pemanggilan fungsi, Google Penelusuran, petunjuk sistem. | Penyesuaian ucapan (custom_vocabulary), deteksi bahasa, VAD manual & hybrid, Transkripsi cerdas. |
| Input stream | Multimodal: audio, video, gambar, teks. | Input audio (PCM 16-bit mentah). |
Mulai
Contoh berikut menunjukkan cara membuka sesi streaming dua arah dengan gemini-3.5-transcribe-live dan menerima transkripsi real-time.
Python
import asyncio
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-3.5-transcribe-live"
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(
language_codes=[], # Automatic language detection
),
)
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
print("Session established with Live Transcription")
# Receive transcription events
async for response in session.receive():
server_content = response.server_content
if server_content and server_content.input_transcription:
print("Transcript:", server_content.input_transcription.text)
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-3.5-transcribe-live';
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {
languageCodes: [], // Automatic language detection
},
};
async function main() {
const session = await ai.live.connect({
model: model,
config: config,
callbacks: {
onopen: () => console.log('Connected to Live Transcription'),
onmessage: (message) => {
const content = message.serverContent;
if (content?.inputTranscription) {
console.log('Transcript:', content.inputTranscription.text);
}
},
onerror: (e) => console.error('Error:', e.message),
onclose: (e) => console.log('Connection closed:', e.reason),
},
});
}
main();
WebSockets
const API_KEY = "YOUR_API_KEY";
const MODEL_NAME = "gemini-3.5-transcribe-live";
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: ['TEXT'],
},
inputAudioTranscription: {
languageCodes: []
}
}
};
websocket.send(JSON.stringify(setupMessage));
};
websocket.onmessage = (event) => {
const response = JSON.parse(event.data);
const content = response.serverContent;
if (content?.inputTranscription) {
console.log('Transcript:', content.inputTranscription.text);
}
};
Transkripsi sementara dan akhir
Saat audio di-streaming ke Live API, server akan memancarkan dua kolom transkripsi pelengkap dalam server_content:
interim_input_transcription: hipotesis parsial spekulatif latensi rendah diperbarui saat pembicara sedang aktif berbicara. Update parsial ini terjadi dengan cepat dan jeda minimal. Gunakaninterim_input_transcriptionuntuk merender subtitel UI live responsif atau pratinjau teks.input_transcription: transkrip akhir yang dikeluarkan saat pembicara menjeda, giliran selesai, atau ucapan diselesaikan. Setelah dikeluarkan, teks ini merepresentasikan transkripsi resmi model dari segmen ucapan tersebut. Dalam mode transkripsi cerdas, hal ini akan mencakup respons yang sudah dibersihkan dan diformat.
Contoh berikut menunjukkan cara menampilkan parsial sementara streaming dan melakukan transkrip akhir:
Python
async def receive_transcripts(session):
async for response in session.receive():
server_content = response.server_content
if not server_content:
continue
# Real-time interim hypothesis (updates dynamically as user speaks)
if server_content.interim_input_transcription:
interim_text = server_content.interim_input_transcription.text
print(f"\r[Interim] {interim_text}", end="", flush=True)
# Finalized transcript (emitted on speech completion)
if server_content.input_transcription:
final_text = server_content.input_transcription.text
print(f"\n[Final] {final_text}")
JavaScript
onmessage: (message) => {
const content = message.serverContent;
if (!content) return;
if (content.interimInputTranscription) {
// Update live subtitle preview on screen
renderInterimPreview(content.interimInputTranscription.text);
}
if (content.inputTranscription) {
// Append final committed transcript to chat history
commitFinalTranscript(content.inputTranscription.text);
}
};
WebSockets
websocket.onmessage = (event) => {
const response = JSON.parse(event.data);
const content = response.serverContent;
if (content?.interimInputTranscription) {
console.log('[Interim]:', content.interimInputTranscription.text);
}
if (content?.inputTranscription) {
console.log('[Final]:', content.inputTranscription.text);
}
};
Mengirim audio
Streaming potongan audio melalui koneksi aktif sebagai audio PCM 16-bit mentah.
- Format audio: PCM 16-bit mentah pada 16 kHz (mono, little-endian).
- Ukuran chunk: Kirim audio dalam chunk 100 md (1.024 hingga 2.048 frame).
Jenis MIME:
audio/pcm;rate=16000(atau sample rate yang cocok).
Python
# Stream a raw PCM audio chunk
await session.send_realtime_input(
audio=types.Blob(
data=audio_chunk_bytes,
mime_type="audio/pcm;rate=16000"
)
)
# Signal the end of the audio stream when finished
await session.send_realtime_input(audio_stream_end=True)
JavaScript
// Send base64-encoded PCM audio chunk
session.sendRealtimeInput({
audio: {
data: audioChunkBase64,
mimeType: 'audio/pcm;rate=16000'
}
});
// Signal stream end
session.sendRealtimeInput({
audioStreamEnd: true
});
WebSockets
// Send base64-encoded PCM audio chunk
websocket.send(JSON.stringify({
realtimeInput: {
audio: {
data: audioChunkBase64,
mimeType: 'audio/pcm;rate=16000'
}
}
}));
// Signal stream end
websocket.send(JSON.stringify({
realtimeInput: {
audioStreamEnd: true
}
}));
Fitur transkripsi
Deteksi bahasa otomatis
Secara default, tidak menyertakan language_codes atau menyetel language_codes=[] akan mengaktifkan identifikasi bahasa otomatis. Model ini secara dinamis mendeteksi bahasa yang diucapkan di seluruh ucapan, termasuk percakapan multibahasa dan peralihan kode.
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(
language_codes=[],
),
)
JavaScript
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {
languageCodes: [],
},
};
WebSockets
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
inputAudioTranscription: {
languageCodes: [],
},
},
};
websocket.send(JSON.stringify(setupMessage));
Petunjuk bahasa tertentu
Berikan kode bahasa BCP-47 eksplisit (misalnya, ["es-ES"] untuk bahasa Spanyol atau ["fr-FR"] untuk bahasa Prancis) untuk memengaruhi pengenalan ke bahasa tertentu (lihat Bahasa yang didukung).
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(
language_codes=["es-ES"],
),
)
JavaScript
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {
languageCodes: ['es-ES'],
},
};
WebSockets
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
inputAudioTranscription: {
languageCodes: ['es-ES'],
},
},
};
websocket.send(JSON.stringify(setupMessage));
Bias kosakata kustom
Berikan daftar hingga 1.000 frasa, kata benda khusus, nama merek, atau istilah teknis dalam custom_vocabulary untuk memengaruhi pengenalan ucapan agar menggunakan terminologi tertentu (hasil terbaik biasanya dicapai dengan hingga 100 istilah).
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(
language_codes=[],
custom_vocabulary=["Gemini", "Kubernetes", "BigQuery"],
),
)
JavaScript
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {
languageCodes: [],
customVocabulary: ['Gemini', 'Kubernetes', 'BigQuery'],
},
};
WebSockets
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
inputAudioTranscription: {
languageCodes: [],
customVocabulary: ['Gemini', 'Kubernetes', 'BigQuery'],
},
},
};
websocket.send(JSON.stringify(setupMessage));
Transkripsi pintar
Konfigurasi pemformatan output transkripsi menggunakan parameter mode di input_audio_transcription:
VERBATIM(default): Menghasilkan transkrip literal yang persis dari semua yang diucapkan, dengan mempertahankan kata pengisi mentah ("um", "eh", "kayak"), pengulangan, dan permulaan yang salah.SMART(Transkripsi cerdas): Membersihkan dan menyusun transkrip agar mudah dibaca:- Penghapusan gangguan kelancaran: Menghapus kata pengisi, gagap, dan kesalahan memulai kalimat.
- Koreksi mandiri inline: Menyelesaikan koreksi lisan secara alami.
- Pemformatan terstruktur: Secara otomatis memformat daftar, poin-poin, angka, tanggal, dan jeda paragraf.
- Tata bahasa & kapitalisasi: Menerapkan kapitalisasi alami dan polesan tanda baca.
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(
mode="SMART",
),
)
JavaScript
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {
mode: 'SMART',
},
};
WebSockets
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
inputAudioTranscription: {
mode: 'SMART',
},
},
};
websocket.send(JSON.stringify(setupMessage));
Strategi Deteksi Aktivitas Suara (VAD)
VAD Otomatis (Default)
Secara default, Deteksi Aktivitas Suara otomatis sisi server mendeteksi kapan pembicara mulai dan berhenti berbicara.
VAD Hybrid
VAD Hybrid menggabungkan deteksi awal ucapan otomatis sisi server dengan deteksi akhir ucapan sisi klien untuk penyelesaian giliran dengan latensi nol:
- VAD otomatis sisi server tetap diaktifkan untuk mendeteksi awal ucapan secara akurat dengan padding audio awalan, sehingga mencegah pemotongan kata depan.
- VAD sisi klien mendeteksi keheningan: Saat VAD di perangkat lokal mendeteksi bahwa pembicara telah berhenti berbicara, klien akan segera mengirimkan sinyal
audio_stream_end. - Finalisasi cepat: Server memperlakukan
audio_stream_endsebagai perintah finalisasi langsung, melewati waktu tunggu tanpa suara sisi server default dan menampilkan transkrip yang difinalisasi dengan latensi minimal. - Penggantian: Jika VAD klien gagal dipicu, VAD sisi server akan bertindak sebagai penggantian otomatis.
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
input_audio_transcription=types.AudioTranscriptionConfig(),
)
async with client.aio.live.connect(model=model, config=config) as session:
# Stream audio chunks...
await session.send_realtime_input(
audio=types.Blob(data=chunk, mime_type="audio/pcm;rate=16000")
)
# When client-side VAD detects end of speech, send audio_stream_end:
await session.send_realtime_input(audio_stream_end=True)
JavaScript
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {},
};
// Stream audio...
session.sendRealtimeInput({
audio: { data: chunkBase64, mimeType: 'audio/pcm;rate=16000' }
});
// When client VAD detects end of speech, send audioStreamEnd:
session.sendRealtimeInput({
audioStreamEnd: true
});
WebSockets
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
inputAudioTranscription: {},
},
};
websocket.send(JSON.stringify(setupMessage));
// Stream audio...
websocket.send(JSON.stringify({
realtimeInput: {
audio: { data: chunkBase64, mimeType: 'audio/pcm;rate=16000' }
}
}));
// When client VAD detects end of speech, send audioStreamEnd:
websocket.send(JSON.stringify({
realtimeInput: {
audioStreamEnd: true
}
}));
VAD Manual (Push-to-Talk)
Untuk antarmuka walkie-talkie atau tombol tekan untuk bicara, nonaktifkan VAD otomatis sepenuhnya dan kontrol batas pergantian secara eksplisit menggunakan activity_start dan activity_end:
Python
config = types.LiveConnectConfig(
response_modalities=["TEXT"],
realtime_input_config=types.RealtimeInputConfig(
automatic_activity_detection=types.AutomaticActivityDetection(
disabled=True
)
),
input_audio_transcription=types.AudioTranscriptionConfig(),
)
async with client.aio.live.connect(model=model, config=config) as session:
# Button pressed: signal speech start
await session.send_realtime_input(activity_start=types.ActivityStart())
# Stream audio chunks...
await session.send_realtime_input(audio=types.Blob(data=chunk, mime_type="audio/pcm;rate=16000"))
# Button released: signal speech end
await session.send_realtime_input(activity_end=types.ActivityEnd())
JavaScript
const config = {
responseModalities: [Modality.TEXT],
realtimeInputConfig: {
automaticActivityDetection: {
disabled: true,
},
},
inputAudioTranscription: {},
};
// Signal speech start
session.sendRealtimeInput({ activityStart: {} });
// Stream audio...
// Signal speech end
session.sendRealtimeInput({ activityEnd: {} });
WebSockets
const setupMessage = {
setup: {
model: 'models/gemini-3.5-transcribe-live',
generationConfig: {
responseModalities: ['TEXT'],
},
realtimeInputConfig: {
automaticActivityDetection: {
disabled: true,
},
},
inputAudioTranscription: {},
},
};
websocket.send(JSON.stringify(setupMessage));
// Button pressed: signal speech start
websocket.send(JSON.stringify({
realtimeInput: {
activityStart: {},
},
}));
// Stream audio...
websocket.send(JSON.stringify({
realtimeInput: {
audio: { data: chunkBase64, mimeType: 'audio/pcm;rate=16000' },
},
}));
// Button released: signal speech end
websocket.send(JSON.stringify({
realtimeInput: {
activityEnd: {},
},
}));
Token sementara di aplikasi klien
Untuk aplikasi klien ke server (seperti aplikasi seluler atau web yang melakukan streaming langsung dari mikrofon), gunakan token sementara untuk menghindari pemaparan kunci API Anda dalam kode klien.
Buat token sementara yang dibatasi di server Anda sebelum memulai koneksi klien:
Python
import datetime
from google import genai
client = genai.Client()
expire_time = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(minutes=30)
token = client.auth_tokens.create(
config={
"uses": 1,
"expire_time": expire_time,
"live_connect_constraints": {
"model": "gemini-3.5-transcribe-live",
"config": {
"response_modalities": ["TEXT"],
"input_audio_transcription": {
"language_codes": [],
},
},
},
}
)
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-transcribe-live',
config: {
responseModalities: ['TEXT'],
inputAudioTranscription: {
languageCodes: [],
},
},
},
},
});
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/auth_tokens" \
-H "x-goog-api-key: ${GEMINI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"uses": 1,
"expireTime": "YYYY-MM-DDTHH:MM:SSZ",
"liveConnectConstraints": {
"model": "models/gemini-3.5-transcribe-live",
"config": {
"responseModalities": ["TEXT"],
"inputAudioTranscription": {
"languageCodes": []
}
}
}
}'
Bahasa yang didukung
Bahasa dan kode bahasa BCP-47 berikut didukung untuk Transcribe Live Gemini 3.5:
| Language | Kode BCP-47 | Language | Kode BCP-47 |
|---|---|---|---|
| Afrika | af-ZA |
Jepang | ja-JP |
| Amharik | am-ET |
Jawa | jv-ID |
| Arab (Mesir) | ar-EG |
Kabuverdianu | kea-CV |
| Armenia | hy-AM |
Kannada | kn-IN |
| Assam | as-IN |
Kazak | kk-KZ |
| Azerbaijan | az-AZ |
Korea | ko-KR |
| Belarusia | be-BY |
Kirgiz | ky-KG |
| Bengali (Bangladesh) | bn-BD |
Latvia | lv-LV |
| Bengali (India) | bn-IN |
Lingala | ln-CD |
| Bosnia | bs-BA |
Lituania | lt-LT |
| Bulgaria | bg-BG |
Makedonia | mk-MK |
| Bulgaria (Aromania) | rup-BG |
Melayu | ms-MY |
| Burma | my-MM |
Malayalam | ml-IN |
| Kanton (Tradisional) | yue-Hant-HK |
Malta | mt-MT |
| Katalan | ca-ES |
China Mandarin (Aksara Sederhana) | cmn-Hans-CN |
| Cebuano | ceb |
Marathi | mr-IN |
| Khmer Tengah | km-KH |
Mongolia | mn-MN |
| Kroasia | hr-HR |
Nepal | ne-NP |
| Ceko | cs-CZ |
Norwegia | nb-NO |
| Denmark | da-DK |
Oriya | or-IN |
| Belanda | nl-NL |
Polandia | pl-PL |
| Inggris (Britania Raya) | en-GB |
Portugis (Brasil) | pt-BR |
| Inggris (India) | en-IN |
Portugis (Portugal) | pt-PT |
| Inggris (Amerika Serikat) | en-US |
Punjabi | pa-IN |
| Estonia | et-EE |
Punjabi (skrip Gurmukhi) | pa-Guru-IN |
| Persia | fa-IR |
Rumania | ro-RO |
| Filipino | fil-PH |
Rusia | ru-RU |
| Finlandia | fi-FI |
Serbia | sr-RS |
| Prancis | fr-FR |
Sindhi (skrip Arab) | sd-Arab-IN |
| Galisia | gl-ES |
Slovakia | sk-SK |
| Georgia | ka-GE |
Slovenia | sl-SI |
| Jerman | de-DE |
Spanyol (Amerika Latin) | es-419 |
| Yunani | el-GR |
Spanyol (Amerika Serikat) | es-US |
| Gujarati | gu-IN |
Swahili (Kenya) | sw-KE |
| Hausa | ha-NG |
Swedia | sv-SE |
| Ibrani | he-IL |
Tajik | tg-TJ |
| Hindi | hi-IN |
Telugu | te-IN |
| Hungaria | hu-HU |
Thai | th-TH |
| Islandia | is-IS |
Turki | tr-TR |
| Inggris - India | en-IN |
Ukraina | uk-UA |
| Indonesia | id-ID |
Uzbek | uz-UZ |
| Italia | it-IT |
Vietnam | vi-VN |
Referensi parameter
Konfigurasi transkripsi instan menggunakan kolom di input_audio_transcription dan realtime_input_config:
| Parameter | Jenis | Deskripsi |
|---|---|---|
language_codes |
Array string | Kode bahasa BCP-47 (misalnya, ["en-US"]). Jika tidak ada atau kosong ([]), model akan otomatis mendeteksi bahasa dan menangani ucapan multibahasa. |
custom_vocabulary |
Array string | Hingga 1.000 istilah kustom, akronim, nama merek, atau kata benda khusus untuk memengaruhi pengenalan ucapan. |
mode |
String | Mode transkripsi: "VERBATIM" (default) atau "SMART" (Transkripsi smart). Jika disetel ke "SMART", model akan menghapus kata pengisi, memformat daftar, dan mengoreksi ketidaklancaran. |
automatic_activity_detection.disabled |
Boolean | Setel ke true untuk menonaktifkan deteksi aktivitas suara otomatis dan mengirim sinyal activityStart dan activityEnd secara manual. |
Kolom respons server
| Kolom | Deskripsi |
|---|---|
server_content.interim_input_transcription |
Hipotesis transkripsi parsial sementara dengan latensi rendah yang dipancarkan secara berkelanjutan saat pengguna sedang berbicara. |
server_content.input_transcription |
Transkrip input resmi yang telah diselesaikan dikeluarkan saat giliran ucapan selesai. |
Batasan
- Durasi sesi: Sesi transkripsi langsung mendukung streaming berkelanjutan hingga 10 menit.
- Diarisasi pembicara: Diarisasi pembicara tidak didukung dalam sesi live streaming. Untuk diarisasi pembicara, gunakan endpoint Transkripsi audio non-streaming.
- Stempel waktu tingkat kata: Stempel waktu tingkat kata tidak didukung melalui Live API. Live API memancarkan stempel waktu tingkat ucapan (
interim_input_transcriptiondaninput_transcription). - Kosakata kustom: Anda dapat memberikan hingga 1.000 istilah dalam
custom_vocabulary, tetapi hasil terbaik biasanya dicapai dengan hingga 100 istilah. - Kompatibilitas mode: Transkripsi smart (
"mode": "SMART") menghapus kata pengisi dan memformat teks yang memahami maksud, tetapi tidak dapat digabungkan dengan anotasi kata.
Langkah berikutnya
- Baca dokumentasi Gemini Transcribe untuk file audio non-streaming.
- Baca Ringkasan Live API untuk agen suara percakapan.
- Baca Panduan terjemahan langsung untuk terjemahan speech-to-speech real-time.
- Lihat halaman Harga untuk mengetahui harga streaming Live API.
- Pelajari panduan kemampuan Live API.