wjs-localizing-video

$npx mdskill add jianshuo/claude-skills/wjs-localizing-video

Orchestrates full video localization pipeline

  • Routes user requests to ASR, translation, dubbing, and subtitle burning sub-skills.
  • Deploys ASR for audio transcription, translation service for subtitles, TTS for dubbing if needed, and final encoding for MP4 output.
  • Decides based on user request for full localization or individual steps, routing directly to relevant sub-skill.
  • Delivers localized video via final MP4 file, optionally with subtitle burn or dubbing.

SKILL.md

.github/skills/wjs-localizing-videoView on GitHub ↗
---
name: wjs-localizing-video
description: Thin orchestrator for the end-to-end video localization pipeline. Routes to the four focused sub-skills — /wjs-transcribing-audio, /wjs-translating-subtitles, /wjs-dubbing-video, /wjs-burning-subtitles. Use when the user asks for full localization in one go ("帮我把这个西班牙语视频做成中文字幕+配音", "translate and dub this video", "做完整的本地化"). For any individual step (just transcribe, just translate, just dub, just burn), invoke the sub-skill directly — it's faster and the boundary is cleaner.
---

# wjs-localizing-video (orchestrator)

> **This skill was split.** What used to be one 1300-line catch-all is now 4 focused sub-skills. Use this orchestrator only when the user asks for the *full pipeline* in one request. For any individual step, route directly to the sub-skill.

## The four sub-skills

| Step | Skill | IN | OUT |
|---|---|---|---|
| 1. ASR | **`/wjs-transcribing-audio`** | audio / video + source language | source-language SRT |
| 2. Translate | **`/wjs-translating-subtitles`** | source SRT + target language | target SRT (punct-bounded) |
| 3. Dub (optional) | **`/wjs-dubbing-video`** | video + target SRT + voice | `*_<lang>_dub.mp4` (TTS audio swapped in) |
| 4. Burn / mix (optional) | **`/wjs-burning-subtitles`** | video + SRT + (optional dub) | final MP4 (one encode) |

Steps 3 and 4 are optional and independent — most "subtitle-only" jobs stop after step 2 + soft-mux via `/wjs-burning-subtitles`. Most "dub-only" jobs stop after step 3.

## When to invoke this orchestrator vs a sub-skill directly

**Invoke this skill (`wjs-localizing-video`)** when the user asks for the whole chain in one go:

- "帮我把这个西班牙语视频做成中文字幕和中文配音"
- "translate this Spanish video to English with dubbing"
- "全套:转写、翻译、烧字幕、配音、混音"

**Invoke a sub-skill directly** when the user asks for one step:

- "转写一下这个音频" → `/wjs-transcribing-audio`
- "把这个 SRT 翻译成中文" → `/wjs-translating-subtitles`
- "给这个视频配个中文音" → `/wjs-dubbing-video`
- "把字幕烧进视频" → `/wjs-burning-subtitles`

The sub-skills are more focused and document their input/output contracts tighter. Don't route through this orchestrator when a single step is the whole ask — you'll just be reading docs you don't need.

## Progress checklist (do this FIRST, before any sub-skill)

The pipeline has up to four steps and runs for several minutes. The user wants to see live progress, not a wall of silence followed by a finished file. **Before invoking the first sub-skill, lay out the planned steps as a TaskCreate checklist.** As you start each step, update its task to `in_progress`; when it finishes, mark `completed`. Claude Code renders this as a checklist in the UI that ticks off in real time.

### Which tasks to create

Decide from the user's ask which subset of the 4 steps will run:

| User asked for | Tasks to create |
|---|---|
| Full localization (subs + dub + final mix) | ① 转写 ② 翻译 ③ 配音 ④ 烧字幕 + 混音 |
| Subtitles only (no voice change) | ① 转写 ② 翻译 ③ 烧字幕 (or soft-mux) |
| Dub only (no burn) | ① 转写 ② 翻译 ③ 配音 |
| User already has source SRT | skip ①; create only the remaining steps |
| User already has target SRT | skip ① and ②; create only the remaining |

Don't create tasks for steps you won't run — an unchecked item at the end reads as "we forgot," not "we skipped."

### How to phrase the task subjects

Use the same labels you'll use in the "Final response template" below, so the in-flight checklist and the completion summary read as the same artifact:

- `转写 <source-lang>` (e.g., `转写 西班牙语`)
- `翻译 → <target-lang>` (e.g., `翻译 → 中文`)
- `配音 <target-lang>` (e.g., `配音 中文 (高冷御姐 -8%)`)
- `烧字幕 + 原声底层 <bed>` (e.g., `烧字幕 + 原声底层 0.18`)

For `activeForm`, use the present-continuous variant (`转写中…`, `翻译中…`, `配音中…`, `合成中…`).

### State discipline

- Mark `in_progress` **only** the task currently running (one at a time).
- Mark `completed` immediately when the sub-skill returns its output file — don't batch.
- If a step surfaces a clarifying question or fails, **leave it as `in_progress`** so the user can see exactly where the pipeline stopped. Don't mark a half-finished step as completed.
- If the user redirects mid-pipeline (e.g., "skip the dub"), update the remaining tasks: delete the ones no longer applicable, keep the rest. Don't silently drop them.

## Canonical end-to-end pipeline (Spanish → Chinese, with dub + bed + burn)

This is the original "validation scenario" — Spanish yoga/spiritual content into Chinese for 微信视频号 / 小红书. Walks through all 4 sub-skills.

### Step 1 — Transcribe the Spanish source

```
Invoke /wjs-transcribing-audio with the video and `--language es`.
```

The sub-skill handles: chunking, word-level timestamps, cue assembly at punctuation boundaries, loop guard, retry. Output: `entrevista.srt` (Spanish, source-language).

### Step 2 — Translate to Simplified Chinese

```
Invoke /wjs-translating-subtitles with the Spanish SRT and target `zh-CN`.
```

The sub-skill handles: re-segmenting cues at punctuation, minimizing filler demonstratives, capping line length, preserving speaker tone. Output: `entrevista.zh-CN.srt`.

### Step 3 — (Optional) Dub into Chinese

```
Invoke /wjs-dubbing-video with the video + entrevista.zh-CN.srt + a voice ID.
```

Default for mature contemplative female: `zh_female_gaolengyujie_moon_bigtts` (Volcano 高冷御姐, `--rate -8% +0Hz`). If no Volcano credentials: `zh-CN-XiaoxiaoNeural --rate -8% --pitch -10Hz`. The sub-skill samples first, then commits.

Output: `entrevista_zh_dub.mp4`.

### Step 4 — Burn subs + mix dub over original-as-bed

```
Invoke /wjs-burning-subtitles with --video entrevista.mp4 --srt entrevista.zh-CN.srt --dub entrevista_zh_dub.mp4
```

The sub-skill handles: libass availability check, evermeet static-build fallback, Fontsize calibration, frame-check before full render, audio bed mix at 0.18.

Output: `entrevista_zh_final.mp4` (ship-ready).

## Defaults the user has standardized

These apply across the pipeline; each sub-skill enforces its own slice:

- **Chinese ASR routes to 豆包 (Volcano) first; Whisper is fallback.** Enforced in `/wjs-transcribing-audio`.
- **Single voice for the whole dub unless the user explicitly mentions multiple speakers.** Enforced in `/wjs-dubbing-video`.
- **Original audio kept as a low-volume bed (0.15–0.25) under any dub.** Enforced in `/wjs-burning-subtitles`.
- **Burn-in for 微信视频号 / 抖音; soft-mux for everything else by default.** Enforced in `/wjs-burning-subtitles`.
- **Channel CTA name (if added to description): 王建硕** — never a guest's name. (Global rule from `~/.claude/CLAUDE.md`; applies when this pipeline is followed by `/wjs-uploading-video`.)

## File naming convention (preserved from the original skill)

```text
input:                       entrevista.mp4

Chinese pipeline:
  source SRT                 entrevista.srt
  Chinese SRT                entrevista.zh-CN.srt
  Chinese dub (audio only)   entrevista_zh_dub.mp4
  Chinese final (subs+dub)   entrevista_zh_final.mp4

English pipeline:
  English SRT                entrevista.en.srt
  English dub                entrevista_en_dub.mp4
  English final              entrevista_en_final.mp4

Bilingual subtitles:
  Spanish + Chinese          entrevista.es-zh.srt
  Spanish + English          entrevista.es-en.srt
  three-language             entrevista.es-zh-en.srt
```

BCP-47-style suffixes keep multiple target-language outputs side-by-side and make the target obvious at a glance.

## What this orchestrator does NOT do

- It does not re-implement anything. Every step delegates to a sub-skill.
- It does not bundle the scripts. `dub.py` lives in `/wjs-dubbing-video/scripts/`, `render.py` lives in `/wjs-burning-subtitles/scripts/`, `visual_diarize.py` lives in `/wjs-dubbing-video/scripts/`. If you see stale copies under `wjs-localizing-video/scripts/`, prefer the canonical sub-skill locations.

## Final response template

When the full pipeline completes, respond briefly in the user's language. Match the original "Done" template the user is used to:

```text
已完成:
- 西班牙语转写  (/wjs-transcribing-audio)
- 中文翻译     (/wjs-translating-subtitles)
- 中文配音     (/wjs-dubbing-video, voice: 高冷御姐 -8%)
- 烧入字幕 + 原声底层 0.18  (/wjs-burning-subtitles)

输出:
- entrevista.srt
- entrevista.zh-CN.srt
- entrevista_zh_dub.mp4
- entrevista_zh_final.mp4

不确定片段:
- 00:01:23–00:01:26 背景噪音较大,原文可能不完全准确。
```

If there are no uncertain parts, drop the second list.

## See also

- `/wjs-segmenting-video` — cut long-form video into stand-alone short clips (uses its own SRT slicer; orthogonal to this pipeline).
- `/wjs-overlaying-video` — HTML/CSS captions on a clip via HyperFrames. **Don't combine with `/wjs-burning-subtitles`** — pick one caption system per output.
- `/wjs-uploading-video` — push the final MP4 to YouTube.
- `/lark-minutes` — alternate Chinese-only transcript path via 飞书妙记 when local 豆包 ASR isn't wired up.

More from jianshuo/claude-skills

SkillDescription
wangjianshuo-perspective|
wjs-auditing-projectUse when the user asks to audit what's wrong with a project, "make it right", "看看项目出了什么问题", "为什么用户的需求还没上线", "为什么没提交App Store", "为什么没新build", or wants a holistic state-of-the-project check covering unmerged branches, stalled PRs, failed GitHub Actions, stale builds, plan drift (TODOS.md / ROADMAP), unreleased commits, and log errors. Runs read-only investigation, presents a grouped checklist, fixes only after explicit user confirmation. Aware of the Cathier iOS app workflow (Xcode + fastlane + auto-merge @claude PRs from in-app feedback).
wjs-burning-subtitlesUse when the user has a video + an SRT and wants the subtitles either burned into the pixels (libass, always-visible) or soft-muxed as a togglable track. Also handles the final composite step for the localization pipeline — burn subs, mix a dub track, and keep the original audio as a low-volume bed, all in ONE ffmpeg encode (no cascade). Verifies libass availability and auto-downloads a static evermeet ffmpeg build when Homebrew's stripped binary lacks it. Triggers — "烧字幕", "硬字幕", "burn subtitles", "burn-in subs", "embed subtitle", "soft mux SRT", "把字幕烧进视频", "做最终合成".
wjs-cleaning-spamUse when the user complains about spam on his X/Twitter posts — 同城面付 / 寻固炮 / 线下上门 / 免费破处 这类引流号在他推文下刷的 emoji 垃圾回复 — and wants them removed. Covers the last 7 days (X recent-search window). Triggers — "把这些spam删掉", "清理X垃圾回复", "推文下面好多引流号", "clean spam replies", "/wjs-cleaning-spam".
wjs-converting-text-to-videoUse when the user wants a 王建硕-style WeChat article (article.md) turned into a narrated short MP4 video — TTS voiceover via 火山引擎 Volcano TTS, HyperFrames CSS/GSAP animation per scene, subtle SFX, abstract watercolor background, full pipeline rendering to 1080×1920 portrait MP4 (30-90s). Triggers — "把这篇文章做成视频", "做一个解说视频", "讲解视频", "/wjs-converting-text-to-video".
wjs-converting-wp-to-hugoUse when migrating a WordPress site to a Hugo static site on GitHub Pages from a WXR export (.xml) plus the wp-content/uploads folder — preserving /archives/<id>/ URLs, localizing images, and deploying via GitHub Actions. Triggers — "把 WordPress 迁成 Hugo", "wordpress 转静态站", "migrate WordPress to Hugo", "WXR to Hugo", "publish WordPress to GitHub Pages", "/wjs-converting-wp-to-hugo".
wjs-distilling-styleUse when the user wants to capture a writer's voice from a few sample articles and rewrite text to sound like that author — "蒸馏文风", "提炼XX的风格", "把这篇改成XX的味儿", "学某某笔法改写", "mimic this writer", "match this author's style", "style transfer". Works for any author, 王建硕 included.
wjs-dubbing-videoUse when the user has a video + a target-language SRT and wants the video to actually speak that language — generates a time-aligned TTS voice dub. Routes by voice ID — Volcano (豆包) TTS for Chinese, edge-tts neural for any language. Defaults to one voice (single-speaker); opt-in multi-speaker via visual diarization. Outputs `*_<lang>_dub.mp4` with the dub audio in place of the original. Final mixing (audio bed + burn-in) is handed off to `/wjs-burning-subtitles`. Triggers — "配音", "中文配音", "Chinese dub", "voice over this", "dub the video", "TTS this SRT", "different voice for each speaker".
wjs-eating-and-growing吃一堑长一智 — 走完 5 步交互式反思(堑 → 自动输出 → 旧权重 → 新参数 → 替代动作),从「情绪复盘」推进到「行为训练」,把第一反应这一层 L3 权重练新。Use when 王建硕 reflects on a personal setback, mistake, or recurring pattern (反思, 复盘, 回顾, 总结教训, 吃一堑, 长一智, "这次又栽了", "怎么又这样", "为什么我总是…", "想开点都做不到", "知道道理但做不到"). For the user as a human, not for Claude's task post-mortems.
wjs-editing-multicamUse when the user has 2+ recordings of the same event (each with a `.sync.json` sidecar from wjs-syncing-multicam) and wants them combined into a single MP4 — auto-switching between cams second-by-second on audio energy, with optional picture-in-picture inset. Triggers — "auto-edit multicam", "做个剪辑", "切几个机位", "把这几个视频合成一个", "combine these angles", "PiP overlay".