一、背景

YouTube 视频翻译中文,本质上是将外语视频通过语音识别(ASR)、文本翻译(NMT)、语音合成(TTS)三个环节处理后,重新合成为中文版本。每一个环节都有成熟的开源工具链支持,按正确的流程串联起来,就能搭建一条可复用的自动化流水线。

本文以一段 10 分钟的英文教程视频为例,用 Python 脚本和命令行工具完整走通四个阶段:音频提取 → 语音转文字 → 字幕翻译 → 配音合成。文末会讨论几个实践中容易踩坑的技术细节。

二、整体流程

一条完整的视频翻译流水线由以下四个模块串联:

原始视频.mp4
    │
    ▼
[1] 音频分离 (FFmpeg) ──→ audio.wav
    │
    ▼
[2] 语音识别 (Whisper) ──→ original.srt(原文时间轴字幕)
    │
    ▼
[3] 文本翻译 (DeepL / GPT) ──→ chinese.srt(中文时间轴字幕)
    │
    ▼
[4] 语音合成 (Edge-TTS / ElevenLabs) ──→ dub.mp3
    │
    ▼
[5] 视频合成 (FFmpeg) ──→ output_chinese.mp4

每个模块的输出都是下一个模块的输入,中间产物(SRT 字幕、WAV 音频)都可以单独检查和修正,不需要因为某一步出错就从头重跑。

三、Step 1:音频分离

先将视频中的音轨提取为 16kHz 单声道 WAV,这是 Whisper 模型要求的输入格式。

ffmpeg -i input.mp4 -vn -acodec pcm_s16le -ar 16000 -ac 1 audio.wav

参数说明:

  • -vn:丢弃视频流,只保留音频
  • -acodec pcm_s16le:输出未压缩 PCM,避免二次有损编码
  • -ar 16000 -ac 1:16kHz 采样率 + 单声道,Whisper 内部会重采样,但提前做好可以减少文件体积

如果原视频音轨是多声道的(常见于访谈类内容),建议先 downmix 到单声道再处理,否则 Whisper 的识别准确率会下降。

四、Step 2:语音识别(ASR)

使用 OpenAI Whisper 将音频转为带时间戳的文本。Whisper 是目前开源领域综合表现最好的 ASR 模型,支持 99 种语言,中文识别准确率在 large-v3 模型下可达 95% 以上。

4.1 安装

pip install openai-whisper

Whisper 依赖 FFmpeg,需确保系统已安装(macOS: brew install ffmpeg,Linux: apt install ffmpeg)。

4.2 转写脚本

import whisper
import sys

model = whisper.load_model("large-v3")  # 首次运行会下载模型(~3GB)
result = model.transcribe(
    "audio.wav",
    language="en",          # 指定源语言可提升准确率
    task="transcribe",      # transcribe=原文, translate=直接译成英文
    verbose=True
)

# 打印转写结果
for segment in result["segments"]:
    start = segment["start"]
    end = segment["end"]
    text = segment["text"].strip()
    print(f"[{start:.2f}s - {end:.2f}s] {text}")

4.3 导出 SRT 字幕

def format_timestamp(seconds):
    """将秒数转为 SRT 时间戳格式 HH:MM:SS,mmm"""
    h = int(seconds // 3600)
    m = int((seconds % 3600) // 60)
    s = int(seconds % 60)
    ms = int((seconds % 1) * 1000)
    return f"{h:02}:{m:02}:{s:02},{ms:03}"

with open("original.srt", "w", encoding="utf-8") as f:
    for i, seg in enumerate(result["segments"], 1):
        start = format_timestamp(seg["start"])
        end = format_timestamp(seg["end"])
        f.write(f"{i}\n{start} --> {end}\n{seg['text'].strip()}\n\n")

print(f"导出完成,共 {len(result['segments'])} 条字幕")

4.4 模型选型

模型 参数量 显存需求 英文准确率 多语言准确率 适用场景
tiny 39M ~1GB ~85% ~70% 快速测试
base 74M ~1GB ~90% ~78% 简单英文内容
small 244M ~2GB ~93% ~83% 日常使用
medium 769M ~5GB ~95% ~88% 专业内容
large-v3 1.55B ~10GB ~97% ~93% 生产环境

如果本地没有 GPU,可以使用 medium 模型跑 CPU(10 分钟音频约 15-20 分钟处理时间),或者使用 Google Colab 的免费 T4 GPU 跑 large-v3。

五、Step 3:字幕翻译

拿到原文 SRT 字幕后,需要翻译成中文。翻译引擎的选择直接影响最终质量——逐句翻译容易丢失上下文,导致同一术语在不同位置被翻译成不同的词。

5.1 解析 SRT 文件

import re

def parse_srt(filepath):
    """解析 SRT 文件,返回字幕列表"""
    with open(filepath, "r", encoding="utf-8") as f:
        content = f.read()

    pattern = re.compile(
        r"(\d+)\n(\d{2}:\d{2}:\d{2},\d{3}) --> (\d{2}:\d{2}:\d{2},\d{3})\n(.*?)\n\n",
        re.DOTALL
    )

    subtitles = []
    for match in pattern.finditer(content):
        subtitles.append({
            "index": int(match.group(1)),
            "start": match.group(2),
            "end": match.group(3),
            "text": match.group(4).replace("\n", " ").strip()
        })
    return subtitles

5.2 使用 DeepL API 翻译

import deepl
import time

translator = deepl.Translator("YOUR_DEEPL_API_KEY")
subtitles = parse_srt("original.srt")

with open("chinese.srt", "w", encoding="utf-8") as f:
    for sub in subtitles:
        result = translator.translate_text(
            sub["text"],
            source_lang="EN",
            target_lang="ZH"
        )
        f.write(f"{sub['index']}\n{sub['start']} --> {sub['end']}\n{result.text}\n\n")
        time.sleep(0.1)  # DeepL 免费 API 限速

print("翻译完成")

5.3 使用 OpenAI GPT-4o 翻译(带上下文)

对于术语较多的技术类视频,用 GPT-4o 配合上下文窗口翻译效果更好。做法是将连续 5-10 条字幕打包成一次请求,让模型看到前后文:

from openai import OpenAI

client = OpenAI(api_key="YOUR_API_KEY")

def translate_batch(subtitle_batch):
    """将多条字幕合并为一次翻译请求"""
    texts = [s["text"] for s in subtitle_batch]
    joined = "\n---\n".join(texts)

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[{
            "role": "system",
            "content": (
                "将以下英文视频字幕翻译为简体中文。要求:"
                "1. 保持口语化,适合配音朗读;"
                "2. 用分隔符 '---' 保持原文分段;"
                "3. 专业术语翻译保持一致;"
                "4. 中文每句不超过25字(配音时长限制)"
            )
        }, {
            "role": "user",
            "content": joined
        }],
        temperature=0.3
    )

    translated = response.choices[0].message.content.split("\n---\n")
    return [t.strip() for t in translated]

5.4 在中文字幕中保留时间轴

翻译完成后,中文文本可能比原文长或短。SRT 格式中每条字幕的建议显示时长为 1-6 秒、每行不超过 40 个字符。如果某条中文字幕过长,可以手动拆分成两条;如果过短(如原文为 “OK”),可以和相邻字幕合并:

def adjust_timeline(subtitles, max_chars_per_line=25):
    """对于过长的中文字幕,自动拆分并调整时间轴"""
    adjusted = []
    for sub in subtitles:
        text = sub["text"]
        if len(text) <= max_chars_per_line:
            adjusted.append(sub)
            continue

        # 按标点拆分
        parts = re.split(r"([,。!?,.!?])", text)
        mid = len(text) // 2
        # 简化处理:过长句子对半拆分
        half_duration = (time_to_seconds(sub["end"]) - time_to_seconds(sub["start"])) / 2
        mid_time = time_to_seconds(sub["start"]) + half_duration

        adjusted.append({
            "index": len(adjusted) + 1,
            "start": sub["start"],
            "end": format_timestamp(mid_time),
            "text": text[:mid]
        })
        adjusted.append({
            "index": len(adjusted) + 1,
            "start": format_timestamp(mid_time),
            "end": sub["end"],
            "text": text[mid:]
        })
    return adjusted

六、Step 4:语音合成(TTS)

有了中文字幕文本后,将其送入 TTS 引擎生成配音。以下是两种方案。

6.1 方案 A:Edge-TTS(免费,适合原型验证)

微软 Edge 浏览器内置的 TTS 引擎有免费的 Python 接口,中文语音自然度不错:

pip install edge-tts
import asyncio
import edge_tts

async def generate_dub():
    # 从 SRT 中提取纯文本
    subtitles = parse_srt("chinese.srt")
    full_text = " ".join([s["text"] for s in subtitles])

    communicate = edge_tts.Communicate(
        full_text,
        voice="zh-CN-XiaoxiaoNeural"  # 女声,还有其他音色可选
    )
    await communicate.save("dub.mp3")

asyncio.run(generate_dub())

常用中文音色:zh-CN-XiaoxiaoNeural(女声-活泼)、zh-CN-YunxiNeural(男声-沉稳)、zh-CN-XiaoyiNeural(女声-温柔)。Edge-TTS 的缺点是单次最长 10 分钟文本,超过需要分段。

6.2 方案 B:ElevenLabs(付费,质量更高)

如果需要更自然的语调和情感表达,ElevenLabs 的多语言模型效果更好:

from elevenlabs import generate, save, set_api_key

set_api_key("YOUR_API_KEY")

subtitles = parse_srt("chinese.srt")
full_text = " ".join([s["text"] for s in subtitles])

audio = generate(
    text=full_text,
    voice="Chris",
    model="eleven_multilingual_v2"
)
save(audio, "dub.mp3")

对于非实时需求,也可以将文本按段落拆分后逐段生成,再拼接——分段生成可以更好地控制每个段落的语调和节奏。

七、Step 5:视频合成

最后一步:用 FFmpeg 将原始视频画面、中文配音、中文字幕合成为最终视频。

7.1 替换音轨

ffmpeg -i input.mp4 -i dub.mp3 \
  -c:v copy -c:a aac -b:a 192k \
  -map 0:v:0 -map 1:a:0 \
  -shortest output.mp4

7.2 嵌入硬字幕

如果目标平台(抖音、小红书等)不支持外挂字幕,需要将字幕烧录到视频画面中:

ffmpeg -i output.mp4 -vf \
  "subtitles=chinese.srt:force_style='FontName=Microsoft YaHei,FontSize=20,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,Outline=1,Shadow=1,MarginV=30'" \
  -c:a copy final_output.mp4

force_style 中几个关键参数:

  • FontSize=20:1080p 视频建议 18-24,720p 建议 14-18
  • MarginV=30:字幕距底部距离,避免被播放器进度条遮挡
  • Outline=1:文字描边,确保浅色画面下字幕可读

7.3 批量处理脚本

将以上全部流程整合为一个脚本,放入 input/ 目录的视频会被自动处理:

#!/bin/bash
# batch_translate.sh — 批量视频翻译脚本

INPUT_DIR="./input"
OUTPUT_DIR="./output"

mkdir -p "$OUTPUT_DIR"

for video in "$INPUT_DIR"/*.mp4; do
    filename=$(basename "$video" .mp4)
    echo "处理: $filename"

    # Step 1: 提取音频
    ffmpeg -y -i "$video" -vn -acodec pcm_s16le -ar 16000 -ac 1 temp_audio.wav

    # Step 2: ASR
    python transcribe.py temp_audio.wav "$filename"

    # Step 3: 翻译
    python translate.py "${filename}.srt"

    # Step 4: TTS
    python synthesize.py "${filename}_chinese.srt"

    # Step 5: 合成
    ffmpeg -y -i "$video" -i "${filename}_dub.mp3" \
      -c:v copy -c:a aac -b:a 192k -map 0:v:0 -map 1:a:0 -shortest \
      "$OUTPUT_DIR/${filename}_chinese.mp4"

    echo "完成: ${filename}_chinese.mp4"
done

# 清理临时文件
rm -f temp_audio.wav

八、实践中的技术问题

8.1 中英文时长不匹配

英文翻译成中文后,文本长度通常会缩短 20-30%(因为中文信息密度更高)。这会导致配音时长短于原视频,出现"话说完了画面还在播"的情况。

两个解决思路:

  • 在翻译阶段扩充:以上文 GPT-4o prompt 中的"中文每句不超过 25 字"为例,可以适当放宽到 30 字,让模型在保持语义的前提下增加自然的语气词和过渡表达
  • 在合成阶段拉伸:FFmpeg 的 atempo 滤镜可以微调音频速度,atempo=0.9 将语速放慢 10%,能让中文配音更从容。不过 atempo 范围仅 0.5-2.0,超出需要用链式滤镜
# 将配音速度放慢 10%
ffmpeg -i dub.mp3 -filter:a "atempo=0.9" dub_slower.mp3

8.2 数字和时间格式的本地化

英文中的 “1,000 dollars” → 中文应为 “1000 美元”,“5:30 PM” → “下午 5 点 30 分”。翻译 API 通常不会自动处理这些转换,需要在翻译后处理时手动替换。

一个简单的正则后处理:

import re

def localize_chinese_text(text):
    """将英文数字格式转为中文习惯"""
    # $100 → 100 美元
    text = re.sub(r'\$(\d+(?:\.\d+)?)', r'\1 美元', text)
    # 1,000 → 1000
    text = re.sub(r'(\d+),(\d{3})', r'\1\2', text)
    # °F → 华氏度
    text = text.replace('°F', ' 华氏度')
    return text

8.3 长视频的分段处理

超过 30 分钟的讲座类视频,一次性送入 Whisper 可能触发显存不足或 API 超时。建议先用 FFmpeg 按静音区间切分为 5-10 分钟的片段:

# 按静音检测切分(静音超过 2 秒处切割)
ffmpeg -i long_video.mp4 -c copy -map 0 \
  -segment_time 600 \
  -f segment \
  -reset_timestamps 1 \
  chunk_%03d.mp4

每个分段独立处理后,将各段的 SRT 时间轴加上段偏移量再合并。

8.4 视频中的背景音效处理

Whisper 对带背景音乐的视频识别效果较差。如果原视频有 BGM,可以先用 Demucs 或 spleeter 分离人声和背景音:

pip install demucs
python -m demucs --two-stems=vocals audio.wav

分离后的 vocals.wav 送入 Whisper,识别准确率有明显提升。合成最终视频时,将原始 BGM 以较低音量混入中文配音,保留原片的氛围感。

九、是否需要自己搭建?

上述流水线适合以下场景:

  • 需要完全控制每个环节的参数和质量
  • 处理的视频量大,自己搭建比按次付费更划算
  • 对翻译质量有定制化要求(比如需要指定术语表)

如果只是偶尔处理一两条视频,或者不太想维护这套脚本,市面上也有一些集成了上述流程的商业平台——比如 Cutrix、Rask.ai、Vozo 等,上传视频后自动完成 ASR → 翻译 → TTS → 合成全流程,省去了搭建和维护成本。选择自行搭建还是用现成方案,取决于你的处理量和定制化需求。


参考资料


本文代码基于 Whisper large-v3、DeepL API v2、FFmpeg 7.0 版本编写,2026 年 5 月测试通过。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐