chjm-ai/tiktok-karaoke-captions/tiktok-karaoke-captions
Claude Code and agent skill by chjm-ai/tiktok-karaoke-captions
- community
Checking that the SKILL.md file is still in the repository.
Burn TikTok-style karaoke captions (per-word yellow highlight, ALL CAPS, bold sans-serif) + optional headline banner into a local video, fully offline on Apple Silicon (mlx-whisper + ffmpeg). Use when the user wants to add subtitles / captions / 字幕 to a video, asks for "TikTok-style captions" / "karaoke captions" / "word-by-word highlighted captions" / "caption a video" / "burn subtitles into a video" / "auto-subtitle this video" / "给视频加字幕" / "做卡拉OK字幕" / "TikTok字幕风格" / "顶部加 headline 横幅", or provides a video file (and optionally a script.txt and/or headline string) wanting a captioned output. Do NOT use for: generating SRT for an online/streaming video without a local file; editing/translating an existing .srt's text (that's a text task); pure transcription with no burn-in and no styling (just run whisper); non-macOS or non-Apple-Silicon hosts (mlx-whisper won't run — needs a different backend).
Install
npx vskill@latest install chjm-ai/tiktok-karaoke-captions/tiktok-karaoke-captionsSKILL.md
TikTok Karaoke Captions
Burn TikTok-style karaoke captions and a persistent headline banner into any local video, fully offline on macOS Apple Silicon.
When to use
Trigger this skill when the user wants any of:
- 给视频加字幕 / add subtitles to a video
- TikTok 风格字幕 / karaoke captions / per-word highlight captions
- 顶部 headline 横幅 / persistent headline / video title overlay
- 用 Whisper 转录视频 / auto-transcribe a video
- 字幕烧入视频 / burn subtitles into a video
- 用脚本原文校准字幕 / forced-alignment subtitles from a known script
Three usage tiers
(moved out of the frontmatter — pick based on what the user gives you)
- Pure auto-caption — just a video. Whisper transcribes, captions burned. Fastest, but typos possible.
- Script-aligned (zero typos) — video +
--script-file script.txt.difflibforced-aligns the known script onto Whisper word timestamps, so the burned text is exactly the script. Use whenever the original script exists. - Full TikTok package — script +
--headline "...". Adds a persistent top headline pill on top of tier 2.
Quick reference
Outputs (in --out-dir or alongside the input)
<stem>.srt— line-level SRT (always written)<stem>.ass— karaoke ASS (tiktok mode only)<stem>.whisper.json— raw Whisper word timestamps (debug)<stem>-captioned.mp4— final video with text burned in
Mechanism
- Audio extract: ffmpeg → 16 kHz mono WAV
- Transcribe:
uvx --from mlx-whisper mlx_whisper(Apple Silicon native, ~10 sec for 15s video at medium model after warmup; auto-retries with bigger model if output looks broken) - Align: if
--script-filegiven,difflib.SequenceMatchermaps each script word → Whisper word timestamp (forced alignment, zero typos) - Chunk: split into 1–3 word chunks at sentence/comma boundaries
- ASS karaoke: each chunk → N events, current word highlighted yellow via
{\c&H0000FFFF&}…{\c}inline tags - Burn: single ffmpeg pass —
drawbox+drawtextfor headline pill +subtitlesfilter for ASS - ffmpeg fallback: if system ffmpeg lacks libass (Homebrew bottle), auto-uses
static-ffmpegfrom PyPI viauvx(no system changes)
Requirements
- macOS on Apple Silicon (mlx-whisper requirement)
uvinstalled (brew install uv) — only system dependency- ~1.8 GB disk for first-run downloads (whisper-medium model + deps + static-ffmpeg)
Optional: Deepgram cloud (faster + more reliable than local)
Set DEEPGRAM_API_KEY env var to enable Deepgram Nova-3 — when the key is set, it becomes the default primary backend (faster: ~2s vs ~10s, and more reliable than local mlx-whisper). Local Whisper is used as the fallback when Deepgram fails. Pass --prefer-local to flip this back to local-first. Free $200 credit at https://console.deepgram.com/signup. Cost ~$0.001 per 15s clip.
Bundled fonts (open-source, commercial OK)
- Archivo Black (OFL 1.1) — headline pill
- Roboto Black / Bold / Regular (Apache 2.0) — captions
See `fonts/README.md` for details and licenses.
Gotchas(来自真实失败,照这个排错)
- 中文/非英文音频不加 `--language` 会被转成英文乱码。
--language默认en,Whisper 会把中文音轨硬听成英文(满屏拼音/错词)。音频不是英文时必须显式传--language zh(或对应语言码)。脚本对齐模式(tier 2)也救不了它——对齐前的转录就已经错了。 - 字幕固定在底部中央(`Alignment=2, MarginV=70`),不会自动避让人脸。 如果说话人脸在画面下半部,字幕会压在脸/嘴上。本工具不做人脸检测。补救:classic 模式用
--style "Alignment=8,MarginV=70"(顶部)或调大MarginV把字幕抬高;或先确认主体构图在上 2/3 再烧字幕。给竖屏数字人视频时尤其要先看一眼人脸位置。 - 每行字符上限是软上限 42(`--max-chars-per-line`,对齐脚本时生效)。 超长行会被按句读/逗号切;中文一个字≈一个 char,但占的视觉宽度比英文字母宽,42 对中文偏长,竖屏建议调到 ~16–20,否则字会顶到屏幕边缘。headline 另有独立按宽度自适应换行逻辑。
- 缩略图 / 转场帧会出现"半句字幕"。 烧字幕是按 Whisper 时间轴的,视频开头的转场帧 / 封面帧那一瞬间可能正好卡在某个 chunk 中间,截图当缩略图时会看到残缺字幕。要干净封面就单独抽一帧没有字幕的原片帧,别从 captioned.mp4 截。
- 系统 ffmpeg 缺 libass 时会自动回退 static-ffmpeg,但首次要联网下 ~60MB。 Homebrew 的 ffmpeg bottle 常被裁掉 libass(
subtitlesfilter 用不了)。脚本检测到就用uvx --from static-ffmpeg,不改系统。离线首跑会失败——确保第一次有网把 static-ffmpeg 和 whisper 模型拉下来。 - 转录看着"太短/太空"会自动换更大模型重试。 真很短的视频(语音少)可能误判触发重试,拖慢。确认音频确实稀疏时直接
--model medium跳过 small 的重试循环。
CLI reference
Run caption.py --help for the full list of flags.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingSKILL.md
Popularity
- Repository stars
- 2
- 7-day trend score
- 5
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 17 May 2026, 5 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/chjm-ai/tiktok-karaoke-captions/tiktok-karaoke-captions)