Burn subtitles into local video files. Supports SRT/VTT/ASS formats, auto-detect subtitles and language, bilingual subtitle merging and translation. Use when user needs to hardcode subtitles into video. Keywords: 字幕烧录、burn subtitles、本地视频、hardcode subtitles
Burn (hardcode) subtitle files into local video.
Scripts: All scripts are in
scripts/relative to this SKILL.md. CRITICAL: When running anybun scripts/...command, you MUST set the working directory (cwd) to this skill's base directory. Do NOT run from the user's project directory.
User explicit input > Project EXTEND.md > User EXTEND.md > Built-in defaults
- [ ] Step 0: Load preferences (EXTEND.md) ⛔ BLOCKING
- [ ] Step 1: Environment check (FFmpeg + libass + fonts)
- [ ] Step 2: Input files (video + subtitle + language detection)
- [ ] Step 3: Confirm mode (mono/bilingual/translate) ⚠️ skip if quick_mode=true
- [ ] Step 4: Preprocess (timeline fix, format convert, merge, translate)
- [ ] Step 5: Burn subtitles + watermark/source label
- [ ] Step 6: Output report
Input → [Step 0: Preferences] ─┬─ Found → Load summary → Continue
└─ Not found → First-time setup ⛔ → Save EXTEND.md → Continue
↓
[Step 1: Env Check] → FFmpeg + libass + fonts
↓
[Step 2: Input Files] → Video + subtitle scan + language detect + timeline offset check
↓
[Step 3: Confirm Mode] → Mono / Bilingual / Translate ⚠️ skippable
↓
[Step 4: Preprocess] ─┬─ Timeline fix (if offset)
├─ VTT → SRT convert (if merge/translate)
├─ Bilingual merge (if needed)
└─ Translate subtitle (if needed)
↓
[Step 5: Burn] ─┬─ Subtitle hardcode
├─ Watermark overlay (if enabled)
└─ Source label overlay (if enabled)
↓
[Step 6: Output] → File path + size + preview command
Check EXTEND.md (project-level first, then user-level):
test -f .daftAI-skills/daftAI-video-subtitler/EXTEND.md && echo "project"
test -f "$HOME/.daftAI-skills/daftAI-video-subtitler/EXTEND.md" && echo "user"
| Result | Action |
|---|---|
| Found | Read, parse, display summary → Continue |
| Not found | ⛔ Run first-time-setup → Save → Continue |
CRITICAL: Must complete setup before asking ANY other questions.
Goal: Ensure FFmpeg and fonts are available
Detect FFmpeg and libass:
ffmpeg -version
ffmpeg -filters 2>&1 | grep subtitles
Detect font (by priority, respecting preferences):
If missing libass:
brew install ffmpegsudo apt install ffmpeg libass-devGoal: Get video and subtitle files
User provides video path (mp4, mkv, avi, etc.)
Auto-scan subtitles in same directory:
Supported formats: .srt, .vtt, .ass, .ssa
Timeline offset detection (MUST execute):
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "<video_path>"
If subtitle start time > video duration → offset detected, needs fix.
VTT → SRT conversion only when merging or translating:
bun scripts/convert_vtt_to_srt.ts "<vtt_path>" "<srt_output>"
Auto-detect language:
Goal: Confirm mono/bilingual/translate + source label
Language: Use user's input language or preferred language for all questions. Do not always use English.
Use single AskUserQuestion with multiple questions when confirmation is needed.
⚠️ If quick_mode: true in preferences and intent is clear, skip subtitle confirmation. Source label still asked each time.
Ask user (only when preferences insufficient):
Source label (ask every time): If source_label.enabled: true in preferences:
What's the source for this video? (will display as "素材来自于 XXX")
Goal: Prepare final subtitle file
CRITICAL: Translated/merged subtitle artifacts MUST be kept by default for reuse. Detection-only process artifacts (screenshots/probe logs/temp checks) should be cleaned up by default unless debugging is requested.
Trigger: User explicitly requests translation.
Output path: <output_dir>/<video_name>_<target_lang>.srt (e.g., output/video_zh.srt)
Principles: Accuracy first, natural flow, concise.
Term mapping:
| English | Chinese |
|---|---|
| AI Agent | AI 智能体 |
| LLM | 大语言模型 |
| Skills | Skills (keep English) |
| overfitting | 过拟合 |
| Other terms | Use industry-standard translation |
Batch: Translate 20 lines per batch.
Count validation (MUST execute):
grep -c "^[0-9]\+$" <original> vs grep -c "^[0-9]\+$" <translated>Output path: <output_dir>/<video_name>_bilingual.srt (e.g., output/video_bilingual.srt)
bun scripts/merge_bilingual_subtitles.ts \
"<top_subtitle.srt>" \
"<bottom_subtitle.srt>" \
"<output_dir>/<video_name>_bilingual.srt"
Order: from preferences bilingual.order, fallback to default (Chinese top, English bottom).
Goal: Hardcode subtitles into video
bun scripts/burn_subtitles.ts \
"<video_path>" \
"<subtitle_path>" \
"<output_path>" \
[--font-size <数字>] \
[--outline <数字>] \
[--margin-v <数字>] \
[--crf <数字>] \
[--watermark-text <文字>] \
[--watermark-position <top-left|top-right|bottom-left|bottom-right>] \
[--watermark-opacity <0-1>] \
[--source-text <文字>] \
[--source-position <top-left|top-right|bottom-left|bottom-right>] \
[--source-opacity <0-1>]
All -- options are optional and fall back to EXTEND.md preferences or built-in defaults.
Parameters (from preferences, fallback to defaults):
| Parameter | Preference field | Default |
|---|---|---|
| Codec | encoding.codec | H.264 |
| Quality | encoding.crf | CRF 18 |
| Font | font | Alibaba PuHuiTi 3.0 |
| Font size | font_size | 21 |
| Outline | outline | 0.75 |
| Margin | margin_v | 15 |
| Color | built-in | White text, black outline |
| Watermark text | watermark.text | None |
| Watermark position | watermark.position | top-right |
| Watermark opacity | watermark.opacity | 0.7 |
| Source text | source_label.prefix + per-session | 素材来自于 {source} |
| Source position | source_label.position | top-left |
| Source opacity | source_label.opacity | 0.7 |
Goal: Show results
Output directory: from preferences output.directory, fallback to ./output/
Naming (from preferences output.naming, fallback to defaults):
video_zh.mp4video_zh-en.mp4Intermediate files policy:
subtitle_zh.srt)bilingual.srt)artifacts.keep_screenshots / artifacts.keep_probe_logs to trueShow user:
open "<output_path>"| Issue | Solution |
|---|---|
| FFmpeg missing subtitles filter | Install FFmpeg with libass |
| Subtitle encoding error | Convert to UTF-8 |
| Path contains spaces | Scripts auto-use temp directory |
| Font not found | Auto-fallback to next priority font |
Mono subtitle:
User: Add Chinese subtitles to this video
→ Load prefs → Env check → Scan subtitles → Burn → output video_zh.mp4
Bilingual:
User: Add both Chinese and English subtitles
→ Load prefs → Merge bilingual → Burn → output video_zh-en.mp4
Translate + burn:
User: Translate English subtitles to Chinese then burn
→ Load prefs → Translate → Burn → output video_zh.mp4
With watermark:
User: Add Chinese subtitles with @daftAI watermark
→ Load prefs → Env check → Scan subtitles → Burn (with watermark) → output video_zh.mp4
Customize via EXTEND.md. See Step 0 for paths.
Supports: font | size | outline | margin | color | CRF | bilingual order | output dir | naming | language | watermark | source label | quick mode | artifacts policy
| File | Content |
|---|---|
| first-time-setup.md | First-time setup flow |
| preferences-schema.md | Full preferences schema |