agentsclimarketplace

Video dubbing

Skill renky1025/agent-skills/video-dubbing

a kinds of skills can run in any agents, totally free.

Install
npx -y skills add renky1025/agent-skills --skill video-dubbing

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Translate video/audio content into another language with dubbed voice and synchronized subtitles. Use this skill whenever the user asks to: translate a video, dub a video, generate foreign-language voiceover for a video, add translated subtitles with dubbed audio, or any workflow involving ASR → translate → TTS → video composition.

SKILL.md

5.6 KB, as published. Nobody here has run it

Video Dubbing & Subtitle Sync

Complete workflow: ASR → translate → TTS → merge audio → burn subtitles

Pipeline

视频 → 抽音轨(16kHz) → ASR(whisper) → AI翻译 → TTS(dub_segments) → 合并音轨 → 烧录硬字幕

Workflow

0. Prerequisite Check

Ensure whisper + moviepy + mlx-audio are installed:

pip install openai-whisper moviepy 2>/dev/null
# mlx_audio for TTS:
pip install mlx-audio 2>/dev/null  # Apple Silicon

1. Extract Audio & Transcribe (ASR)

Extract 16kHz mono audio, then run whisper for accurate per-segment timestamps:

ffmpeg -y -i input.mp4 -ar 16000 -ac 1 -c:a pcm_s16le audio16k.wav

whisper audio16k.wav \
  --model large-v3-turbo \
  --language <source_lang> \
  --output_format srt \
  --output_dir .

Output: audio16k.srt with native timestamps matching the video.

Use large-v3-turbo for best accuracy. If you want even better Chinese recognition, install Qwen3-ASR (pip install qwen-asr) and use scripts/qwen3_asr.py instead.

2. Translate Subtitles (AI does this)

Read the SRT, translate each segment's text into the target language. Output one line per SRT segment, preserving order exactly.

  • Count SRT segments first (e.g. 27 segments → 27 translated lines)
  • Save as translated.txt in the working directory
  • Verify line count matches SRT segment count before proceeding

3. Generate Dubbed Audio

python3 scripts/dub_segments.py audio16k.srt translated.txt dubbing.wav subtitle_synced.srt --lang <target_lang>

What it does:

  • Generates TTS per segment with voice consistency (first segment = voice reference)
  • Preserves original timestamps — subtitles stay synced with video
  • Smart speed adjustment: only adjusts segments that overflow their slot (atempo 0.88–1.20)
  • Bridges adjacent gaps <1s for natural flow

4. Merge Dubbed Audio into Video

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

Verify audio replaced:

ffprobe -v error -show_entries stream=codec_type -of csv=p=0 output_temp.mp4
# Should show: video, audio

5. Burn Hard Subtitles into Video

python3 scripts/burn_subtitles.py output_temp.mp4 subtitle_synced.srt output_final.mp4

This renders translated subtitles permanently into the video frame (hardcoded).

6. Cleanup (Optional)

rm -f audio16k.wav audio16k.srt translated.txt dubbing.wav subtitle_synced.srt output_temp.mp4

Output Files

FileDescription
output_final.mp4Final video with dubbed audio + hardcoded subtitles
subtitle_synced.srtSynced subtitles (original timestamps + translated text)
dubbing.wavPer-segment aligned dubbing track

Key Design Decisions

PrincipleWhy
Preserve original ASR timestampsThey match the video's visual cues natively. Re-ASR on dubbing drifts.
Per-segment speed adjustment (0.88–1.20x)Global atempo on the whole dubbing sounds robotic. Per-segment is natural.
Hard subtitles (burned in)Soft subtitles don't work on all platforms. Burn them so they always show.
16kHz mono for ASRWhisper expects this. Higher sample rate wastes compute without improving accuracy.
Voice consistency via first segment referencemlx-tts supports --ref_audio. First segment sets the voice for all others.
No Demucs by defaultFor typical narration/speech videos, background music removal is unnecessary overhead.
large-v3-turbo modelBest accuracy/speed tradeoff. Significantly better than base for proper nouns and fast speech.

Dependencies

ComponentInstallPurpose
ffmpegbrew install ffmpegAudio extraction, merging
openai-whisperpip install openai-whisperSpeech-to-text (ASR)
moviepypip install moviepyBurn subtitles into video
mlx-audiopip install mlx-audioTTS on Apple Silicon
qwen-asrpip install qwen-asr (optional)Better Chinese ASR

Common Mistakes to Avoid

MistakeWhy It FailsCorrect Approach
ffmpeg without -mapPicks original audio (video source's audio stream), dubbing ignoredAlways use -map 0:v:0 -map 1:a:0
Global atempo on entire dubbingAll speech slows uniformly (EN→ZH ~0.8x), sounds roboticPer-segment alignment (dub_segments.py)
Re-ASR on dubbed audio for timestampsTimestamps drift from visual cuesReuse original Step 1 timestamps
Translation line count ≠ SRT segmentsdub_segments.py requires strict 1:1 mappingCount SRT segments first, match exactly
Use whisper base/tiny modelProper nouns wrong, fast speech missedUse large-v3-turbo or turbo
Burn subtitles without checking FFmpeg libasssubtitles= filter silently failsUse scripts/burn_subtitles.py (moviepy)
Translate segments out of orderSubtitles play at wrong timesKeep segment order: 1 translated line per SRT segment
Skip verificationAudio may not have been replacedRun ffprobe to check both audio + video streams exist

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.