千問3-LiveTranslate-Flash 是音視頻翻譯模型,支援 18 種語言(包括中文、英文、俄文、法文等)互譯,可結合視覺上下文提升翻譯準確性,並輸出文本與語音。
工作方式
-
設定語種:參考支援的語種,在
translation_options參數中設定源語種 (source_lang) 和目標語種 (target_lang)。省略
source_lang將啟用自動檢測,但指定語種能提升翻譯準確率。 -
輸入待翻譯檔案:
messages數組中有且僅有一條role為user的訊息,content欄位需傳入待翻譯音頻/視頻的 URL 或 Base64 資料。 -
控制輸出模態:通過
modalities參數控制輸出模態:-
["text"]:僅輸出文本; -
["text","audio"]:輸出文本和 Base 64 編碼的音頻。若輸出音頻,需在
audio參數中設定音色(voice)。參考支援的音色。
-
以下為使用 OpenAI Python SDK 的核心代碼:
# 匯入依賴與建立用戶端...
completion = client.chat.completions.create(
model="qwen3-livetranslate-flash", # 選擇模型
# messages 僅包含一條 user 訊息,content 為待翻譯檔案
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"
}
}
]
}
],
# translation_options 非 OpenAI 標準參數,需通過 extra_body 傳入
extra_body={"translation_options": {"source_lang": "zh", "target_lang": "en"}},
# 樣本:輸出文本和音頻
modalities = ["text","audio"],
audio={"voice": "Cherry", "format": "wav"}
)
使用限制
- 單輪翻譯:模型專為翻譯任務設計,不支援多輪對話。
- 無 System Message:不支援通過
system角色設定全域行為。 - 調用方式:僅支援相容 OpenAI 協議的流式輸出。
chunk為流式響應對象:
- 文本:讀取
chunk.choices[0].delta.content。 - 音頻:讀取
chunk.choices[0].delta.audio["data"],模型輸出音訊採樣率是 24kHz。
支援的模型
| 模型名稱 | 版本 | 上下文長度 | 最大輸入 | 最大輸出 |
|---|---|---|---|---|
| (Token數) | ||||
qwen3-livetranslate-flash
| 穩定版 | 53,248 | 49,152 | 4,096 |
qwen3-livetranslate-flash-2025-12-01 | 快照版 | |||
如何使用
qwen3-livetranslate-flash 模型支援音頻或視頻輸入,並輸出文本與音頻。
請確保已擷取API Key並配置API Key到環境變數。若通過OpenAI SDK調用,需安裝SDK。
以下樣本使用音頻輸入。如需輸入視頻,請取消對應代碼的注釋。
import os
from openai import OpenAI
client = OpenAI(
# 若沒有配置環境變數,請用阿里雲百鍊API Key將下行替換為:api_key="sk-xxx",
api_key=os.getenv("DASHSCOPE_API_KEY"),
# 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。
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",
},
}
],
}
]
# ----------------視頻輸入(需取消注釋)----------------
# 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},
extra_body={"translation_options": {"source_lang": "zh", "target_lang": "en"}},
)
for chunk in completion:
print(chunk)
import OpenAI from "openai";
const client = new OpenAI({
// 若沒有配置環境變數,請用阿里雲百鍊API Key將下行替換為:apiKey: "sk-xxx",
apiKey: process.env.DASHSCOPE_API_KEY,
// 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。
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 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();
# ======= 重要提示 =======
# 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。
# === 執行時請刪除該注釋 ===
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"
}
}'
此樣本使用公網檔案 URL。若使用本地檔案,請參見輸入 Base 64 編碼的本地檔案中的音頻與視頻部分。
解析 Base64 音頻資料
模型以流式 Base 64 編碼格式輸出音頻。可採用以下兩種方式處理資料:
- 拼接解碼:拼接所有返回的 Base64 片段,待產生結束後統一解碼,儲存為音頻檔案。
- 即時播放:即時解碼每個 Base64 片段並直接播放。
# Installation instructions for pyaudio:
# APPLE Mac OS X
# brew install portaudio
# pip install pyaudio
# Debian/Ubuntu
# sudo apt-get install python-pyaudio python3-pyaudio
# or
# pip install pyaudio
# CentOS
# sudo yum install -y portaudio portaudio-devel && pip install pyaudio
# Microsoft Windows
# python -m pip install pyaudio
import os
from openai import OpenAI
import base64
import numpy as np
import soundfile as sf
# 初始化OpenAI用戶端
client = OpenAI(
# 若沒有配置環境變數,請用阿里雲百鍊API Key將下行替換為:api_key="sk-xxx",
api_key=os.getenv("DASHSCOPE_API_KEY"),
# 以下為華北2(北京)地區的URL。請將 {WorkspaceId} 替換為您的百鍊業務空間ID,各地區的URL不同。
base_url="https://{WorkspaceId}.cn-beijing.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"}},
)
# 方式1: 待產生結束後再進行解碼
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("audio_assistant_py.wav", audio_np, samplerate=24000)
# 方式2: 邊產生邊解碼(使用方式2請將方式1的代碼進行注釋)
# # 初始化 PyAudio
# import pyaudio
# import time
# 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_string = chunk.choices[0].delta.audio["data"]
# wav_bytes = base64.b64decode(audio_string)
# 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()
// 運行前的準備工作:
// Windows/Mac/Linux 通用:
// 1. 確保已安裝 Node.js (建議版本 >= 14)
// 2. 運行以下命令安裝必要的依賴:
// npm install openai wav
//
// 如果要使用即時播放功能 (方式2), 還需要:
// Windows:
// npm install speaker
// Mac:
// brew install portaudio
// npm install speaker
// Linux (Ubuntu/Debian):
// sudo apt-get install libasound2-dev
// npm install speaker
import OpenAI from "openai";
const client = new OpenAI({
// 若沒有配置環境變數,請用阿里雲百鍊API Key將下行替換為:apiKey: "sk-xxx",
apiKey: process.env.DASHSCOPE_API_KEY,
// 以下為華北2(北京)地區的URL。請將 {WorkspaceId} 替換為您的百鍊業務空間ID,各地區的URL不同。
baseURL: "https://{WorkspaceId}.cn-beijing.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" },
});
// 方式1: 待產生結束後再進行解碼
// 需要安裝: npm install wav
import { createWriteStream } from 'node:fs'; // node:fs 是 Node.js 內建模組,無需安裝
import { Writer } from 'wav';
async function convertAudio(audioString, audioPath) {
try {
// 解碼Base64字串為Buffer
const wavBuffer = Buffer.from(audioString, 'base64');
// 建立WAV檔案寫入流
const writer = new Writer({
sampleRate: 24000, // 採樣率
channels: 1, // 單聲道
bitDepth: 16 // 16位元深度
});
// 建立輸出檔案流並建立管道串連
const outputStream = createWriteStream(audioPath);
writer.pipe(outputStream);
// 寫入PCM資料並結束寫入
writer.write(wavBuffer);
writer.end();
// 使用Promise等待檔案寫入完成
await new Promise((resolve, reject) => {
outputStream.on('finish', resolve);
outputStream.on('error', reject);
});
// 添加額外等待時間確保音頻完整
await new Promise(resolve => setTimeout(resolve, 800));
console.log(`音頻檔案已成功儲存為 ${audioPath}`);
} catch (error) {
console.error('處理過程中發生錯誤:', error);
}
}
let audioString = "";
for await (const chunk of completion) {
if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
if (chunk.choices[0].delta.audio) {
if (chunk.choices[0].delta.audio["data"]) {
audioString += chunk.choices[0].delta.audio["data"];
}
}
} else {
console.log(chunk.usage);
}
}
// 執行轉換
convertAudio(audioString, "audio_assistant_mjs.wav");
// 方式2: 邊產生邊即時播放
// 需要先按照上方系統對應的說明安裝必要組件
// import Speaker from 'speaker'; // 引入音頻播放庫
// // 建立擴音器執行個體(配置與 WAV 檔案參數一致)
// const speaker = new Speaker({
// sampleRate: 24000, // 採樣率
// channels: 1, // 聲道數
// bitDepth: 16, // 位深
// signed: true // 有符號 PCM
// });
// for await (const chunk of completion) {
// if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
// if (chunk.choices[0].delta.audio) {
// 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('播放完成'));
// speaker.end(); // 根據實際 API 流結束情況調用
計費說明
音頻
輸入或輸出每秒音頻均消耗 12.5 Token。
視頻
視頻檔案的 Token 分為 video_tokens(視覺)與 audio_tokens(音頻)。
-
video_tokens本指令碼用於計算
video_tokens。計算流程如下:- 幀數採樣:以 2 FPS 速率採樣。將幀數限制在 [4, 128] 之間。
- 尺寸調整:將高與寬調整為 32 的倍數。根據幀數動態縮放,適配總像素限制。
- Token 計算:⌈幀數/2⌉ × (高/32) × (寬/32) + 2。
# 使用前安裝:pip install opencv-python
import math
import os
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" # 你的視頻路徑
video_token = video_token_calculate(video_path)
print("video_tokens:", video_token)
-
audio_tokens每秒音頻消耗 12.5 Token。若音頻時間長度不足1秒,按 1 秒計算。
Token 費用請參見選擇模型。
API 參考
qwen3-livetranslate-flash 模型的輸入輸出參數請參見音視頻翻譯-通義千問。
支援的語種
下表中的語種代碼可用於指定源語種與目標語種。
部分目標語種僅支援輸出文本,不支援輸出音頻。
語種代碼 | 語種 | 支援的輸出模態 |
|---|---|---|
en | 英語 | 音頻、文本 |
zh | 中文 | 音頻、文本 |
ru | 俄語 | 音頻、文本 |
fr | 法語 | 音頻、文本 |
de | 德語 | 音頻、文本 |
pt | 葡萄牙語 | 音頻、文本 |
es | 西班牙語 | 音頻、文本 |
it | 意大利語 | 音頻、文本 |
id | 印尼語 | 文本 |
ko | 韓語 | 音頻、文本 |
ja | 日語 | 音頻、文本 |
vi | 越南語 | 文本 |
th | 泰語 | 文本 |
ar | 阿拉伯語 | 文本 |
yue | 粵語 | 音頻、文本 |
hi | 印地語 | 文本 |
el | 希臘語 | 文本 |
tr | 土耳其語 | 文本 |
支援的音色
| 音色名 |
| 音色效果 | 描述 | 支援的語種 |
|---|---|---|---|---|
芊悅 | Cherry | 陽光積極、親切自然小姐姐。 | 中文、英語、法語、德語、俄語、意大利語、西班牙語、葡萄牙語、日語、韓語 | |
不吃魚 | Nofish | 不會翹舌音的設計師。 | 中文、英語、法語、德語、俄語、意大利語、西班牙語、葡萄牙語、日語、韓語 | |
上海-阿珍 | Jada | 風風火火的滬上阿姐。 | 中文 | |
北京-曉東 | Dylan | 北京胡同裡長大的少年。 | 中文 | |
四川-晴兒 | Sunny | 甜到你心裡的川妹子。 | 中文 | |
天津-李彼得 | Peter | 天津相聲,專業捧人。 | 中文 | |
粵語-阿清 | Kiki | 甜美的港妹閨蜜。 | 粵語 | |
四川-程川 | Eric | 一個跳脫市井的四川成都男子。 | 中文 |
常見問題
Q:傳入的視訊檔案時,翻譯的是什麼內容?
A:翻譯視頻中的音頻內容,視覺資訊用於輔助上下文理解,以提升準確率。
樣本:
當音頻內容為This is a mask時:
- 若畫面顯示口罩,會翻譯為“這是一個口罩”;
- 若畫面顯示面具,會翻譯為“這是一個面具”。