qwen3-livetranslate-flash traduce archivos de audio y video en 18 idiomas. Acepta entrada de audio o video y devuelve texto traducido, audio sintetizado o ambos a través de una API de transmisión. Para entradas de video, el contexto visual mejora la precisión de la traducción (por ejemplo, distinguiendo entre "mascarilla médica" y "máscara de carnaval" basándose en los fotogramas del video).
Antes de comenzar
- Crear una clave de API.
- Configure la clave de API como variable de entorno.
- (Opcional) Si utiliza el SDK de OpenAI, instale el SDK.
Inicio rápido
Todos los ejemplos utilizan la API de transmisión compatible con OpenAI. Establezca los idiomas de origen y destino mediante translation_options. La entrada predeterminada es audio; descomente el bloque de entrada de video en cada ejemplo para traducir archivos de video en su lugar.
Especificar
source_langmejora la precisión. Omítalo para habilitar la detección automática de idioma.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
# --- Audio input ---
messages = [
{
"role": "user",
"content": [
{
"type": "input_audio",
"input_audio": {
"data": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250211/tixcef/cherry.wav",
"format": "wav",
},
}
],
}
]
# --- Video input (uncomment to use) ---
# messages = [
# {
# "role": "user",
# "content": [
# {
# "type": "video_url",
# "video_url": {
# "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241115/cqqkru/1.mp4"
# },
# }
# ],
# },
# ]
completion = client.chat.completions.create(
model="qwen3-livetranslate-flash",
messages=messages,
modalities=["text", "audio"],
audio={"voice": "Cherry", "format": "wav"},
stream=True,
stream_options={"include_usage": True},
# translation_options is not a standard OpenAI parameter; pass it through extra_body
extra_body={"translation_options": {"source_lang": "zh", "target_lang": "en"}},
)
for chunk in completion:
print(chunk)
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
});
// --- Audio input ---
const messages = [
{
role: "user",
content: [
{
type: "input_audio",
input_audio: {
data: "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250211/tixcef/cherry.wav",
format: "wav",
},
},
],
},
];
// --- Video input (uncomment to use) ---
// const messages = [
// {
// role: "user",
// content: [
// {
// type: "video_url",
// video_url: {
// url: "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241115/cqqkru/1.mp4",
// },
// },
// ],
// },
// ];
async function main() {
const completion = await client.chat.completions.create({
model: "qwen3-livetranslate-flash",
messages: messages,
modalities: ["text", "audio"],
audio: { voice: "Cherry", format: "wav" },
stream: true,
stream_options: { include_usage: true },
translation_options: { source_lang: "zh", target_lang: "en" },
});
for await (const chunk of completion) {
console.log(JSON.stringify(chunk));
}
}
main();
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-livetranslate-flash",
"messages": [
{
"role": "user",
"content": [
{
"type": "input_audio",
"input_audio": {
"data": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250211/tixcef/cherry.wav",
"format": "wav"
}
}
]
}
],
"modalities": ["text", "audio"],
"audio": {
"voice": "Cherry",
"format": "wav"
},
"stream": true,
"stream_options": {
"include_usage": true
},
"translation_options": {
"source_lang": "zh",
"target_lang": "en"
}
}'
Estos ejemplos utilizan una URL de archivo pública. Para utilizar un archivo local, consulte Ingresar un archivo local codificado en Base64.
Parámetros de solicitud
Entrada
El arreglo messages debe contener exactamente un mensaje con role establecido en user. El campo content contiene el audio o video a traducir:
- Audio: Establezca
typeeninput_audio. Proporcione la URL del archivo o datos codificados en Base64 eninput_audio.data, y especifique el formato (por ejemplo,wav) eninput_audio.format. - Video: Establezca
typeenvideo_url. Proporcione la URL del archivo envideo_url.url.
Opciones de traducción
Especifique los idiomas de origen y destino en el parámetro translation_options:
"translation_options": {"source_lang": "zh", "target_lang": "en"}
En el SDK de Python, translation_options no es un parámetro estándar de OpenAI. Páselo a través de extra_body:
extra_body={"translation_options": {"source_lang": "zh", "target_lang": "en"}}
Modalidad de salida
Controle el formato de salida con el parámetro modalities:
Valor de modalities | Salida |
|---|---|
["text"] | Solo texto traducido |
["text", "audio"] | Texto traducido y audio sintetizado codificado en Base64 |
Cuando la salida incluye audio, establezca la voz en el parámetro audio. Consulte Voces admitidas para ver las opciones disponibles.
Restricciones
- Solo turno único: El modelo gestiona una traducción por solicitud. No se admiten conversaciones de múltiples turnos.
- Sin mensaje del sistema: El rol
systemno es compatible. - Solo transmisión: Solo se admite la salida por transmisión compatible con OpenAI.
Analizar la respuesta
Cada objeto chunk de transmisión contiene:
- Texto:
chunk.choices[0].delta.content - Audio:
chunk.choices[0].delta.audio["data"](codificado en Base64, tasa de muestreo de 24 kHz)
Guardar audio en un archivo
Concatene todos los fragmentos de audio Base64 de la transmisión, luego decodifique y guarde el resultado una vez completada la transmisión.
Python
import os
from openai import OpenAI
import base64
import numpy as np
import soundfile as sf
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
messages = [
{
"role": "user",
"content": [
{
"type": "input_audio",
"input_audio": {
"data": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250211/tixcef/cherry.wav",
"format": "wav",
},
}
],
}
]
completion = client.chat.completions.create(
model="qwen3-livetranslate-flash",
messages=messages,
modalities=["text", "audio"],
audio={"voice": "Cherry", "format": "wav"},
stream=True,
stream_options={"include_usage": True},
extra_body={"translation_options": {"source_lang": "zh", "target_lang": "en"}},
)
# Concatenate Base64 fragments, then decode after the stream completes
audio_string = ""
for chunk in completion:
if chunk.choices:
if hasattr(chunk.choices[0].delta, "audio"):
try:
audio_string += chunk.choices[0].delta.audio["data"]
except Exception as e:
print(chunk.choices[0].delta.audio["transcript"])
else:
print(chunk.usage)
wav_bytes = base64.b64decode(audio_string)
audio_np = np.frombuffer(wav_bytes, dtype=np.int16)
sf.write("output.wav", audio_np, samplerate=24000)
Node.js
import OpenAI from "openai";
import { createWriteStream } from "node:fs";
import { Writer } from "wav";
const client = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
});
const messages = [
{
role: "user",
content: [
{
type: "input_audio",
input_audio: {
data: "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250211/tixcef/cherry.wav",
format: "wav",
},
},
],
},
];
const completion = await client.chat.completions.create({
model: "qwen3-livetranslate-flash",
messages: messages,
modalities: ["text", "audio"],
audio: { voice: "Cherry", format: "wav" },
stream: true,
stream_options: { include_usage: true },
translation_options: { source_lang: "zh", target_lang: "en" },
});
// Concatenate Base64 fragments, then decode after the stream completes
let audioString = "";
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
if (chunk.choices[0].delta.audio?.data) {
audioString += chunk.choices[0].delta.audio.data;
}
} else {
console.log(chunk.usage);
}
}
// Save as WAV file
async function saveAudio(base64Data, outputPath) {
const wavBuffer = Buffer.from(base64Data, "base64");
const writer = new Writer({
sampleRate: 24000,
channels: 1,
bitDepth: 16,
});
const outputStream = createWriteStream(outputPath);
writer.pipe(outputStream);
writer.write(wavBuffer);
writer.end();
await new Promise((resolve, reject) => {
outputStream.on("finish", resolve);
outputStream.on("error", reject);
});
console.log(`Audio saved to ${outputPath}`);
}
saveAudio(audioString, "output.wav");
Reproducción en tiempo real
Decodifique cada fragmento Base64 a medida que llega y reprodúzcalo directamente. Este enfoque requiere bibliotecas de audio específicas de la plataforma.
Python
Instale pyaudio primero:
| Plataforma | Instalación |
|---|---|
| macOS | brew install portaudio && pip install pyaudio |
| Ubuntu / Debian | sudo apt-get install python-pyaudio python3-pyaudio o pip install pyaudio |
| CentOS | sudo yum install -y portaudio portaudio-devel && pip install pyaudio |
| Windows | python -m pip install pyaudio |
import os
from openai import OpenAI
import base64
import numpy as np
import pyaudio
import time
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
messages = [
{
"role": "user",
"content": [
{
"type": "input_audio",
"input_audio": {
"data": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250211/tixcef/cherry.wav",
"format": "wav",
},
}
],
}
]
completion = client.chat.completions.create(
model="qwen3-livetranslate-flash",
messages=messages,
modalities=["text", "audio"],
audio={"voice": "Cherry", "format": "wav"},
stream=True,
stream_options={"include_usage": True},
extra_body={"translation_options": {"source_lang": "zh", "target_lang": "en"}},
)
# Initialize PyAudio for real-time playback
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1, rate=24000, output=True)
for chunk in completion:
if chunk.choices:
if hasattr(chunk.choices[0].delta, "audio"):
try:
audio_data = chunk.choices[0].delta.audio["data"]
wav_bytes = base64.b64decode(audio_data)
audio_np = np.frombuffer(wav_bytes, dtype=np.int16)
stream.write(audio_np.tobytes())
except Exception as e:
print(chunk.choices[0].delta.audio["transcript"])
time.sleep(0.8)
stream.stop_stream()
stream.close()
p.terminate()
Node.js
Instale las dependencias primero:
| Plataforma | Instalación |
|---|---|
| macOS | brew install portaudio && npm install speaker |
| Ubuntu / Debian | sudo apt-get install libasound2-dev && npm install speaker |
| Windows | npm install speaker |
import OpenAI from "openai";
import Speaker from "speaker";
const client = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
// The following URL is for the Singapore region. When calling, replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
});
const messages = [
{
role: "user",
content: [
{
type: "input_audio",
input_audio: {
data: "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250211/tixcef/cherry.wav",
format: "wav",
},
},
],
},
];
const completion = await client.chat.completions.create({
model: "qwen3-livetranslate-flash",
messages: messages,
modalities: ["text", "audio"],
audio: { voice: "Cherry", format: "wav" },
stream: true,
stream_options: { include_usage: true },
translation_options: { source_lang: "zh", target_lang: "en" },
});
// Stream audio to speaker in real time
const speaker = new Speaker({
sampleRate: 24000,
channels: 1,
bitDepth: 16,
signed: true,
});
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
if (chunk.choices[0].delta.audio?.data) {
const pcmBuffer = Buffer.from(chunk.choices[0].delta.audio.data, "base64");
speaker.write(pcmBuffer);
}
} else {
console.log(chunk.usage);
}
}
speaker.on("finish", () => console.log("Playback complete"));
speaker.end();
Facturación
Audio
Cada segundo de audio de entrada o salida consume 12.5 tokens. El audio de menos de 1 segundo se factura como 1 segundo.
Video
El consumo de tokens de video tiene dos componentes:
- Tokens de audio: 12.5 tokens por segundo de audio. El audio de menos de 1 segundo se factura como 1 segundo.
- Tokens de video: Calculados según el recuento de fotogramas y la resolución. La fórmula es:
video_tokens = ceil(frame_count / 2) x (height / 32) x (width / 32) + 2
Donde:
- Los fotogramas se muestrean a 2 FPS, limitados al rango [4, 128].
- La altura y el ancho se ajustan a múltiplos de 32 píxeles y se escalan dinámicamente para ajustarse al límite total de píxeles.
Detalles
Script de Python para calcular tokens de video
# Install: pip install opencv-python
import math
import cv2
FRAME_FACTOR = 2
IMAGE_FACTOR = 32
MAX_RATIO = 200
VIDEO_MIN_PIXELS = 128 * 32 * 32
VIDEO_MAX_PIXELS = 768 * 32 * 32
FPS = 2
FPS_MIN_FRAMES = 4
FPS_MAX_FRAMES = 128
VIDEO_TOTAL_PIXELS = 16384 * 32 * 32
def round_by_factor(number, factor):
return round(number / factor) * factor
def ceil_by_factor(number, factor):
return math.ceil(number / factor) * factor
def floor_by_factor(number, factor):
return math.floor(number / factor) * factor
def get_video(video_path):
cap = cv2.VideoCapture(video_path)
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
video_fps = cap.get(cv2.CAP_PROP_FPS)
cap.release()
return frame_height, frame_width, total_frames, video_fps
def smart_nframes(total_frames, video_fps):
min_frames = ceil_by_factor(FPS_MIN_FRAMES, FRAME_FACTOR)
max_frames = floor_by_factor(min(FPS_MAX_FRAMES, total_frames), FRAME_FACTOR)
duration = total_frames / video_fps if video_fps != 0 else 0
if duration - int(duration) > (1 / FPS):
total_frames = math.ceil(duration * video_fps)
else:
total_frames = math.ceil(int(duration) * video_fps)
nframes = total_frames / video_fps * FPS
nframes = int(min(min(max(nframes, min_frames), max_frames), total_frames))
if not (FRAME_FACTOR <= nframes <= total_frames):
raise ValueError(f"nframes should in interval [{FRAME_FACTOR}, {total_frames}], but got {nframes}.")
return nframes
def smart_resize(height, width, nframes, factor=IMAGE_FACTOR):
min_pixels = VIDEO_MIN_PIXELS
total_pixels = VIDEO_TOTAL_PIXELS
max_pixels = max(min(VIDEO_MAX_PIXELS, total_pixels / nframes * FRAME_FACTOR), int(min_pixels * 1.05))
if max(height, width) / min(height, width) > MAX_RATIO:
raise ValueError(f"absolute aspect ratio must be smaller than {MAX_RATIO}, got {max(height, width) / min(height, width)}")
h_bar = max(factor, round_by_factor(height, factor))
w_bar = max(factor, round_by_factor(width, factor))
if h_bar * w_bar > max_pixels:
beta = math.sqrt((height * width) / max_pixels)
h_bar = floor_by_factor(height / beta, factor)
w_bar = floor_by_factor(width / beta, factor)
elif h_bar * w_bar < min_pixels:
beta = math.sqrt(min_pixels / (height * width))
h_bar = ceil_by_factor(height * beta, factor)
w_bar = ceil_by_factor(width * beta, factor)
return h_bar, w_bar
def video_token_calculate(video_path):
height, width, total_frames, video_fps = get_video(video_path)
nframes = smart_nframes(total_frames, video_fps)
resized_height, resized_width = smart_resize(height, width, nframes)
video_token = int(math.ceil(nframes / FPS) * resized_height / 32 * resized_width / 32)
video_token += 2
return video_token
if __name__ == "__main__":
video_path = "spring_mountain.mp4" # Replace with your video path
video_token = video_token_calculate(video_path)
print("video_tokens:", video_token)
Para consultar los precios de tokens, consulte Lista de modelos.
Detalles del modelo
| Modelo | Versión | Ventana de contexto | Entrada máxima | Salida máxima |
|---|---|---|---|---|
| qwen3-livetranslate-flash | Estable | 53,248 tokens | 49,152 tokens | 4,096 tokens |
| qwen3-livetranslate-flash-2025-12-01 | Instantánea | 53,248 tokens | 49,152 tokens | 4,096 tokens |
qwen3-livetranslate-flash actualmente tiene las mismas capacidades que qwen3-livetranslate-flash-2025-12-01.
Idiomas admitidos
Utilice estos códigos de idioma para source_lang y target_lang. Algunos idiomas de destino solo admiten salida de texto.
| Código de idioma | Idioma | Salida admitida |
|---|---|---|
| en | Inglés | Audio, texto |
| zh | Chino | Audio, texto |
| ru | Ruso | Audio, texto |
| fr | Francés | Audio, texto |
| de | Alemán | Audio, texto |
| pt | Portugués | Audio, texto |
| es | Español | Audio, texto |
| it | Italiano | Audio, texto |
| id | Indonesio | Text |
| ko | Coreano | Audio, texto |
| ja | Japonés | Audio, texto |
| vi | Vietnamita | Text |
| th | Tailandés | Text |
| ar | Árabe | Text |
| yue | Cantonés | Audio, texto |
| hi | Hindi | Text |
| el | Griego | Text |
| tr | Turco | Text |
Voces admitidas
Establezca el parámetro voice en audio cuando la salida incluya audio sintetizado.
| Nombre de voz | Parámetro voice | Descripción | Idiomas admitidos |
|---|---|---|---|
| Cherry | Cherry | Una mujer joven alegre, amable y auténtica. | Chino, inglés, francés, alemán, ruso, italiano, español, portugués, japonés, coreano |
| Nofish | Nofish | Un diseñador que tiene dificultad para pronunciar consonantes retroflejas. | Chino, inglés, francés, alemán, ruso, italiano, español, portugués, japonés, coreano |
| Shanghai-Jada | Jada | Una dama bulliciosa y enérgica de Shanghái. | Chino |
| Beijing-Dylan | Dylan | Un hombre joven que creció en los hutongs de Pekín. | Chino |
| Sichuan-Sunny | Sunny | Una chica dulce de Sichuan. | Chino |
| Tianjin-Peter | Peter | Una voz al estilo de un intérprete de xiangsheng de Tianjin (el papel secundario). | Chino |
| Cantonese-Kiki | Kiki | Una dulce mejor amiga de Hong Kong. | Cantonés |
| Sichuan-Eric | Eric | Un hombre de Chengdu, Sichuan, que es poco convencional y destaca entre la multitud. | Chino |
FAQ
Cuando ingreso un archivo de video, ¿qué contenido se traduce?
El modelo traduce la pista de audio del video. La información visual mejora la precisión de la traducción.
Por ejemplo, si el audio dice "Esto es una mascarilla":
- Cuando el video muestra una mascarilla médica, el modelo lo traduce como "Esto es una mascarilla médica".
- Cuando el video muestra una máscara de carnaval, el modelo lo traduce como "Esto es una máscara de carnaval".
Referencia de API
Para obtener detalles completos sobre los parámetros de entrada y salida, consulte Traducción de audio y video - Qwen.