Tradução em tempo real de áudio e vídeo
Qwen Discurso em tempo real e tradução audiovisual com latência de 2,3 segundos
Detalhes do modelo.
O qwen3.8-livetranslate-flash-realtime e qwen3.5-livetranslate-flash-realtime Modelos são modelos de tradução em tempo real com maior visão, suportando 60 idiomas (29 com áudio + texto, 31 apenas texto). Eles processam entrada de áudio e imagem de fluxos de vídeo ou arquivos locais, usam o contexto visual para melhorar a precisão, e saída de texto traduzido e áudio em tempo real.
Principais características:
- ** Suporte multi-língua**: Traduz entre 60 idiomas - 29 com áudio e texto, 31 com texto apenas de saída - incluindo chinês, Inglês, Francês, Alemão, Russo, Japonês, Coreano, Espanhol, Português e Árabe.
- Analisa pistas visuais, como movimentos labiais, gestos e texto na tela, para melhorar a precisão da tradução, especialmente em ambientes barulhentos ou para palavras ambíguas.
- Dá interpretação simultânea com latência tão baixa quanto 2,3 segundos.
- Distingue diferentes falantes e seu discurso quando várias pessoas se revezam em falar, então os ouvintes podem entender claramente quem disse o quê.
- Preveem unidades semânticas para resolver diferenças entre palavras, alcançando qualidade comparável à tradução offline.
- Combina automaticamente com a entonação e emoção do áudio de origem.
- As palavras-chave configuráveis melhoram a precisão da tradução para termos específicos.
- Clones a voz do alto-falante para a saída traduzida. Suporta clonagem em tempo real e perfis de voz pré-clonados.
Além do WebSocket, qwen3.5-livetranslate-flash-realtime Também suporta os protocolos de QAO e WebRTC. Para integração cliente-side que prioriza latência estável, resiliência em redes fracas, e integração de ruído e cancelamento de eco, o AOQ é recomendado. Para uma comparação de protocolo, veja [Realtime API overview] (/api-reference/realtime-api/overview).
Modelos recomendados
| Modelo | Versão | Janela de contexto | Max input | Saída máxima |
|---|---|---|---|---|
| qwen3.8-livetranslate-flash-realtime | Estável. | 53,248 | 49,152 | 4,096 |
| qwen3.5-livetranslate-flash-realtime(Alias para qwen3.5-livetranslate-flash-realtime-2026-05-19) | Estável. | 53,248 | 49,152 | 4,096 |
| qwen3.5-livetranslate-flash-realtime-2026-05-19 | Deslize | 53,248 | 49,152 | 4,096 |
Começando.
Prepare o ambiente.
Requer Python 3.10 ou posterior.
Primeiro, instale o piano.
macOS
```bash
brew install portaudio && pip install pyaudio
```
Debian/Ubuntu
```bash
sudo apt-get install python3-pyaudio
# or
pip install pyaudio
```
CentOS
```bash
sudo yum install -y portaudio portaudio-devel && pip install pyaudio
```
Windows
```powershell
pip install pyaudio
```
Então instale as dependências do WebSocket:
pip install websocket-client==1.8.0 websockets
Crie o cliente.
Crie um arquivo chamado livetranslate_client.py com o seguinte código:
Client code - livetranslate_client.py
import os
import time
import base64
import asyncio
import json
import websockets
import pyaudio
import queue
import threading
import traceback
class LiveTranslateClient:
def __init__(self, api_key: str, target_language: str = "en", *, audio_enabled: bool = True):
if not api_key:
raise ValueError("API key cannot be empty.")
self.api_key = api_key
self.target_language = target_language
self.audio_enabled = audio_enabled
self.ws = None
self.api_url = "wss://maas.qwencloudapi.com/api-ws/v1/realtime?model=qwen3.5-livetranslate-flash-realtime"
# Audio input configuration (from microphone)
self.input_rate = 16000
self.input_chunk = 1600
self.input_format = pyaudio.paInt16
self.input_channels = 1
# Audio output configuration (for playback)
self.output_rate = 24000
self.output_chunk = 2400
self.output_format = pyaudio.paInt16
self.output_channels = 1
# State management
self.is_connected = False
self.audio_player_thread = None
self.audio_playback_queue = queue.Queue()
self.pyaudio_instance = pyaudio.PyAudio()
self.session_finished_event = asyncio.Event()
async def connect(self):
"""Establish a WebSocket connection to the translation service."""
headers = {"Authorization": f"Bearer {self.api_key}"}
try:
self.ws = await websockets.connect(self.api_url, additional_headers=headers)
self.is_connected = True
print(f"Successfully connected to the server: {self.api_url}")
await self.configure_session()
except Exception as e:
print(f"Connection failed: {e}")
self.is_connected = False
raise
async def configure_session(self):
"""Configure the translation session, setting the target language, voice, etc."""
config = {
"event_id": f"event_{int(time.time() * 1000)}",
"type": "session.update",
"session": {
# 'modalities' controls the output type.
# ["text", "audio"]: Returns both translated text and synthesized audio (recommended).
# ["text"]: Returns only the translated text.
"modalities": ["text", "audio"] if self.audio_enabled else ["text"],
"input_audio_format": "pcm",
"output_audio_format": "pcm",
# 'input_audio_transcription' configures source language recognition.
# Set 'model' to 'qwen3-asr-flash-realtime' to also output the source language recognition result.
# "input_audio_transcription": {
# "model": "qwen3-asr-flash-realtime",
# "language": "zh" # source language, default 'en'
# },
"translation": {
"language": self.target_language,
# 'corpus' configures hotwords to improve the translation accuracy of specific terms.
# "corpus": {
# "phrases": {
# "Artificial Intelligence": "Artificial Intelligence",
# "Machine Learning": "Machine Learning"
# }
# }
}
}
}
print(f"Sending session configuration: {json.dumps(config, indent=2, ensure_ascii=False)}")
await self.ws.send(json.dumps(config))
async def send_audio_chunk(self, audio_data: bytes):
"""Encode and send an audio chunk to the server."""
if not self.is_connected:
return
event = {
"event_id": f"event_{int(time.time() * 1000)}",
"type": "input_audio_buffer.append",
"audio": base64.b64encode(audio_data).decode()
}
await self.ws.send(json.dumps(event))
async def send_image_frame(self, image_bytes: bytes, *, event_id: str | None = None):
# Send an image frame to the server.
if not self.is_connected:
return
if not image_bytes:
raise ValueError("image_bytes cannot be empty.")
# Encode to Base64
image_b64 = base64.b64encode(image_bytes).decode()
event = {
"event_id": event_id or f"event_{int(time.time() * 1000)}",
"type": "input_image_buffer.append",
"image": image_b64,
}
await self.ws.send(json.dumps(event))
def _audio_player_task(self):
stream = self.pyaudio_instance.open(
format=self.output_format,
channels=self.output_channels,
rate=self.output_rate,
output=True,
frames_per_buffer=self.output_chunk,
)
try:
while self.is_connected or not self.audio_playback_queue.empty():
try:
audio_chunk = self.audio_playback_queue.get(timeout=0.1)
if audio_chunk is None: # Termination signal
break
stream.write(audio_chunk)
self.audio_playback_queue.task_done()
except queue.Empty:
continue
finally:
stream.stop_stream()
stream.close()
def start_audio_player(self):
"""Start the audio player thread (only when audio output is enabled)."""
if not self.audio_enabled:
return
if self.audio_player_thread is None or not self.audio_player_thread.is_alive():
self.audio_player_thread = threading.Thread(target=self._audio_player_task, daemon=True)
self.audio_player_thread.start()
async def handle_server_messages(self, on_text_received):
"""Handle incoming messages from the server in a loop."""
try:
async for message in self.ws:
event = json.loads(message)
event_type = event.get("type")
if event_type == "response.audio.delta" and self.audio_enabled:
audio_b64 = event.get("delta", "")
if audio_b64:
audio_data = base64.b64decode(audio_b64)
self.audio_playback_queue.put(audio_data)
elif event_type == "response.done":
print("\n[INFO] Response round complete.")
usage = event.get("response", {}).get("usage", {})
if usage:
print(f"[INFO] token usage: {json.dumps(usage, indent=2, ensure_ascii=False)}")
elif event_type == "session.finished":
print("[INFO] Session finished.")
self.session_finished_event.set()
# Process source language recognition results (requires enabling input_audio_transcription.model)
# elif event_type == "conversation.item.input_audio_transcription.text":
# stash = event.get("stash", "") # Pending recognition text
# print(f"[Recognizing] {stash}")
# elif event_type == "conversation.item.input_audio_transcription.completed":
# transcript = event.get("transcript", "") # Complete recognition result
# print(f"[Source language] {transcript}")
elif event_type == "response.text.text":
# Streaming translated text in text-only modality
text = event.get("text", "")
stash = event.get("stash", "")
print(f"\r[Translating] {text}{stash}", end="", flush=True)
elif event_type == "response.audio_transcript.done":
print("\n[INFO] Translation complete.")
text = event.get("transcript", "")
if text:
print(f"[INFO] Translated text: {text}")
elif event_type == "response.text.done":
print("\n[INFO] Translation complete.")
text = event.get("text", "")
if text:
print(f"[INFO] Translated text: {text}")
except websockets.exceptions.ConnectionClosed as e:
print(f"[WARNING] Connection closed: {e}")
self.is_connected = False
except Exception as e:
print(f"[ERROR] An unexpected error occurred while processing messages: {e}")
traceback.print_exc()
self.is_connected = False
async def start_microphone_streaming(self):
"""Capture audio from the microphone and stream it to the server."""
stream = self.pyaudio_instance.open(
format=self.input_format,
channels=self.input_channels,
rate=self.input_rate,
input=True,
frames_per_buffer=self.input_chunk
)
print("Microphone is on. Start speaking...")
try:
while self.is_connected:
audio_chunk = await asyncio.get_event_loop().run_in_executor(
None, stream.read, self.input_chunk
)
await self.send_audio_chunk(audio_chunk)
finally:
stream.stop_stream()
stream.close()
async def close(self):
"""Gracefully close the connection and release resources."""
if self.is_connected and self.ws:
finish_event = {
"event_id": f"event_{int(time.time() * 1000)}",
"type": "session.finish",
}
await self.ws.send(json.dumps(finish_event))
print("Sent session.finish, waiting for server to finish processing...")
try:
await asyncio.wait_for(self.session_finished_event.wait(), timeout=15)
print("Server processing complete.")
except asyncio.TimeoutError:
print("Timed out waiting for session.finished.")
self.is_connected = False
if self.ws:
await self.ws.close()
print("WebSocket connection closed.")
if self.audio_player_thread:
self.audio_playback_queue.put(None) # Send termination signal
self.audio_player_thread.join(timeout=1)
print("Audio player thread stopped.")
self.pyaudio_instance.terminate()
print("PyAudio instance released.")
Interaja com o modelo.
No mesmo diretório, crie um arquivo chamado main.py com o seguinte código:
main.py
import os
import asyncio
from livetranslate_client import LiveTranslateClient
def print_banner():
print("=" * 60)
print(" Powered by Qwen qwen3.5-livetranslate-flash-realtime")
print("=" * 60 + "\n")
def get_user_config():
"""Get user configuration."""
print("Select a mode:")
print("1. Voice + Text [Default] | 2. Text Only")
mode_choice = input("Enter your choice (press Enter for Voice + Text): ").strip()
audio_enabled = (mode_choice != "2")
if audio_enabled:
lang_map = {
"1": "en", "2": "zh", "3": "ru", "4": "fr", "5": "de", "6": "pt",
"7": "es", "8": "it", "9": "ko", "10": "ja"
}
print("Select the target language (Voice + Text mode):")
print("1. English | 2. Chinese | 3. Russian | 4. French | 5. German | 6. Portuguese | 7. Spanish | 8. Italian | 9. Korean | 10. Japanese")
else:
lang_map = {
"1": "en", "2": "zh", "3": "ru", "4": "fr", "5": "de", "6": "pt", "7": "es", "8": "it",
"9": "id", "10": "ko", "11": "ja", "12": "vi", "13": "th", "14": "ar",
"15": "yue", "16": "hi", "17": "el", "18": "tr"
}
print("Select the target language (Text Only mode):")
print("1. English | 2. Chinese | 3. Russian | 4. French | 5. German | 6. Portuguese | 7. Spanish | 8. Italian | 9. Indonesian | 10. Korean | 11. Japanese | 12. Vietnamese | 13. Thai | 14. Arabic | 15. Cantonese | 16. Hindi | 17. Greek | 18. Turkish")
choice = input("Enter your choice (defaults to the first option): ").strip()
target_language = lang_map.get(choice, next(iter(lang_map.values())))
return target_language, audio_enabled
async def main():
"""Main program entry point."""
print_banner()
api_key = os.environ.get("DASHSCOPE_API_KEY")
if not api_key:
print("[ERROR] Please set the DASHSCOPE_API_KEY environment variable.")
print(" For example: export DASHSCOPE_API_KEY='your_api_key_here'")
return
target_language, audio_enabled = get_user_config()
print("\nConfiguration complete:")
print(f" - Target language: {target_language}")
if not audio_enabled:
print(" - Output mode: Text Only")
client = LiveTranslateClient(api_key=api_key, target_language=target_language, audio_enabled=audio_enabled)
# Define the callback function.
def on_translation_text(text):
print(text, end="", flush=True)
try:
print("Connecting to the translation service...")
await client.connect()
# Start audio playback based on the mode.
client.start_audio_player()
print("\n" + "-" * 60)
print("Connection successful! Speak into the microphone.")
print("The program will translate your speech in real time and play the translated audio. Press Ctrl+C to exit.")
print("-" * 60 + "\n")
# Run message handling and microphone recording concurrently.
message_handler = asyncio.create_task(client.handle_server_messages(on_translation_text))
tasks = [message_handler]
# Capture audio from the microphone for translation, regardless of whether audio output is enabled.
microphone_streamer = asyncio.create_task(client.start_microphone_streaming())
tasks.append(microphone_streamer)
await asyncio.gather(*tasks)
except KeyboardInterrupt:
print("\n\nUser interrupted. Exiting...")
except Exception as e:
print(f"\nA critical error occurred: {e}")
finally:
print("\nCleaning up resources...")
await client.close()
print("Program exited.")
if __name__ == "__main__":
asyncio.run(main())
Corra. main.py e fale no seu microfone. O modelo traduz áudio e texto em tempo real. O sistema detecta automaticamente a fala e envia para o servidor.
Como usar
1. Configura a conexão.
O qwen3.5-livetranslate-flash-realtime O modelo usa o protocolo WebSocket. A conexão requer os seguintes parâmetros:
| Parâmetro | Descrição |
|---|---|
| Endpoint | wss://maas.qwencloudapi.com/api-ws/v1/realtime |
| parâmetro de consulta | OmodelO parâmetro de consulta deve ser definido como o nome do modelo. Exemplo:?model=qwen3.5-livetranslate-flash-realtime |
| cabeçalho da mensagem | Use um Token para autenticação:Authorization: Bearer DASHSCOPE_API_KEY |
DASHSCOPE APIKY é sua chave de API QwenCloud.
Exemplo de código Python para estabelecer uma conexão:
Código de exemplo Python para conexão WebSocket
# pip install websocket-client
import json
import websocket
import os
API_KEY=os.getenv("DASHSCOPE_API_KEY")
API_URL = "wss://maas.qwencloudapi.com/api-ws/v1/realtime?model=qwen3.5-livetranslate-flash-realtime"
headers = [
"Authorization: Bearer " + API_KEY
]
def on_open(ws):
print(f"Connected to server: {API_URL}")
def on_message(ws, message):
data = json.loads(message)
print("Received event:", json.dumps(data, indent=2))
def on_error(ws, error):
print("Error:", error)
ws = websocket.WebSocketApp(
API_URL,
header=headers,
on_open=on_open,
on_message=on_message,
on_error=on_error
)
ws.run_forever()
- Dois. Configura linguagem, modalidade e voz
qwen3.8-livetranslate-flash-realtime
Configure a sessão através de [sessão.atualização] (/api-reference/speech-translation/livetranslate-realtime/client-events#session-update):
- ** Língua de alvo **: definido `session.translation.language`, como `en` Para inglês.
- **Modalidades de saída**: `session.output_modalities` para `["text"]` Só para texto ou `["text", "audio"]` Para texto e áudio.
- Tradução: `conversation.item.input_audio_transcription.delta` e transcrições completas através de `conversation.item.input_audio_transcription.completed`.
- Os padrões são 16000 Hz entrada PCM, 24000 Hz saída PCM e voz `Tina`. Veja [Eventos de servidor] (/api-reference/speech-translation/livetranslate-realtime/server-events#session-created) para a estrutura da sessão.
qwen3.5-livetranslate-flash-realtime
Envie a [sessão.atualização] (/api-reference/speech-translation/livetranslate-realtime/client-events#session-update) evento cliente com os seguintes parâmetros:
- #Língua#
- ** Linguagem de origem:** Configurar usando o `session.input_audio_transcription.language` parâmetro.
Se não especificado, o modelo detecta automaticamente a linguagem de origem.
- **Língua de alvo:** Configurar usando o `session.translation.language` parâmetro.
O valor padrão é en (Inglês).
Veja [línguas suportadas] (#supported-languages).
- ** Resultado do reconhecimento de linguagem de saída
Para ativar esta característica, defina o `session.input_audio_transcription.model` parâmetro. Quando está pronto para `qwen3-asr-flash-realtime`, o servidor retorna tanto a tradução quanto o resultado do reconhecimento de fala (texto original) para o áudio de entrada.
Quando esta funcionalidade está ativa, o servidor retorna os seguintes eventos:
- `conversation.item.input_audio_transcription.text`Transmite os resultados do reconhecimento.
- `conversation.item.input_audio_transcription.completed` Retorna o resultado final após o reconhecimento estar completo.
- `conversation.item.input_audio_transcription.failed` Devolve informações de erro quando o reconhecimento falha.
- ? modalidade de saída ?
Defina o `session.modalities` parâmetro para `["text"]` (apenas texto) ou `["text","audio"]` (texto e áudio).
- Detecção de Atividade Vocal (VAD) e Modo Manual
Configure como os limites de fala são detectados usando o `session.turn_detection` parâmetro:
- Modo VAD, definido. `turn_detection` para um objeto de configuração. O servidor detecta automaticamente limites de fala e desencadeia a tradução, adequado para cenários onde o cliente envia continuamente fluxos de áudio.
- ** Modo manual**: definido `turn_detection` para `null`. O cliente determina limites de fala e envia um `input_audio_buffer.commit` evento para enviar o áudio após cada enunciação, adequado para cenários de push-to-talk.
Para os passos de interação completa sob ambos os modos, veja [3. Entrada de áudio e imagens (#3-input-audio-and-images).
- Voz
- Configure usando o `session.voice` parâmetro. Veja [Vozes Suportadas] (#supported-voices).
- # Palavra quente #
Configure palavras quentes usando o `session.translation.corpus.phrases` parâmetro. Palavras-chave são pares de valor chave que mapeiam termos de origem para as traduções de alvos, melhorando a precisão para termos específicos. Recomendamos que configure não mais que 1000 palavras quentes.
Exemplo: Mapa `"artificial intelligence"` para `"Artificial Intelligence"`.
- Clonagem de voz
- Configure usando o `session.enable_voice_clone`, `session.voice_clone_options.frequency`, e `session.voice` Parâmetros. Suporta três modos: perfil de voz pré-clonado (`frequency`: `never`O clone do lado do servidor começa uma vez na sessão.`once` Ou clone em tempo real antes de cada resposta.`always`). Veja [clonografia de voz] (#voice-cloning).
3. Áudio de entrada e imagens
Envie dados de áudio e imagem codificados pela base 64 usando o input_audio_buffer.append eventos. Entrada de áudio é necessária, entrada de imagem é opcional.
As imagens podem ser de um arquivo local ou capturadas em tempo real de um fluxo de vídeo.
Por qwen3.8-livetranslate-flash-realtime, a configuração padrão de detecção de turnos é audio.input.turn_detection.type = speaker_detectionEnviar áudio continuamente e receber respostas geradas pelo servidor. As configurações do VAD e Manual abaixo se aplicam a qwen3.5-livetranslate-flash-realtime.
Como o modelo determina que uma expressão é completa depende do modo VAD ou modo Manual configurado através do objeto turn_detection em eventos de clientes:
- O cliente envia continuamente [input_audio_buffer.append] (/api-reference/speech-translation/livetranslate-realtime/client-events#input-audio-buffer-append) eventos. Quando o servidor detecta o início/fim da fala, ele retorna.
input_audio_buffer.speech_startedeinput_audio_buffer.speech_stoppedeventos, respectivamente, automaticamente, comprime o buffer de áudio, e desencadeia a tradução. Respostas de tradução são geradas sincronicamente com o áudio de streaming e normalmente começam durante a entrada de áudio, sem esperar o discurso terminar. - ** Modo manual**: definido
session.turn_detectionparanull. Depois que o cliente terminar de enviar uma declaração completa, ele envia um [input_audio_buffer.commit] (/api-reference/speech-translation/livetranslate-realtime/client-events#input-audio-buffer-commit) evento para comprometer o buffer de áudio. Depois que o servidor retornar uminput_audio_buffer.committedO evento para confirmar, automaticamente começa a gerar a resposta da tradução, o cliente não precisa enviar nenhum outro evento para desencadear a resposta. Para limpar áudio não comprometido antes de commit, envie um [input_audio_buffer.clear] (/api-reference/speech-translation/livetranslate-realtime/client-events#input-audio-buffer-clear) evento.
- Quatro. Receba a resposta do modelo.
qwen3.8-livetranslate-flash-realtime
Lidar com as respostas de acordo com as modalidades de saída:
- Apenas texto, concatene o `delta` Os valores de `response.text.delta` para obter a tradução.
- ** Texto e áudio ** Concatenar `delta` De `response.audio_transcript.delta` Para texto, e base64-decodificação `delta` De `response.audio.delta` para obter pedaços de áudio.
`response.done` indica o fim de uma resposta. Veja [Eventos de servidor] (/api-reference/speech-translation/livetranslate-realtime/server-events#response-text-delta) para campos de eventos.
qwen3.5-livetranslate-flash-realtime
Respostas de tradução são geradas sincronicamente com o áudio de streaming e normalmente não requerem esperar o fim da fala (veja a descrição do modo VAD/Manual na seção anterior). O formato de resposta depende da modalidade de saída.
- ** Saída somente de texto **
O servidor transmite texto traduzido incremental (incluindo texto confirmado e texto previsto tentado) através de [resposta.texto.texto] (/api-reference/speech-translation/livetranslate-realtime/server-events#response-text-text Quando o texto é traduzido, é devolvido em uma resposta./api-reference/speech-translation/livetranslate-realtime/server-events#response-text-done) evento.
- Texto e saída de áudio
- O servidor transmite texto traduzido incremental através de [resposta.audio\_transcript.text] (/api-reference/speech-translation/livetranslate-realtime/server-events#response-audio-transcript-text Depois de concluída, o texto traduzido é devolvido em um.../api-reference/speech-translation/livetranslate-realtime/server-events#response-audio-transcript-done) evento.
- Os dados de áudio codificados pela Base 64 são devolvidos em [resposta.audio.delta]/api-reference/speech-translation/livetranslate-realtime/server-events#response-audio-delta) eventos.
`qwen3.5-livetranslate-flash-realtime` usa o `response.text.text` evento para entrega incremental de texto, que difere do `response.text.delta` Evento usado por modelos Omni (conversa de voz duplex). Estes eventos têm diferentes estruturas de campo e semânticas - não os usam de forma intercambiável.
- Cinco. Termine a sessão.
Depois de enviar todo o áudio, envie um [session.finish] (/api-reference/speech-translation/livetranslate-realtime/client-events#session-finish) evento, em seguida, esperar o servidor para retornar um session.finished evento antes de fechar a conexão WebSocket.
Se você fechar o WebSocket sem enviar session.finishO DAV do servidor não pode detectar o final do segmento final de fala. Isso faz com que os resultados da tradução para esse segmento se percam completamente, e a conexão pode ser suspensa indefinidamente. Sempre mande este evento antes de desconectar.
Clonagem de voz
O modelo clona a voz do alto-falante do áudio de entrada e usa a voz clonada para a saída traduzida, então a tradução soa como o alto-falante entregando em outra língua. Use um perfil de voz pré-clonado, ou deixe o servidor clonar a voz em tempo real. Isso é útil em cenários onde preservar a voz do orador importa, como interpretação de conferência, transmissão ao vivo, e dublagem de vídeo.
Defina os seguintes parâmetros em [sessão.atualização] (/api-reference/speech-translation/livetranslate-realtime/client-events#session-update) para permitir a clonagem de voz:
session.enable_voice_clone- Pronto paratruepara permitir a clonagem de voz.session.voice_clone_options.frequencyControla quando a clonagem de voz ocorre. Valores aceitos:neverNão clona no servidor. Usa um perfil de voz pré-clonado. Preparar.session.voicepara sua identificação personalizada clonada.onceClones a voz do áudio de entrada uma vez no início da sessão, em seguida, reutiliza-o para toda a saída subsequente. Melhor para cenários de um único falante. Preparar.session.voiceparadefault.alwaysClones a voz antes de cada resposta, dinamicamente adaptando-se às mudanças de falante. Melhor para conversas multi-falantes. Preparar.session.voiceparadefault.
session.voiceEspecifica a voz de saída. O valor depende dofrequencySetting:-
- Pronto para...
default- Use comfrequency- Pronto para...onceOualways. O servidor clona a voz do alto-falante do áudio de entrada. Uma voz padrão é usada até a clonagem terminar.
- Pronto para...
- Configure uma identificação de voz clonada personalizada (por exemplo,
qwen-translate-vc-xxx-yyy-zzzUse comfrequency- Pronto para...never. Você deve preparar a voz com antecedência usando a API de clonagem de voz comtargetModelDefina o modelo de tradução que você usa.
-
Quando frequency Está pronto para once Ou always, o voice O parâmetro deve ser definido como default. Qualquer outro valor faz o servidor retornar um erro.
Exemplos de configuração de clonagem de voz
Perfil de voz pré-clonado (qualidade consistente; recomendado quando uma identidade vocal estável é necessária):
{
"type": "session.update",
"session": {
"modalities": ["text","audio"],
"voice": "qwen-translate-vc-xxx-yyy-zzz",
"translation": {
"language": "en"
},
"enable_voice_clone": true,
"voice_clone_options": {
"frequency": "never"
}
}
}
Clonagem do lado do servidor, uma vez por sessão.
{
"type": "session.update",
"session": {
"modalities": ["text","audio"],
"voice": "default",
"translation": {
"language": "en"
},
"enable_voice_clone": true,
"voice_clone_options": {
"frequency": "once"
}
}
}
Clonagem do lado do servidor, todas as respostas.
{
"type": "session.update",
"session": {
"modalities": ["text","audio"],
"voice": "default",
"translation": {
"language": "en"
},
"enable_voice_clone": true,
"voice_clone_options": {
"frequency": "always"
}
}
}
Fluxo de interação
qwen3.8-livetranslate-flash-realtime
O servidor detecta voltas e gera respostas por padrão. A tabela seguinte resume as principais fases de interação. Veja [Eventos de servidor] (/api-reference/speech-translation/livetranslate-realtime/server-events) para campos de eventos.
| Estágio | Ação do cliente | -Eventos de servidor. |
|---|---|---|
| Crie e configure a sessão | Conectar e enviarsession.update |
session.created,session.updated |
| Enviem áudio | input_audio_buffer.append |
A transcrição da fonte é transmitida através deconversation.item.input_audio_transcription.delta, seguido porconversation.item.input_audio_transcription.completed. |
| Receba tradução e áudio | Continue recebendo eventos do servidor. | Tradução é devolvida atravésresponse.text.delta(apenas texto) ouresponse.audio_transcript.delta(texto e áudio). O áudio é devolvido atravésresponse.audio.delta.response.done marca o fim de uma resposta. |
| Termine a sessão. | session.finish |
Feche a conexão após recebersession.finished. |
qwen3.5-livetranslate-flash-realtime
Tradução de discurso em tempo real segue um modelo WebSocket dirigido por eventos. Como os limites de fala são determinados depende do modo VAD ou do modo Manual (ver [3. Entrada de áudio e imagens (#3-input-audio-and-images)). A tabela abaixo é baseada no modo VAD (padrão) e anota os diferentes eventos do servidor no modo Manual.
| Ciclo de vida | Evento do cliente | -Evento do servidor. |
|---|---|---|
| Inicialização da sessão | Session.update (Configuração da sessão) | Session.created (Session created), session.updated (Session configuration updated) |
| Entrada de áudio do usuário | input_audio_buffer.append (Anexar áudio ao buffer), input_image_buffer.append (Anexar imagem ao buffer), input_audio_buffer.commit ((Modo manual apenas) Commit the audio buffer) | Modo VAD:input_audio_buffer.speech_started (Início de fala detectado), input_audio_buffer.speech_stopped (End de fala detectado; servidor automaticamente compromete o buffer de áudio). Modo manual:(Retorno após o cliente enviar o input_audio_buffer.commit, confirmando o buffer de áudio foi cometido) |
| Saída de áudio do servidor | Nenhum. | response.created (Sinais que o servidor começa a gerar uma resposta), response.output_item. added (Sinais que um novo item de saída está disponível), conversation.item.created (Um novo item de mensagem é criado na conversa), response.content_part. added (Sinais que uma nova parte de conteúdo foi adicionada à mensagem assistente), response.text.text (Texto traduzido em modo texto-somente), response.audio_transcript.text (Texto traduzido em modalidade áudio+texto), response.audio.delta (Contém um trecho incremental do (Respondência: conteúdo: texto: texto: completo: áudio: completo: áudio: completo: texto: completo: áudio: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: completo: |
| Sessão de encerramento | Session.finir (Notifica ao servidor que a entrada de áudio está completa) | Session.completou (processamento do servidor completo; sessão terminada) |
Depois de enviar todo o áudio, envie um `session.finish` Evento e esperar `session.finished` Antes de fechar o WebSocket. Se você fechar a conexão sem enviar `session.finish`O servidor não pode saber que a entrada de áudio terminou, e o reconhecimento e os resultados da tradução para o último segmento de fala serão perdidos.
Melhore a tradução com imagens.
O qwen3.5-livetranslate-flash-realtime O modelo usa a entrada de imagem para melhorar a tradução de áudio, ajudando a desambiguar homônimos e reconhecer substantivos comuns. Não envie mais de 2 imagens por segundo.
Baixe as seguintes imagens de amostra:https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/en-US/20250923/tjpeys/%E5%8F%A3%E7%BD%A9.pngE uma máscara de máscara.https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/en-US/20250923/ifqttq/%E9%9D%A2%E5%85%B7.png)
Baixe o seguinte código para o mesmo diretório que livetranslate_client.py e execute-o. Diga. "What is mask?" no seu microfone. O modelo usa a imagem fornecida para desambiguar a palavra "máscara". medical mask.png O arquivo traduz a frase "O que é uma máscara médica?", enquanto usa o masquerade mask.png O arquivo traduz como "O que é uma máscara de máscara?"
import os
import time
import json
import asyncio
import contextlib
import functools
from livetranslate_client import LiveTranslateClient
IMAGE_PATH = "medical mask.png"
# IMAGE_PATH = "masquerade mask.png"
def print_banner():
print("=" * 60)
print(" Powered by Qwen qwen3.5-livetranslate-flash-realtime — single-turn interaction example (mask)")
print("=" * 60 + "\n")
async def stream_microphone_once(client: LiveTranslateClient, image_bytes: bytes):
pa = client.pyaudio_instance
stream = pa.open(
format=client.input_format,
channels=client.input_channels,
rate=client.input_rate,
input=True,
frames_per_buffer=client.input_chunk,
)
print(f"[INFO] Recording started. Please speak...")
loop = asyncio.get_event_loop()
last_img_time = 0.0
frame_interval = 0.5 # 2 fps
try:
while client.is_connected:
data = await loop.run_in_executor(None, stream.read, client.input_chunk)
await client.send_audio_chunk(data)
# Append an image frame every 0.5 seconds
now = time.time()
if now - last_img_time >= frame_interval:
await client.send_image_frame(image_bytes)
last_img_time = now
finally:
stream.stop_stream()
stream.close()
async def main():
print_banner()
api_key = os.environ.get("DASHSCOPE_API_KEY")
if not api_key:
print("[ERROR] Please set the DASHSCOPE_API_KEY environment variable.")
return
client = LiveTranslateClient(api_key=api_key, target_language="zh", audio_enabled=True)
def on_text(text: str):
print(text, end="", flush=True)
try:
await client.connect()
client.start_audio_player()
message_task = asyncio.create_task(client.handle_server_messages(on_text))
with open(IMAGE_PATH, "rb") as f:
img_bytes = f.read()
await stream_microphone_once(client, img_bytes)
await asyncio.sleep(15)
finally:
await client.close()
if not message_task.done():
message_task.cancel()
with contextlib.suppress(asyncio.CancelledError):
await message_task
if __name__ == "__main__":
asyncio.run(main())
Contagem
Qwen3.8-LiveTranslate-Flash-Realtime e Qwen3.5-LiveTranslate-Flash-Realtime
- 7 fichas por segundo de áudio de entrada, 12,5 fichas por segundo de áudio de saída.
- Cada 32x32 pixels consome 0,5 fichas.
Para preços, veja [lista de modelos] (/developer-guides/getting-started/model-selection).
Linguagens apoiadas
Use os seguintes códigos de linguagem para especificar a fonte e línguas alvo.
| Código da língua. | Linguagem | Saída |
|---|---|---|
| zh | Chinês. | Áudio + texto |
| en | Inglês | Áudio + texto |
| ar | Árabe. | Áudio + texto |
| de | Alemão | Áudio + texto |
| fr | Francês | Áudio + texto |
| es | Espanhol | Áudio + texto |
| pt | Português | Áudio + texto |
| id | indonésio | Áudio + texto |
| it | Italiano | Áudio + texto |
| ko | Coreano | Áudio + texto |
| ru | Russo | Áudio + texto |
| th | Tailandês | Áudio + texto |
| vi | Vietnamita | Áudio + texto |
| ja | Japonês | Áudio + texto |
| tr | Turco | Áudio + texto |
| hi | Hindi. | Áudio + texto |
| ms | Malaio. | Áudio + texto |
| nl | Holandês | Áudio + texto |
| ur | Urdu. | Áudio + texto |
| nb | Bokmål norueguês | Áudio + texto |
| sv | Sueco | Áudio + texto |
| da | Dinamarquês | Áudio + texto |
| he | Hebreu | Áudio + texto |
| fi | Finlandês | Áudio + texto |
| pl | Polonês | Áudio + texto |
| is | Islandês | Áudio + texto |
| cs | Tcheco | Áudio + texto |
| fil | Filipino. | Áudio + texto |
| fa | Persa. | Áudio + texto |
| Yue. | Cantonês | Texto |
| el | Grego. | Texto |
| af | Afrikaans. | Texto |
| ast | Asturiano. | Texto |
| be | Belarusian. | Texto |
| bg | Búlgaro | Texto |
| bn | Bengali. | Texto |
| bs | Bósnio | Texto |
| ca | Catalã | Texto |
| Ceb. | Cebuano. | Texto |
| et | Estônia | Texto |
| gl | Galego | Texto |
| gu | Gujarati. | Texto |
| hr | Croata | Texto |
| hu | Húngaro | Texto |
| jv | Javanês. | Texto |
| kk | Cazaque | Texto |
| kn | Kannada. | Texto |
| ky | Quirguiz. | Texto |
| lv | Letão | Texto |
| mk | Macedônio. | Texto |
| ml | Malayalam. | Texto |
| mr | Marathi. | Texto |
| pa | Punjabi. | Texto |
| ro | Romeno | Texto |
| sk | Eslovaco | Texto |
| sl | Esloveno | Texto |
| sw | Suaíli. | Texto |
| tg | Tajik. | Texto |
| az | Azerbaijan. | Texto |
| uk | Ucraniano | Texto |
- Alemão * Áudio + texto * Tradução:
- Espanhol * * Áudio + texto * Tradução: ? Indonésio ? Áudio + texto ? É italiano, áudio, texto. Tradução: Ru Russo, áudio, texto ♪ Thai ♪ ♪ Áudio + texto ♪ Vi Vi Vi Vi Vivi Vivivivivit Ja Ja Japonês, áudio e texto Tradução: Oi, Hindi, áudio, texto. ♪ ♪ Malay ♪ ♪ Áudio + texto ♪
Áudio + texto
Áudio + texto
- Áudio + texto * Tradução: Dinamarquês***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** Ele é hebraico, áudio e texto. Fi, Fi, Finlandês, Áudio, Texto, Tradução: É islandês, áudio e texto. Checo, áudio, texto. ? Fil ? Filipino ? Áudio + texto ? Tradução: Tradução: Tradução: Tradução: Tradução: Seja Belarusian Tradução: ♪ ♪ Bengali ♪ ♪ Texto ♪ Tradução: Tradução: Cebuano, texto Tradução: ♪ ♪ ♪ Galego ♪ ♪ Texto ♪ Gujarati, Gujarati, Tradução: Hu Hu Hu Hu Hungarian Tradução: Tradução: ♪ ♪ Kannada ♪ ♪ Texto ♪ Tradução: Tradução: Tradução: ♪ ♪ Malayalam ♪ ♪ Texto ♪ Tradução e Sincronia: Tradução: Tradução: Tradução: Tradução: Tradução: Tradução: Tradução: Tradução:
Vozes apoiadas
Para as vozes apoiadas por Qwen3.5-LiveTranslate e Qwen3.8-LiveTranslateE o seu voice valores dos parâmetros, veja [lista de voz Omni-modal] (/developer-guides/speech/omni-voice-list).
Referência da API
- [Acontecimentos do cliente] (/api-reference/speech-translation/livetranslate-realtime/client-events)
- [Eventos de servidor] (/api-reference/speech-translation/livetranslate-realtime/server-events)
- [Python SDK] (/api-reference/speech-translation/livetranslate-realtime/python-sdk)
- [Java SDK] (/api-reference/speech-translation/livetranslate-realtime/java-sdk)
- [cliente AOQ SDK] (/api-reference/realtime-api/aoq-sdk-intro)
- [Observação API em tempo real] (/api-reference/realtime-api/overview(Descrição do protocolo WebRTC)