qwen3-livetranslate-flash traduit des fichiers audio et vidéo dans 18 langues. Il accepte une entrée audio ou vidéo et renvoie du texte traduit, de l'audio synthétisé, ou les deux via une API en streaming. Pour les entrées vidéo, le contexte visuel améliore la précision de la traduction (par exemple, distinguer un « masque médical » d'un « masque de bal » grâce aux images vidéo).
Prérequis
- Créer une clé API.
- Configurer la clé API comme variable d'environnement.
- (Facultatif) Si vous utilisez le SDK OpenAI, installez le SDK.
Démarrage rapide
Tous les exemples utilisent l'API en streaming compatible OpenAI. Définissez les langues source et cible via translation_options. L'entrée par défaut est l'audio ; décommentez le bloc d'entrée vidéo dans chaque exemple pour traduire des fichiers vidéo.
Spécifier
source_langaméliore la précision. Omettez ce paramètre pour activer la détection automatique de la langue.
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"
}
}'
Ces exemples utilisent l'URL d'un fichier public. Pour utiliser un fichier local, consultez Saisir un fichier local encodé en Base64.
Paramètres de la requête
Entrée
Le tableau messages doit contenir exactement un message dont le role est défini sur user. Le champ content contient l'audio ou la vidéo à traduire :
- Audio : Définissez
typesurinput_audio. Fournissez l'URL du fichier ou les données encodées en Base64 dansinput_audio.dataet spécifiez le format (par exemple,wav) dansinput_audio.format. - Vidéo : Définissez
typesurvideo_url. Indiquez l'URL du fichier dansvideo_url.url.
Options de traduction
Spécifiez les langues source et cible dans le paramètre translation_options :
"translation_options": {"source_lang": "zh", "target_lang": "en"}
Dans le SDK Python, translation_options n'est pas un paramètre OpenAI standard. Transmettez-le via extra_body :
extra_body={"translation_options": {"source_lang": "zh", "target_lang": "en"}}
Modalité de sortie
Contrôlez le format de sortie avec le paramètre modalities :
**Valeur de modalities** | Sortie |
|---|---|
["text"] | Texte traduit uniquement |
["text", "audio"] | Texte traduit et audio synthétisé encodé en Base64 |
Si la sortie inclut de l'audio, définissez la voix dans le paramètre audio. Consultez Voix prises en charge pour connaître les options disponibles.
Contraintes
- Tour unique uniquement : Le modèle traite une seule traduction par requête. Les conversations multi-tours ne sont pas prises en charge.
- Aucun message système : Le rôle
systemn'est pas pris en charge. - Streaming uniquement : Seule la sortie en streaming compatible OpenAI est prise en charge.
Analyser la réponse
Chaque objet chunk du flux contient :
- Texte :
chunk.choices[0].delta.content - Audio :
chunk.choices[0].delta.audio["data"](encodé en Base64, taux d'échantillonnage de 24 kHz)
Enregistrer l'audio dans un fichier
Concaténez tous les fragments audio Base64 du flux, puis décodez et enregistrez le résultat une fois le flux terminé.
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");
Lecture en temps réel
Décodez chaque fragment Base64 dès sa réception et jouez-le directement. Cette approche nécessite des bibliothèques audio spécifiques à la plateforme.
Python
Installez d'abord pyaudio :
| Plateforme | Installation |
|---|---|
| macOS | brew install portaudio && pip install pyaudio |
| Ubuntu / Debian | sudo apt-get install python-pyaudio python3-pyaudio ou 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
Installez d'abord les dépendances :
| Plateforme | Installation |
|---|---|
| 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();
Facturation
Audio
Chaque seconde d'audio en entrée ou en sortie consomme 12,5 tokens. Toute durée audio inférieure à 1 seconde est facturée comme 1 seconde.
Vidéo
La consommation de tokens vidéo se compose de deux éléments :
-
Tokens audio : 12,5 tokens par seconde d'audio. Toute durée audio inférieure à 1 seconde est facturée comme 1 seconde.
-
Tokens vidéo : Calculés en fonction du nombre d'images et de la résolution selon la formule suivante :
video_tokens = ceil(frame_count / 2) x (height / 32) x (width / 32) + 2Où :
- Les images sont échantillonnées à 2 FPS, limitées à l'intervalle [4, 128].
- La hauteur et la largeur sont ajustées à des multiples de 32 pixels et mises à l'échelle dynamiquement pour respecter la limite totale de pixels.
Script Python pour calculer les tokens vidéo
# 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)
Pour connaître les tarifs des tokens, consultez Liste des modèles.
Détails du modèle
| Modèle | Version | Fenêtre de contexte | Entrée max. | Sortie max. |
|---|---|---|---|---|
| qwen3-livetranslate-flash | Stable | 53 248 tokens | 49 152 tokens | 4 096 tokens |
| qwen3-livetranslate-flash-2025-12-01 | Snapshot | 53 248 tokens | 49 152 tokens | 4 096 tokens |
Actuellement, qwen3-livetranslate-flash possède les mêmes capacités que qwen3-livetranslate-flash-2025-12-01.
Langues prises en charge
Utilisez ces codes de langue pour source_lang et target_lang. Certaines langues cibles ne prennent en charge que la sortie texte.
| Code de langue | Langue | Sortie prise en charge |
|---|---|---|
| en | Anglais | Audio, texte |
| zh | Chinois | Audio, texte |
| ru | Russe | Audio, texte |
| fr | Français | Audio, texte |
| de | Allemand | Audio, texte |
| pt | Portugais | Audio, texte |
| es | Espagnol | Audio, texte |
| it | Italien | Audio, texte |
| id | Indonésien | Texte |
| ko | Coréen | Audio, texte |
| ja | Japonais | Audio, texte |
| vi | Vietnamien | Texte |
| th | Thaï | Texte |
| ar | Arabe | Texte |
| yue | Cantonais | Audio, texte |
| hi | Hindi | Texte |
| el | Grec | Texte |
| tr | Turc | Texte |
Voix prises en charge
Définissez le paramètre voice dans audio lorsque la sortie inclut de l'audio synthétisé.
| Nom de la voix | **Paramètre voice** | Description | Langues prises en charge |
|---|---|---|---|
| Cherry | Cherry | Une jeune femme joyeuse, amicale et authentique. | Chinois, anglais, français, allemand, russe, italien, espagnol, portugais, japonais, coréen |
| Nofish | Nofish | Un designer ayant des difficultés à prononcer les consonnes rétroflexes. | Chinois, anglais, français, allemand, russe, italien, espagnol, portugais, japonais, coréen |
| Shanghai-Jada | Jada | Une femme shanghaienne dynamique et pleine d'énergie. | Chinois |
| Beijing-Dylan | Dylan | Un jeune homme qui a grandi dans les hutongs de Pékin. | Chinois |
| Sichuan-Sunny | Sunny | Une douce jeune fille du Sichuan. | Chinois |
| Tianjin-Peter | Peter | Une voix dans le style d'un artiste de crosstalk de Tianjin (le rôle secondaire). | Chinois |
| Cantonese-Kiki | Kiki | Une meilleure amie douce venue de Hong Kong. | Cantonais |
| Sichuan-Eric | Eric | Un homme de Chengdu, au Sichuan, anticonformiste et singulier. | Chinois |
FAQ
Quel contenu est traduit lors de la fourniture d'un fichier vidéo ?
Le modèle traduit la piste audio de la vidéo. Les informations visuelles améliorent la précision de la traduction.
Par exemple, si l'audio dit « Ceci est un masque » :
- Si la vidéo montre un masque médical, le modèle le traduit par « Ceci est un masque médical ».
- Si la vidéo montre un masque de bal, le modèle le traduit par « Ceci est un masque de bal ».
Référence API
Pour tous les détails sur les paramètres d'entrée et de sortie, consultez Traduction audio et vidéo - Qwen.