すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Model Studio:音声・動画ファイルの翻訳 - Qwen

最終更新日:Aug 26, 2026

qwen3-livetranslate-flash は、18 言語間の音声ファイルと動画ファイルを翻訳します。音声または動画を入力として受け取り、翻訳されたテキスト、合成音声、またはその両方をストリーミング API 経由で返します。動画入力の場合、視覚的コンテキストによって翻訳の精度が向上します (例:ビデオフレームに基づいて「医療用マスク」と「仮面舞踏会のマスク」を区別するなど)。

始める前に

  1. API キーを作成します。
  2. API キーを環境変数として設定します。
  3. (オプション) OpenAI SDK を使用する場合は、SDK をインストールします。

クイックスタート

すべての例では、OpenAI 互換のストリーミング API を使用します。ソース言語とターゲット言語は translation_options で設定します。デフォルトの入力は音声です。動画ファイルを翻訳する場合は、各例の動画入力ブロックのコメントを解除してください。

source_lang を指定すると精度が向上します。これを省略すると、自動言語検出が有効になります。

import os
from openai import OpenAI

client = OpenAI(
    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},
    # 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,
    // 次の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 は標準の OpenAI パラメーターではないため、extraBody を介して渡します
        extraBody: { 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"
    }
}'

これらの例では、公開ファイルの URL を使用しています。ローカルファイルを使用する場合は、「Base64 エンコードされたローカルファイルの入力」をご参照ください。

リクエストパラメーター

入力

messages 配列には、role が user に設定されたメッセージを 1 つだけ含めてください。content フィールドには、翻訳する音声または動画を指定します。

  • 音声:type を input_audio に設定します。input_audio.data にファイルの URL または Base64 エンコードされたデータを指定し、input_audio.format にフォーマット (例:wav) を指定します。
  • 動画: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 つの翻訳を処理します。マルチターン対話はサポートされていません。
  • システムメッセージなし:system ロールはサポートされていません。
  • ストリーミングのみ:OpenAI 互換のストリーミング出力のみがサポートされています。

レスポンスの解析

ストリーミングの各 chunk オブジェクトには、以下が含まれます。

  • テキスト:chunk.choices[0].delta.content
  • 音声:chunk.choices[0].delta.audio["data"] (Base64 エンコードされた、サンプリングレート 24kHz)

音声のファイルへの保存

ストリームからすべての 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"),
    # 次の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",
                },
            }
        ],
    }
]

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,
    // 次の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 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 は標準の OpenAI パラメーターではないため、extraBody を介して渡します
    extraBody: { 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(`音声が ${outputPath} に保存されました`);
}

saveAudio(audioString, "output.wav");

リアルタイム再生

各 Base64 フラグメントを到着時にデコードし、直接再生します。このアプローチには、プラットフォーム固有の音声ライブラリが必要です。

Python

最初に pyaudio をインストールします。

プラットフォームインストール
macOSbrew install portaudio && pip install pyaudio
Ubuntu / Debiansudo apt-get install python-pyaudio python3-pyaudio または pip install pyaudio
CentOSsudo yum install -y portaudio portaudio-devel && pip install pyaudio
Windowspython -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"),
    # 次の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",
                },
            }
        ],
    }
]

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

最初に依存関係をインストールします。

プラットフォームインストール
macOSbrew install portaudio && npm install speaker
Ubuntu / Debiansudo apt-get install libasound2-dev && npm install speaker
Windowsnpm install speaker
import OpenAI from "openai";
import Speaker from "speaker";

const client = new OpenAI({
    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 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 は標準の OpenAI パラメーターではないため、extraBody を介して渡します
    extraBody: { 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 ピクセルの倍数に調整され、総ピクセル数の上限内に収まるように動的にスケーリングされます。

Details

動画トークンを計算する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-flashStable53,248 トークン49,152 トークン4,096 トークン
qwen3-livetranslate-flash-2025-12-01スナップショット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トルコ語テキスト

サポートされている音声

出力に合成音声が含まれる場合は、audio の voice パラメーターで音声を設定します。

音声名voice パラメーター説明サポートされている言語
CherryCherry明るく、親しみやすく、誠実な若い女性。中国語、英語、フランス語、ドイツ語、ロシア語、イタリア語、スペイン語、ポルトガル語、日本語、韓国語
NofishNofishそり舌母音の発音が苦手なデザイナー。中国語、英語、フランス語、ドイツ語、ロシア語、イタリア語、スペイン語、ポルトガル語、日本語、韓国語
Shanghai-JadaJada賑やかでエネルギッシュな上海の女性。中国語
Beijing-DylanDylan北京の胡同で育った青年。中国語
Sichuan-SunnySunny四川省出身の可愛い女の子。中国語
Tianjin-PeterPeter天津の漫才師 (ツッコミ役) スタイルの音声。中国語
Cantonese-KikiKiki香港出身の可愛い親友。広東語
Sichuan-EricEric四川省成都市出身の、型にはまらず、群衆から際立つ男性。中国語

よくある質問

動画ファイルを入力した場合、どのコンテンツが翻訳されますか?

モデルは動画の音声トラックを翻訳します。視覚情報により、翻訳の精度が向上します。

例えば、音声が「This is a mask」の場合:

  • 動画に医療用マスクが映っている場合、モデルは「This is a medical mask.」と翻訳します。
  • 動画に仮面舞踏会のマスクが映っている場合、モデルは「This is a masquerade mask.」と翻訳します。

API リファレンス

すべての入力および出力パラメーターの詳細については、「音声・動画ファイルの翻訳 - Qwen」をご参照ください。