Communitygithub.com

HedgehogsGX/chinese-subtitles-skill

EN→简体中文 subtitle translate + burn-in Claude skill. Glossary packs for Apex/Warframe/osu!/Minecraft/SC2/CS2; one-line stroked white hardsubs. Works on talks/vlogs too.

chinese-subtitles-skill とは?

chinese-subtitles-skill is a Claude Code agent skill that eN→简体中文 subtitle translate + burn-in Claude skill. Glossary packs for Apex/Warframe/osu!/Minecraft/SC2/CS2; one-line stroked white hardsubs. Works on talks/vlogs too.

対応✓Claude Code~Codex CLI~Cursor
npx skills add HedgehogsGX/chinese-subtitles-skill

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

视频中文字幕 — translate and burn in

Takes an English video that already exists on disk and produces a Simplified-Chinese hardcoded version, plus a matching SRT.

Downloading is deliberately out of scope. Assume the source MP4 is already there.

The pipeline is subject-agnostic — it was built on a 22-minute Apex movement video, but nothing in the scripts knows or cares what the footage is. What changes per video is the glossary and the caption band position.

What good output looks like

The person using this cares about a specific, already-settled look. These are not defaults to reconsider each time — they were arrived at by iterating on real output, and changing them silently will be treated as a regression:

  • Simplified Chinese only. Never mixed Traditional. Verify before delivering.
  • One line per caption, always. Two-line captions are the single most common complaint. If a line is too long, split it into two sequential cues rather than wrapping. build_srt.py enforces this.
  • Captions are short. "One line" is not licence for a very wide line. Target at most ~1100px rendered width (about 57% of frame at 1080p).
  • No background box. White text, hard dark stroke, soft dark shadow.
  • 思源黑体 / Source Han Sans Bold (bundled at assets/NotoSansSC-Bold.ttf). Upright and heavy, with strong Latin glyphs — this style of video is full of English jargon set inside Chinese sentences, and a display face handles that badly.
  • Jargon the community actually says in English stays in English. Which terms those are is a per-subject question, and it is what the glossaries answer.
  • Burned-in chapter cards get a Chinese line underneath, not on top.

Workflow

1. Probe the source, and pick a glossary

ffprobe -v error -show_entries format=duration -show_entries stream=codec_type,codec_name,width,height,r_frame_rate -of default=nw=1 source.mp4

Note duration and fps exactly — every later step depends on them.

Then work out what the video is about and read references/glossaries/README.md, which routes to the right file and says which of its sections to read. Read the matched glossary's 字幕使用原则 section in full before translating — it is short, and it is where the conventions for that game live.

Bundled: Apex Legends, Warframe, osu!, Minecraft 速通/MCSR, StarCraft 星际争霸, Counter-Strike 反恐精英, ARC Raiders.

If there is no glossary for this video, that is the normal case. Translate against verifiable official Simplified names, keep a list of the terms you had to decide on, and hand that list over at the end. If a term has no official Chinese name, use a descriptive translation and say that it is not official — do not present a guess as settled. Never invent a name for something that already has one.

2. Get an English transcript with timings

If the video came from YouTube, its auto-captions are a usable base: yt-dlp --write-auto-subs --sub-langs "en.*" --skip-download. They are rolling captions with word-level timing tags, so de-duplicate them into sentence segments.

Auto-captions mangle jargon badly and you must repair it while translating. ASR transcribes phonetically against a general-English model, so every domain term that is not a common word comes back as a plausible wrong word. Real examples from Apex movement footage: "forward rez/raft/raz" → RAS, "Neor strafe" → Neo strafe, "pedo strafe" → Pito strafe, "mantel boost" → mantle boost, "alerts" → lurches, "my VO was so high" → my velo (velocity), "I couldn't attach out of that" → couldn't tap-strafe out of that. Expect the same class of damage in any jargon-dense video — the glossary is what lets you recognise it.

Where speech is genuinely unrecoverable — music stings, overlapping shouting — leave zh empty for that segment so it is dropped, and tell the user which timestamps you dropped. Inventing a plausible line is worse than no line.

3. Translate into a segments JSON

[{"i": 1, "start": 0.24, "end": 4.90,
  "en": "Seeing movement players pull off tricks like these is super cool and all, but",
  "zh": "看身法玩家秀出这种操作确实很酷,但真正的问题是"}]

Keep en — it is not decorative. build_srt.py uses it to tell a sentence continuation from a separate utterance when deciding whether two cues may be merged, which is what prevents run-ons like 算了好 or 是,长官你好啊.

4. Build the SRT

python scripts/build_srt.py segments.json sub.srt --font assets/NotoSansSC-Bold.ttf

It prints a report. Treat non-zero overlaps, multiline, latin_cjk_runons or term_split_across_cues as bugs to fix before encoding. A few under_0.35s cues are fine when they are 1–3 character interjections — check them, don't assume.

5. Find and translate burned-in chapter cards

python scripts/find_chapters.py source.mp4

Creators often burn chapter cards into the video rather than using YouTube chapters, so the metadata shows none. This reports candidate windows; extract a frame from each and read the actual card text before writing the translation. Output chapters.json: [{"start":42,"end":46,"zh":"第 1 章:定义 lurch 组合"}].

6. Check for places captions would collide with on-screen text

Outro cards are the usual offender — captions at the normal position land on top of the creator's socials. Extract a frame, find the gap, and declare it:

[{"from": 1334.0, "to": 100000, "bottom": 820}]

The default caption band sits above a typical FPS HUD. A different game, or non-gaming footage, may put its own elements there — a MOBA minimap, a rhythm game's judgement line, a talk's lower third. Extract a frame and look before accepting the default.

7. Build the overlay and encode

python scripts/build_overlay.py sub.srt ov --font assets/NotoSansSC-Bold.ttf \
    --duration 1354.351 --chapters chapters.json --avoid avoid.json
python scripts/burn_in.py source.mp4 ov/concat.txt out.mp4

Check the overlay's reported drift is a few milliseconds, not hundreds.

Before committing to a ~20 minute encode, composite one overlay PNG onto a real frame in PIL and look at it. It costs seconds and catches position and font mistakes that would otherwise surface 20 minutes later.

8. Verify

python scripts/verify.py out.mp4 --expect-frames <frames> \
    --contact-sheet sheet.jpg --at 75 300 660 945 1340

Look at the sheet. Confirm: single lines, legible over bright frames, chapter lines under their cards, nothing colliding with HUD or outro text.

9. Later fixes — splice, don't re-encode

When the user asks to change a few lines (they will), rebuild the SRT, diff it against the previous one to find which cues moved, then:

python scripts/splice.py out.mp4 source.mp4 sub.srt out_fixed.mp4 \
    --font assets/NotoSansSC-Bold.ttf --change-from 310 --change-to 316 \
    --duration 1354.351 --chapters chapters.json --avoid avoid.json
python scripts/verify.py out_fixed.mp4 --expect-frames <frames> --seams 310 316

15 seconds instead of 20 minutes. The frame count must come out identical.

Deliverables

Alongside out.mp4, hand over the SRT (dialogue plus chapter lines, merged and renumbered) so the captions can be edited later without redoing the work. Offer a Chinese title and description too — if the video is a repost, raise that the original first-person description implies authorship, and that music attribution blocks should stay in their original English because the licence requires that exact form.

If you had to settle terms that were not in a glossary, list them. A term decided once and written down is worth more than the same decision made differently next time; references/glossaries/README.md says how to turn a list like that into a glossary file.

Reference material

  • references/glossaries/README.md — which glossary to read, which sections of it, and what to do when the video has none. Start here.
  • references/glossaries/*.md — the glossaries themselves. Large. Read the principles section and the relevant sections; grep for individual terms.
  • references/pipeline.md — technical notes and the specific traps in this pipeline. Read it before debugging anything that looks like a timing, splice, or rendering problem; most of them have already been diagnosed once.

関連スキル