Oct 22, 2026
Turn Real Video Frames Into Subtitle Quote Images With native-subtitle-quote-image
A Python agent skill that crops burned-in subtitles straight from video pixels — or draws your reviewed lines onto real frames and labels them post-produced — then stacks them into compact quote images at content-driven or explicit aspect ratios such as 3:4 and checks every one before delivery, from Codex, Claude Code, or the command line.
The subtitle-stack quote image — one hero frame with a column of subtitle strips under it — is a staple of social feeds, and making one by hand means scrubbing for timestamps and cropping strips pixel by pixel. The 3k-star chengyi-ai/native-subtitle-quote-image repository — README in Chinese first, with English and Korean twins — packages that job as an agent skill: video in, native or scripted subtitle quote images out, with every image checked before delivery.
Why This Skill Matters
The README's defining rule is two subtitle modes, never mixed. Native mode only crops subtitles already burned into the frame — video pixels only, no OCR redraw, translation, or rewriting. Scripted mode draws your reviewed copy onto real frames and labels it as post-produced; its text comes only from the reviewed lines[].text in a JSON you supply. The commands are render and render-script, and if you have not chosen a mode, the agent asks first, briefly explains the difference, and waits. The layout is deliberately compact: native subtitle strips are stacked as source pixels and scaled together rather than enlarging the first line, scripted fixed layouts keep about 70% of the canvas for the hero, and strips sit flush with no gaps.
It works three ways: from a local video with no yt-dlp; as a full URL flow that uses yt-dlp to fetch a video you have the right to process plus metadata and auxiliary subtitle tracks; and as the last stage of content production, where upstream skills pick topics and write the post and this one owns timestamps, real frames, subtitle-source labels, and QA.
Installation
Clone and copy the skill directory into your agent's skills folder — the README's primary path is Codex:
git clone https://github.com/chengyi-ai/native-subtitle-quote-image.git
cd native-subtitle-quote-image
mkdir -p ~/.codex/skills && cp -R skills/native-subtitle-quote-image ~/.codex/skills/
For Claude Code, swap .codex for .claude; the README also documents Windows PowerShell equivalents, a Codex Skill Installer path, and a generic "copy the directory" route for other agents that read the open Agent Skills format. When upgrading, delete the old directory first so files removed upstream do not linger. Then install the Python dependencies and run the read-only self-check:
python3 -m pip install -r skills/native-subtitle-quote-image/requirements.txt
python3 skills/native-subtitle-quote-image/scripts/check_environment.py
For YouTube URLs, also install yt-dlp and re-run the check with --url-mode; to draw Chinese, Japanese, or Korean copy, check fonts with --script-mode. The checker never installs or changes software — when something is missing, the agent explains why it is needed and asks before installing. The dependency table lists Python 3.10+, Pillow, and imageio-ffmpeg or FFmpeg as required in both modes; yt-dlp and Deno (or explicitly enabled Node.js) for YouTube; CJK fonts only for CJK scripted mode.
Real Workflow: Native Quote Images From a Burned-In Video
- Open a new agent task and use the README's one-sentence ask (the
$form is Codex syntax; in Claude Code use/native-subtitle-quote-imageor just describe what you want):
Use $native-subtitle-quote-image to turn this video with burned-in subtitles into native subtitle quote images.
- The agent checks the source, subtitle type, and candidate frames, locks the mode, then delivers JPG files matching the layout, a
原生字幕时间点.jsontimestamp file for native mode (or alinesJSON for scripted), and afinal_contact_sheet.jpgoverview for multi-image jobs.
If you would rather drive the scripts yourself, the README's native path is three commands: sample VIDEO --start 30 --end 120 --interval 5 --out candidate-contact-sheet.jpg to get a timestamped candidate sheet (with no range it samples up to 24 frames evenly across the whole video), band VIDEO -t 61.2 --band-top 0.78 --band-bottom 0.96 --out band-preview.jpg to confirm the subtitle crop region, then render VIDEO --manifest manifest.json --out-dir output-v1 --band-top 0.78 --band-bottom 0.96. Native one-line subtitles are previewed from the 0.78–0.96 band of the source height by default.
Tips
- Each image takes at most 7 timestamps — 1 hero plus 6 strips — in both modes; split longer passages into several images. Existing images are never overwritten unless you pass
--overwrite. - Before rendering, both modes check for duplicate frames: if every timestamp yields nearly the same picture (a static cover image, say) or two adjacent native strips are nearly identical, the command stops without writing. Pass
--allow-duplicate-framesonce you have confirmed it is intended. - Scripted mode has a
--six-line-cardpreset (six reviewed lines, strictly increasing timestamps, an 870px hero over five contiguous 114px strips at 1080×1440), a--speaker-prefix on-changeoption for interviews that draws a speaker label only when the speaker changes, and--emphasize-line lastto highlight one line. - Fixed single-camera footage is high risk — six near-identical heroes. The README's answer is
--hero-zoom 1.0,0.9,0.95, per-card hero zoom factors in the 0.8–1.0 range, and it warns the result is crop-and-upscale, not real sharpness. - Batch
renderstops at the first failure;--keep-goingwrites a failure list to渲染失败报告.jsonand exits non-zero, and--resumethen renders only the missing or corrupt cards.
When Not to Use This
The scope table is explicit. If the video only has a switchable or downloadable subtitle track, native mode cannot work — the frame is clean once CC is off — and the agent switches to scripted mode only after you agree. Unreviewed copy or translations are out: scripted text is your reviewed JSON, never a quote the source did not say. And low-resolution footage will not be "enhanced" into genuinely high-resolution output. The README also asks you to prefer footage you created and subtitled, licensed material, or public video that clearly permits reuse, and to confirm usage rights again before publishing.
See the leaderboard for more skills.