L'API Gemini Live supporta la trascrizione della conversione della voce in testo in tempo reale e a bassa latenza utilizzando il modello gemini-3.5-transcribe-live. Se ti connetti all'API Live tramite WebSocket o utilizzi l'SDK Google Gen AI, puoi trasmettere in streaming l'input audio continuo e ricevere trascrizioni di testo incrementali in tempo reale man mano che viene pronunciato il discorso.
Sfruttando l'API Gemini Live, piattaforme per sviluppatori come Agora, Fishjam, LiveKit, Pipecat, Vercel e Vision Agents consentono agli sviluppatori di creare e implementare interfacce vocali ad alte prestazioni con facilità. Queste piattaforme gestiscono un'infrastruttura complessa di streaming multimediale in tempo reale dietro le quinte, consentendo agli sviluppatori di concentrarsi interamente sulla creazione dell'esperienza utente.
Operatore e trascrizione in tempo reale
Sebbene entrambi utilizzino la connessione di streaming bidirezionale dell'API Live, la trascrizione in tempo reale funziona come una pipeline di riconoscimento vocale dedicata a bassa latenza anziché come un agente conversazionale.
| Funzionalità | Agente | Trascrizione Istantanea |
|---|---|---|
| Ruolo principale | Assistente conversazionale che ascolta, ragiona e risponde. | Pipeline di conversione della voce in testo in tempo reale che trascrive l'audio in entrata. |
| Modalità di risposta | Audio e testo parlati (response_modalities=["AUDIO"]). |
Trascrizioni di testo dello streaming (response_modalities=["TEXT"]). |
| Stile di interazione | Dialogo a turni con rilevamento di pause e interruzioni. | Elaborazione continua del flusso mentre l'oratore parla. |
| Funzionalità supportate | Chiamata di funzione, Ricerca Google, istruzioni di sistema. | Bias del parlato (custom_vocabulary), rilevamento della lingua, VAD manuale e ibrido, trascrizione intelligente. |
| Stream di input | Multimodale: audio, video, immagini, testo. | Input audio (PCM a 16 bit non elaborato). |
Inizia
I seguenti esempi mostrano come aprire una sessione di streaming bidirezionale con gemini-3.5-transcribe-live e ricevere trascrizioni in tempo reale.
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);
}
};
Trascrizioni provvisorie e definitive
Man mano che gli stream audio vengono inseriti nell'API Live, il server emette due campi di trascrizione complementari all'interno di server_content:
interim_input_transcription: ipotesi parziali speculative a bassa latenza aggiornate mentre l'oratore parla attivamente. Questi aggiornamenti parziali vengono eseguiti rapidamente con un ritardo minimo. Utilizzainterim_input_transcriptionper visualizzare in anteprima i sottotitoli codificati o i sottotitoli codificati in tempo reale reattivi dell'interfaccia utente.input_transcription: la trascrizione finalizzata emessa quando l'oratore si ferma, il turno termina o il discorso viene finalizzato. Una volta emesso, questo testo rappresenta la trascrizione autorevole del modello del segmento vocale. In modalità di trascrizione intelligente, verrà inclusa la risposta pulita e formattata.
L'esempio seguente mostra come visualizzare i risultati parziali intermedi dello streaming e inviare le trascrizioni finali:
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);
}
};
Invio di audio
Trasmetti in streaming blocchi audio tramite la connessione attiva come audio PCM a 16 bit non elaborato.
- Formato audio:PCM a 16 bit non elaborato a 16 kHz (mono, little-endian).
- Dimensioni chunk:invia l'audio in chunk di 100 ms (da 1024 a 2048 frame).
Tipo MIME:
audio/pcm;rate=16000(o la frequenza di campionamento corrispondente).
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
}
}));
Funzionalità di trascrizione
Rilevamento automatico della lingua
Per impostazione predefinita, l'omissione di language_codes o l'impostazione di language_codes=[] attiva l'identificazione automatica della lingua. Il modello rileva dinamicamente la lingua parlata in tutte le espressioni, incluse le conversazioni multilingue e il cambio di codice.
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));
Suggerimento per una lingua specifica
Fornisci codici lingua BCP-47 espliciti (ad esempio, ["es-ES"] per lo spagnolo o ["fr-FR"] per il francese) per orientare il riconoscimento verso lingue specifiche (vedi Lingue supportate).
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 del vocabolario personalizzato
Fornisci un elenco di massimo 1000 frasi, nomi propri, nomi di brand o termini tecnici in custom_vocabulary per orientare il riconoscimento vocale verso una terminologia specifica (i risultati migliori si ottengono in genere con un massimo di 100 termini).
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));
Trascrizione intelligente
Configura la formattazione dell'output della trascrizione utilizzando il parametro mode in input_audio_transcription:
VERBATIM(impostazione predefinita): produce una trascrizione letterale esatta di tutto ciò che viene detto, conservando le parole di riempimento grezze ("um", "uh", "tipo"), le ripetizioni e le false partenze.SMART(Trascrizione intelligente): pulisce e struttura la trascrizione per renderla più leggibile:- Rimozione delle disfluenze: rimuove gli intercalari, le balbuzie e gli avvii errati.
- Correzioni automatiche in linea: risolve le correzioni vocali in modo naturale.
- Formattazione strutturata: formatta automaticamente elenchi, punti elenco, numeri, date e interruzioni di paragrafo.
- Grammatica e maiuscole: applica la punteggiatura e le maiuscole naturali.
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));
Strategie di rilevamento di attività vocale (VAD)
Rilevamento automatico dell'attività vocale (impostazione predefinita)
Per impostazione predefinita, il rilevamento automatico dell'attività vocale lato server rileva quando un oratore inizia e smette di parlare.
VAD ibrido
VAD ibrido combina il rilevamento automatico dell'inizio del discorso lato server con il rilevamento della fine del discorso lato client per la finalizzazione del turno a latenza zero:
- Il rilevamento automatico dell'attività vocale lato server rimane attivo per rilevare con precisione l'inizio del parlato con il padding audio del prefisso, evitando il troncamento delle parole iniziali.
- Rilevamento dell'attività vocale lato client rileva il silenzio: quando il rilevamento dell'attività vocale locale sul dispositivo rileva che l'oratore ha smesso di parlare, il client invia immediatamente un segnale
audio_stream_end. - Finalizzazione rapida: il server considera
audio_stream_endcome un prompt di finalizzazione immediata, ignorando il tempo di attesa predefinito del silenzio lato server e restituendo la trascrizione finalizzata con una latenza minima. - Fallback: se la VAD lato client non viene attivata, la VAD lato server funge da fallback automatico.
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 manuale (premi per parlare)
Per le interfacce walkie-talkie o i pulsanti push-to-talk, disattiva completamente il VAD automatico e controlla i limiti di turno in modo esplicito utilizzando activity_start e 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 effimeri nelle applicazioni client
Per le applicazioni client-server (come le app web o mobile che trasmettono in streaming direttamente da un microfono), utilizza i token effimeri per evitare di esporre la chiave API nel codice client.
Crea un token effimero vincolato sul server prima di avviare la connessione client:
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": []
}
}
}
}'
Lingue supportate
Le seguenti lingue e i seguenti codici lingua BCP-47 sono supportati per Gemini 3.5 Transcribe Live:
| Lingua | Codice BCP-47 | Lingua | Codice BCP-47 |
|---|---|---|---|
| Afrikaans | af-ZA |
Giapponese | ja-JP |
| Amarico | am-ET |
Giavanese | jv-ID |
| Arabo (Egitto) | ar-EG |
Kabuverdianu | kea-CV |
| Armeno | hy-AM |
Kannada | kn-IN |
| Assamese | as-IN |
Kazako | kk-KZ |
| Azero | az-AZ |
Coreano | ko-KR |
| Bielorusso | be-BY |
Kirgizo | ky-KG |
| Bengalese (Bangladesh) | bn-BD |
Lettone | lv-LV |
| Bengalese (India) | bn-IN |
Lingala | ln-CD |
| Bosniaco | bs-BA |
Lituano | lt-LT |
| Bulgaro | bg-BG |
Macedone | mk-MK |
| Bulgaro (aromeno) | rup-BG |
Malese | ms-MY |
| Birmano | my-MM |
Malayalam | ml-IN |
| Cantonese (tradizionale) | yue-Hant-HK |
Maltese | mt-MT |
| Catalano | ca-ES |
Cinese mandarino (semplificato) | cmn-Hans-CN |
| Cebuano | ceb |
Marathi | mr-IN |
| Khmer centrale | km-KH |
Mongolo | mn-MN |
| Croato | hr-HR |
Nepalese | ne-NP |
| Ceco | cs-CZ |
Norvegese | nb-NO |
| Danese | da-DK |
Oriya | or-IN |
| Olandese | nl-NL |
Polacco | pl-PL |
| Inglese (Gran Bretagna) | en-GB |
Portoghese (Brasile) | pt-BR |
| Inglese (India) | en-IN |
Portoghese (Portogallo) | pt-PT |
| Inglese (Stati Uniti) | en-US |
Punjabi | pa-IN |
| Estone | et-EE |
Punjabi (Gurmukhi script) | pa-Guru-IN |
| Farsi | fa-IR |
Rumeno | ro-RO |
| Filippino | fil-PH |
Russo | ru-RU |
| Finlandese | fi-FI |
Serbo | sr-RS |
| Francese | fr-FR |
Sindhi (alfabeto arabo) | sd-Arab-IN |
| Galiziano | gl-ES |
Slovacco | sk-SK |
| Georgiano | ka-GE |
Sloveno | sl-SI |
| Tedesco | de-DE |
Spagnolo (America Latina) | es-419 |
| Greek | el-GR |
Spagnolo (Stati Uniti) | es-US |
| Gujarati | gu-IN |
Swahili (Kenya) | sw-KE |
| Hausa | ha-NG |
Svedese | sv-SE |
| Ebraico | he-IL |
Tagico | tg-TJ |
| Hindi | hi-IN |
Telugu | te-IN |
| Ungherese | hu-HU |
Thailandese | th-TH |
| Islandese | is-IS |
Turco | tr-TR |
| Inglese indiano | en-IN |
Ucraino | uk-UA |
| Indonesiano | id-ID |
Uzbeco | uz-UZ |
| Italiano | it-IT |
Vietnamita | vi-VN |
Riferimento ai parametri
Configura la trascrizione in tempo reale utilizzando i campi in input_audio_transcription e realtime_input_config:
| Parametro | Tipo | Descrizione |
|---|---|---|
language_codes |
Array di stringhe | Codici lingua BCP-47 (ad es. ["en-US"]). Se omesso o vuoto ([]), il modello rileva automaticamente la lingua e gestisce la voce multilingue. |
custom_vocabulary |
Array di stringhe | Fino a 1000 termini personalizzati, acronimi, nomi di brand o nomi propri per orientare il riconoscimento vocale. |
mode |
Stringa | Modalità di trascrizione: "VERBATIM" (predefinita) o "SMART" (Trascrizione intelligente). Se impostato su "SMART", il modello rimuove gli intercalari, formatta gli elenchi e corregge le disfluenze. |
automatic_activity_detection.disabled |
Booleano | Imposta su true per disattivare il rilevamento di attività vocale automatico e inviare manualmente i segnali activityStart e activityEnd. |
Campi di risposta del server
| Campo | Descrizione |
|---|---|
server_content.interim_input_transcription |
Ipotesi di trascrizione parziale provvisoria a bassa latenza emessa continuamente mentre l'utente parla. |
server_content.input_transcription |
Trascrizione autorevole e finalizzata emessa al termine di un turno di parola. |
Limitazioni
- Durata della sessione:le sessioni di trascrizione in tempo reale supportano lo streaming continuo fino a 10 minuti.
- Diarizzazione degli oratori:la diarizzazione degli oratori non è supportata nelle sessioni di live streaming. Per la diarizzazione degli oratori, utilizza l'endpoint Trascrizione audio non in streaming.
- Timestamp a livello di parola:i timestamp a livello di parola non sono supportati tramite l'API Live. L'API Live emette timestamp a livello di enunciato (
interim_input_transcriptioneinput_transcription). - Vocabolario personalizzato:puoi fornire fino a 1000 termini in
custom_vocabulary, ma in genere i risultati migliori si ottengono con un massimo di 100 termini. - Compatibilità delle modalità:la trascrizione intelligente (
"mode": "SMART") rimuove le parole di riempimento e formatta il testo in base all'intent, ma non può essere combinata con le annotazioni delle parole.
Passaggi successivi
- Leggi la documentazione di Gemini Transcribe per i file audio non in streaming.
- Leggi la panoramica dell'API Live per gli agenti vocali conversazionali.
- Leggi la guida alla traduzione live per la traduzione vocale in tempo reale.
- Consulta la pagina dei prezzi per i prezzi dello streaming dell'API Live.
- Esplora la guida alle funzionalità dell'API Live.