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

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

最終更新日:Jul 09, 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 配列には、roleuser に設定されたメッセージを 1 つだけ含めてください。content フィールドには、翻訳する音声または動画を指定します。

  • 音声typeinput_audio に設定します。input_audio.data にファイルの URL または Base64 エンコードされたデータを指定し、input_audio.format にフォーマット (例:wav) を指定します。

  • 動画typevideo_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 をインストールします。

プラットフォーム インストール
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"),
    # 次の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

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

プラットフォーム インストール
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,
    // 次の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 ピクセルの倍数に調整され、総ピクセル数の上限内に収まるように動的にスケーリングされます。

動画トークンを計算する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 スナップショット 53,248 トークン 49,152 トークン 4,096 トークン
現在、qwen3-livetranslate-flash は qwen3-livetranslate-flash-2025-12-01 と同じ機能を備えています。

サポートされている言語

これらの言語コードを source_langtarget_lang に使用します。一部のターゲット言語はテキスト出力のみをサポートします。

言語コード 言語 サポートされている出力
en 英語 音声、テキスト
zh 中国語 音声、テキスト
ru ロシア語 音声、テキスト
fr フランス語 音声、テキスト
de ドイツ語 音声、テキスト
pt ポルトガル語 音声、テキスト
es スペイン語 音声、テキスト
it イタリア語 音声、テキスト
id インドネシア語 テキスト
ko 韓国語 音声、テキスト
ja 日本語 音声、テキスト
vi ベトナム語 テキスト
th タイ語 テキスト
ar アラビア語 テキスト
yue 広東語 音声、テキスト
hi ヒンディー語 テキスト
el ギリシャ語 テキスト
tr トルコ語 テキスト

サポートされている音声

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

音声名 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.」と翻訳します。

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

API リファレンス

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