qwen3-livetranslate-flash は、18 の言語間で音声および動画ファイルを翻訳します。入力として音声または動画を受け付け、ストリーミング API を通じて翻訳されたテキスト、合成音声、またはその両方を返します。動画入力の場合、モデルは動画フレームから得られる視覚的文脈を活用して翻訳精度を向上させます。たとえば、動画に映し出される内容に応じて、「mask」を「医療用マスク」または「仮面」のいずれかに正確に翻訳します。
事前準備
API キーの作成を行います。
API キーを環境変数として設定します。
(任意)OpenAI SDK を使用する場合、SDK のインストールを行います。
クイックスタート
すべての例では、OpenAI 互換のストリーミング API を使用し、translation_options パラメーターでソース言語およびターゲット言語を指定します。デフォルトの入力は音声です。動画ファイルを翻訳する場合は、各例の動画入力ブロックのコメントを解除してください。
source_lang を明示的に指定すると、翻訳精度が向上します。省略した場合は、自動言語検出が有効になります。import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# シンガポールリージョン。北京リージョンの場合は、https://dashscope.aliyuncs.com/compatible-mode/v1 を使用します。
base_url="https://dashscope-intl.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},
# translation_options は標準の OpenAI パラメーターではありません。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,
// シンガポールリージョン。北京リージョンの場合は、https://dashscope.aliyuncs.com/compatible-mode/v1 を使用します。
baseURL: "https://dashscope-intl.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();curl -X POST https://dashscope-intl.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 を使用しています。ローカルファイルを使用する場合は、「Base64 エンコード済みローカルファイルの入力」をご参照ください。
リクエストパラメーター
入力
messages 配列には、role が user に設定されたメッセージが 1 つだけ含まれている必要があります。content フィールドには、翻訳対象の音声または動画が格納されます:
音声:
typeをinput_audioに設定します。input_audio.dataにファイル URL または Base64 エンコード済みデータを指定し、wavなどのフォーマットをinput_audio.formatで指定します。動画:
typeをvideo_urlに設定します。video_url.urlにファイル URL を指定します。
翻訳オプション
translation_options パラメーターで、ソース言語およびターゲット言語を指定します:
"translation_options": {"source_lang": "zh", "target_lang": "en"}Python SDK では、translation_options は標準の OpenAI パラメーターではありません。extra_body 経由で渡します:
extra_body={"translation_options": {"source_lang": "zh", "target_lang": "en"}}出力モダリティ
modalities パラメーターで出力形式を制御します:
modalities の値 | 出力 |
|---|---|
["text"] | 翻訳されたテキストのみ |
["text", "audio"] | 翻訳されたテキストおよび Base64 エンコード済み合成音声 |
出力に音声が含まれる場合、audio パラメーターで音声のボイスを指定します。「サポートされるボイス」で利用可能なオプションをご確認ください。
制限事項
単一ターンのみ: モデルは 1 回のリクエストにつき 1 回の翻訳を処理します。マルチターンの会話はサポートされていません。
システムメッセージ不可:
systemロールはサポートされていません。ストリーミング出力のみ: OpenAI プロトコルと互換性のあるストリーミング出力のみがサポートされています。
応答の解析
各ストリーミング chunk オブジェクトには以下の情報が含まれます:
テキスト:
chunk.choices[0].delta.content音声:
chunk.choices[0].delta.audio["data"](Base64 エンコード、サンプルレート 24 kHz)
音声をファイルに保存
ストリームから受信したすべての Base64 音声フラグメントを連結し、ストリーム完了後にデコードして保存します。
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"),
# シンガポールリージョン。北京リージョンの場合は、https://dashscope.aliyuncs.com/compatible-mode/v1 を使用します。
base_url="https://dashscope-intl.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"}},
)
# ストリーム完了後に Base64 フラグメントを連結し、デコードして保存
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,
# シンガポールリージョン。北京リージョンの場合は、https://dashscope.aliyuncs.com/compatible-mode/v1 を使用します。
baseURL: "https://dashscope-intl.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" },
});
// ストリーム完了後に Base64 フラグメントを連結し、デコードして保存
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);
}
}
// WAV ファイルとして保存
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");リアルタイム再生
受信した Base64 フラグメントを逐次デコードし、即座に再生します。この方法では、プラットフォーム固有の音声ライブラリが必要です。
Python
まず pyaudio をインストールします:
| プラットフォーム | インストール方法 |
|---|---|
| macOS | brew install portaudio && pip install pyaudio |
| Ubuntu / Debian | sudo apt-get install python-pyaudio python3-pyaudio または 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"),
# シンガポールリージョン。北京リージョンの場合は、https://dashscope.aliyuncs.com/compatible-mode/v1 を使用します。
base_url="https://dashscope-intl.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"}},
)
# リアルタイム再生用に PyAudio を初期化
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
まず依存関係をインストールします:
| プラットフォーム | インストール方法 |
|---|---|
| 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,
# シンガポールリージョン。北京リージョンの場合は、https://dashscope.aliyuncs.com/compatible-mode/v1 を使用します。
baseURL: "https://dashscope-intl.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" },
});
// ストリームをスピーカーへリアルタイム再生
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("再生完了"));
speaker.end();課金
音声
入力または出力音声の 1 秒あたり 12.5 トークンが課金されます。1 秒未満の音声は、1 秒分として課金されます。
動画
動画のトークン消費には、以下の 2 つの構成要素があります:
音声トークン: 音声の 1 秒あたり 12.5 トークン。1 秒未満の音声は、1 秒分として課金されます。
動画トークン: フレーム数および解像度に基づいて計算されます。計算式は以下のとおりです:
video_tokens = ceil(frame_count / 2) x (height / 32) x (width / 32) + 2場所:
フレームは 2 FPS でサンプリングされ、範囲 [4, 128] に制限されます。
高さおよび幅は 32 ピクセルの倍数に調整され、総ピクセル数の上限内に収まるよう動的にスケーリングされます。
動画トークンを計算する Python スクリプト
# インストール: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" # ご自身の動画パスに置き換えてください
video_token = video_token_calculate(video_path)
print("video_tokens:", video_token)トークン単価については、「モデル一覧」をご参照ください。
モデルの詳細
| モデル | バージョン | コンテキストウィンドウ | 最大入力 | 最大出力 |
|---|---|---|---|---|
| qwen3-livetranslate-flash | Stable | 53,248 トークン | 49,152 トークン | 4,096 トークン |
| qwen3-livetranslate-flash-2025-12-01 | Snapshot | 53,248 トークン | 49,152 トークン | 4,096 トークン |
qwen3-livetranslate-flash は、現在 qwen3-livetranslate-flash-2025-12-01 と同等の機能を持ちます。
サポートされる言語
以下の言語コードを source_lang および target_lang として使用できます。一部のターゲット言語ではテキスト出力のみがサポートされています。
| 言語コード | 言語 | サポートされる出力 |
|---|---|---|
| en | 英語 | 音声、テキスト |
| zh | 中国語 | 音声、テキスト |
| ru | ロシア語 | 音声、テキスト |
| fr | フランス語 | 音声、テキスト |
| de | ドイツ語 | 音声、テキスト |
| pt | ポルトガル語 | 音声、テキスト |
| es | スペイン語 | 音声、テキスト |
| it | イタリア語 | 音声、テキスト |
| id | インドネシア語 | テキスト |
| ko | 韓国語 | 音声、テキスト |
| ja | 日本語 | 音声、テキスト |
| vi | ベトナム語 | テキスト |
| th | タイ語 | テキスト |
| ar | アラビア語 | テキスト |
| yue | 広東語 | 音声、テキスト |
| hi | ヒンディー語 | テキスト |
| el | ギリシャ語 | テキスト |
| tr | トルコ語 | テキスト |
サポートされるボイス
出力に合成音声が含まれる場合、voice パラメーターを audio 内で指定します。
| ボイス名 | voice パラメーター | 説明 | サポートされる言語 |
|---|---|---|---|
| Cherry | Cherry | 明るく、フレンドリーで、誠実な若い女性。 | 中国語、英語、フランス語、ドイツ語、ロシア語、イタリア語、スペイン語、ポルトガル語、日本語、韓国語 |
| Nofish | Nofish | 巻き舌音の発音が苦手なデザイナー。 | 中国語、英語、フランス語、ドイツ語、ロシア語、イタリア語、スペイン語、ポルトガル語、日本語、韓国語 |
| Shanghai-Jada | Jada | 活気がありエネルギッシュな上海の女性。 | 中国語 |
| Beijing-Dylan | Dylan | 北京の胡同で育った若い男性。 | 中国語 |
| Sichuan-Sunny | Sunny | 四川出身の愛らしい女の子。 | 中国語 |
| Tianjin-Peter | Peter | 天津相声の演者風の声(ツッコミ役) | 中国語 |
| Cantonese-Kiki | Kiki | 香港から来た優しい親友。 | 広東語 |
| Sichuan-Eric | Eric | 四川成都出身で、個性的で目立つ存在感を持つ男性。 | 中国語 |
よくある質問
動画ファイルを入力した場合、どのようなコンテンツが翻訳されますか?
モデルは動画の音声トラックを翻訳します。視覚的情報は、翻訳精度を向上させるための文脈として活用されます。
たとえば、音声で「This is a mask」と発話された場合:
動画に医療用マスクが映っているときは、「This is a medical mask」と翻訳されます。
ビデオにマスカレードマスクが表示されると、モデルは「これはマスカレードマスクです。」と翻訳します。
API リファレンス
入力および出力パラメーターの詳細については、「音声および動画の翻訳 – Qwen」をご参照ください。