Communitygithub.com

renky1025/agent-skills

本地影片配音流程:抽取 16kHz 音頻 → ASR → AI 翻譯 → 分段 TTS → 合成 → 硬字幕燒錄。時間戳鎖定同步。

agent-skills 是什麼?

此技能提供一個完整的本地影片在地化流程:將輸入影片的原始語言語音轉換為目標語言的配音與硬字幕,並確保時間戳完全同步。它會先抽取出 16kHz 單聲道音軌,接著使用 Whisper 或 Qwen3-ASR 進行帶時間戳的語音辨識(ASR),再由 AI 逐段翻譯字幕。翻譯完成後,透過 `dub_segments.py` 腳本進行分段文字轉語音(TTS),並智慧調整每個段落的播放速度(0.88–1.20 倍速)以適應原始時間槽。最終,腳本會合併新的配音音軌並將翻譯後的字幕永久燒錄到影片畫面上,產生可直接發布的單一影片檔案。此技能支援一鍵執行的 `dub.py` 腳本,並提供多個獨立腳本供進階使用者分別執行各步驟。它不僅能生成配音,還能保留原始時間戳,確保字幕與配音與畫面精準對齊,省去手動對軸的麻煩,非常適合需要影片翻譯配音與同步字幕的場景。

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

在你喜歡的 AI 中提問

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

說明文件

video-dubbing: 影片翻譯配音與字幕同步

目的

把一段影片整體在地化為另一種語言:辨識原始語音、翻譯、用 TTS 生成目標語言配音,在保持原始時間戳的前提下合成音軌並將譯文硬字幕燒進畫面。產出是可直接發布的單檔影片,配音與字幕天然同步,不需要二次對軸。

使用時機

  • 用戶要求把影片翻譯成另一種語言,並要配音(不只是字幕)。
  • 需要給影片加目標語言配音 + 同步字幕(雙語或純譯文)。
  • 觸發詞:影片翻譯、影片配音、翻譯字幕、生成外語配音、雙語字幕、dub a video、translate a video、foreign-language voiceover。
  • 任何 ASR -> 翻譯 -> TTS -> 影片合成的工作流程。

不應使用時機

  • 只需轉錄、不需要翻譯或配音 -> 交給 video-minutes 或直接 whisper。
  • 只需把文字合成為音訊、不涉及影片 -> 交給 mlx-tts。
  • 需要保留原背景音樂/音效並做專業混音(人聲分離)-> 本技能預設不做 Demucs,需另行處理。
  • 影片無音軌或音質極差到無法辨識。

工作流程

端到端推薦直接用編排腳本 <skill>/scripts/dub.py(見 ## 腳本),它會依序執行下面各步並在翻譯處暫停等待 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);把相鄰小於 1 秒的間隔橋接起來讓聽感自然。

  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 等中間產物。

決策規則

  • 想一鍵跑完 -> 用 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,不要對整條音軌做全域變速。

限制條件

  • 時間戳必須複用 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。
  • 預設不做背景音樂人聲分離;用戶要求時應明確說明需要額外處理。

驗證

交付前逐項確認:

  • translated.txt 行數與 SRT 段落數完全一致。
  • dubbing.wav 與 subtitle_synced.srt 均已產生。
  • ffprobe 顯示最終影片同時含 video 與 audio 串流,且音訊確實被取代。
  • 字幕已硬燒進畫面(不是外部軟字幕),中文無方塊。
  • 配音與畫面在若干隨機點抽查時間戳對齊。
  • 未刪除用戶提供的原始檔案。

輸出

  • 成果:一個在地化後的影片檔案(預設 output_final.mp4,dub.py 下為 <影片名稱>_<目標語言>.mp4),含目標語言配音與硬字幕;另可保留 subtitle_synced.srt。
  • 完成條件:音軌已取代、字幕已燒錄、音畫在抽查點同步、ffprobe 校驗通過。
  • 證據:最終檔案路徑;SRT 段落數與譯文行數;ffprobe 的串流清單;抽查的同步時間點。

參考資料

按需載入,不要預先全讀:

  • references/pipeline-design.md — 需要解釋或調整流水線行為(為何保留時間戳、分段變速、預設不做人聲分離、產物與依賴清單)時讀。
  • references/troubleshooting.md — 實際報錯、音畫不同步、字幕沒出現或中文變方塊時讀。

腳本

  • <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 <路徑>] [--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。

疑難排解

  • 配音沒被取代 / 還是原聲 -> 合併 ffmpeg 時漏了 -map 0:v:0 -map 1:a:0。
  • 字幕沒出現或中文方塊 -> 改用 burn_subtitles.py,並用 --font 指定中文字型。
  • 譯文行數與 SRT 段落數不符 -> 腳本會報錯退出,先補齊到 1:1。
  • 完整錯誤清單見 references/troubleshooting.md。

相關技能

  • mlx-tts — 提供底層 mlx_audio.tts.generate,本技能的配音環節依賴它。
  • video-minutes — 影片轉結構化會議記錄;只需轉錄/總結時改用此技能。

相關技能