Communitygithub.com

renky1025/agent-skills

Local video dubbing pipeline: extract 16kHz → ASR → AI translate → segmented TTS → mux → hardsub burn. Timestamp-locked sync.

agent-skills 是什麼?

agent-skills is a Claude Code agent skill that local video dubbing pipeline: extract 16kHz → ASR → AI translate → segmented TTS → mux → hardsub burn. Timestamp-locked sync.

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/renky1025/agent-skills/tree/main/video-dubbing

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

video-dubbing: 视频翻译配音与字幕同步

Purpose

把一段视频整体本地化为另一种语言:识别原语音、翻译、用 TTS 生成目标语言配音,在保持原始 时间戳的前提下合成音轨并把译文硬字幕烧进画面。产出是可直接发布的单文件视频,配音与字幕 天然同步,不需要二次对轴。

When to Use

  • 用户要求把视频翻译成另一种语言,并要配音(不只是字幕)。
  • 需要给视频加目标语言配音 + 同步字幕(双语或纯译文)。
  • 触发词:视频翻译、视频配音、翻译字幕、生成外语配音、双语字幕、dub a video、translate a video、 foreign-language voiceover。
  • 任何 ASR -> 翻译 -> TTS -> 视频合成的工作流。

When NOT to Use

  • 只需转录、不需要翻译或配音 -> 交给 video-minutes 或直接 whisper。
  • 只需把文字合成为音频、不涉及视频 -> 交给 mlx-tts。
  • 需要保留原背景音乐/音效并做专业混音(人声分离)-> 本技能默认不做 Demucs,需另行处理。
  • 视频无音轨或音质极差到无法识别。

Workflow

端到端推荐直接用编排脚本 <skill>/scripts/dub.py(见 ## Scripts),它会依次执行下面各步并 在翻译处暂停等待 AI 翻译。手动执行时按以下步骤:

  1. 抽音轨(16kHz 单声道): ffmpeg -y -i input.mp4 -ar 16000 -ac 1 -c:a pcm_s16le audio16k.wav

  2. ASR 转录(要逐段准确时间戳): whisper audio16k.wav --model large-v3-turbo --language <源语言> --output_format srt --output_dir . 产出 audio16k.srt,时间戳与原视频天然对齐。想要更好的中文识别可改装 Qwen3-ASR (pip install qwen-asr)并用 <skill>/scripts/qwen3_asr.py。

  3. 翻译字幕(由 AI 完成):读 SRT,逐段翻译。每个 SRT 段输出一行译文,严格保持顺序。 先数清段数(如 27 段 -> 27 行),存为 translated.txt,继续前核对行数一致。

  4. 生成配音: python3 <skill>/scripts/dub_segments.py audio16k.srt translated.txt dubbing.wav subtitle_synced.srt --lang <目标语言> 脚本会:用首段作音色参考保证音色一致;保留原始时间戳让字幕与画面同步;只对溢出槽位 的段做变速(atempo 0.88–1.20);把相邻小于 1s 的间隔桥接起来让听感自然。

  5. 合并配音音轨到视频:

    ffmpeg -y -i input.mp4 -i dubbing.wav \
      -map 0:v:0 -map 1:a:0 \
      -c:v copy -c:a aac -b:a 192k -shortest output_temp.mp4
    

    然后确认音轨已被替换: ffprobe -v error -show_entries stream=codec_type -of csv=p=0 output_temp.mp4(应显示 video, audio)。

  6. 烧录硬字幕: python3 <skill>/scripts/burn_subtitles.py output_temp.mp4 subtitle_synced.srt output_final.mp4 把译文字幕永久渲染进画面。

  7. 清理(可选):删除 audio16k.wav、audio16k.srt、translated.txt、dubbing.wav、 subtitle_synced.srt、output_temp.mp4 等中间产物。

Decision Rules

  • 想一键跑完 -> 用 dub.py;只想重跑某一步(如已有 SRT)-> 用 dub.py --srt existing.srt 跳步。
  • ASR 引擎:默认 --asr whisper(large-v3-turbo);中文识别要求高 -> --asr qwen3。
  • 不需要硬字幕 -> dub.py --no-burn(只到音轨合并)。
  • 目标语言由 --target-lang 决定(默认 zh);dub_segments.py 的 TTS 语言由 --lang 决定。
  • 翻译必须由 AI 完成且与 SRT 段严格 1:1;行数不符时脚本直接报错退出,不要绕过。
  • 字幕没出现/中文变方框 -> 用 burn_subtitles.py(moviepy 渲染,自动找中文字体),不要依赖 ffmpeg 的 subtitles=(libass 缺失时会静默失败)。
  • 配音时长溢出槽位 -> 依赖脚本的分段 atempo,不要对整条音轨做全局变速。

Constraints

  • 时间戳必须复用 ASR 原始结果,禁止对配音重新 ASR 取时间。
  • 译文行数必须等于 SRT 段数(1:1),否则中止。
  • 合并音轨必须显式 -map 0:v:0 -map 1:a:0,否则会保留原音轨。
  • ASR 必须用 large-v3-turbo(或 turbo),不要退回 base/tiny。
  • 变速只在段级别进行,范围 0.88–1.20x;禁止全局 atempo。
  • 默认不做背景音乐人声分离;用户要求时应显式说明需要额外处理。

Verification

交付前逐项确认:

  • translated.txt 行数与 SRT 段数完全一致。
  • dubbing.wav 与 subtitle_synced.srt 均已生成。
  • ffprobe 显示最终视频同时含 video 与 audio 流,且音频确实被替换。
  • 字幕已硬烧进画面(不是外部软字幕),中文无方框。
  • 配音与画面在若干随机点抽查时间戳对齐。
  • 未删除用户提供的源文件。

Output

  • Outcome:一个本地化后的视频文件(默认 output_final.mp4,dub.py 下为 <视频名>_<目标语言>.mp4),含目标语言配音与硬字幕;另可保留 subtitle_synced.srt。
  • Done when:音轨已替换、字幕已烧录、音画在抽查点同步、ffprobe 校验通过。
  • Evidence:最终文件路径;SRT 段数与译文行数;ffprobe 的流清单;抽查的同步时间点。

References

按需加载,不要预先全读:

  • references/pipeline-design.md — 需要解释或调整流水线行为(为何保留时间戳、分段变速、 默认不做人声分离、产物与依赖清单)时读。
  • references/troubleshooting.md — 实际报错、音画不同步、字幕没出现或中文变方框时读。

Scripts

  • <skill>/scripts/dub.py — 端到端编排。用法 python3 <skill>/scripts/dub.py input.mp4 --source-lang en --target-lang zh [--asr whisper|qwen3] [--srt existing.srt] [-o out.mp4] [--font-size 28] [--no-burn] [--keep-temp]。 运行到翻译步时会生成 to_translate.txt 并要求 AI 翻译成 translated.txt,然后重跑继续; 返回最终视频路径与字幕路径。
  • <skill>/scripts/dub_segments.py — 分段 TTS 配音 + 时间戳对齐。用法 python3 <skill>/scripts/dub_segments.py original.srt translated.txt out_dub.wav out_synced.srt [--lang zh] [--min-atempo 0.88] [--max-atempo 1.20] [--gap-bridge 1.0] [--keep-temp]。 返回对齐后的 dubbing.wav 与 subtitle_synced.srt;译文行数不匹配时以退出码 1 中止。
  • <skill>/scripts/burn_subtitles.py — 用 moviepy 烧录硬字幕。用法 python3 <skill>/scripts/burn_subtitles.py input.mp4 subtitles.srt output.mp4 [--font <path>] [--font-size 28]。 返回烧好字幕的视频;--font 缺省时自动探测中文字体。
  • <skill>/scripts/qwen3_asr.py — whisper 兼容的 Qwen3-ASR CLI,中文识别更佳。用法 python3 <skill>/scripts/qwen3_asr.py audio.wav [--model 0.6B|1.7B] [--language zh] [-f srt|vtt|txt|json|tsv|all] [-o 输出目录] [--device cuda:0|mps|cpu] [--dtype float16|bfloat16|float32]。 返回指定格式的字幕/文本文件。模型别名:turbo/tiny/base/small -> Qwen3-ASR-0.6B, medium/large -> Qwen3-ASR-1.7B。

Troubleshooting

  • 配音没被替换 / 还是原声 -> 合并 ffmpeg 时漏了 -map 0:v:0 -map 1:a:0。
  • 字幕没出现或中文方框 -> 改用 burn_subtitles.py,并用 --font 指定中文字体。
  • 译文行数与 SRT 段数不符 -> 脚本会报错退出,先补齐到 1:1。
  • 完整错误清单见 references/troubleshooting.md。

Related Skills

  • mlx-tts — 提供底层 mlx_audio.tts.generate,本技能的配音节依赖它。
  • video-minutes — 视频转结构化纪要;只需转录/总结时改用它。

相關技能