native-subtitle-quote-image: an Agent Skill that turns real video frames into 3:4 subtitle images
保留视频内嵌字幕,精确取帧并生成 3:4 社交长图的 Agent Skill
At a glance
- What is it?
- This Codex-compatible Skill keeps burned-in subtitles as pixels and renders reviewed script lines as clearly marked post-production text. It is a frame-accurate pipeline for quote cards, not a video editor.
- Who is it for?
- Adopt it if you already produce subtitle quote cards by hand and want the frame choice, the 3:4 layout and the subtitle-source labelling to happen in one agent task, and you are willing to install Python 3.10+, Pillow and FFmpeg first. Do not adopt it if your source only has a toggleable subtitle track and you need the original text untouched: the README is explicit that the Agent must explain the limitation and get consent before switching to script mode.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 25 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 16, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem: quote cards that quietly rewrite the video
Most subtitle quote cards are made by screenshotting a player and cropping. That works until you need a specific line, a clean 3:4 aspect ratio, and a guarantee that the text in the image is the text that was actually on screen. The project states its own boundary in one line: native subtitles are not redrawn, and script subtitles are not passed off as native ones. That distinction is the reason the Skill exists. It is aimed at people who publish quote images from interviews, talks or videos they have the rights to process, and who care whether the caption in the picture came from the video pixels or from a JSON file they approved. The repository also ships a Codex plugin package and an open Agent Skills directory, so the intended user is someone running an agent that can execute local Python scripts rather than someone clicking through a GUI.
Two subtitle modes that are never mixed
The README defines two modes with separate CLIs. Native mode uses `render` and takes its text from the video pixels: no OCR, no redrawing, no translation. It applies when the subtitles are burned into the frame and remain visible with the player's CC turned off. Script mode uses `render-script` and draws reviewed `lines[].text` onto a real video frame, and the documentation requires those lines to be marked as post-production subtitles. The two are deliberately not interchangeable. If a user asks for native subtitles but the video only carries a toggleable subtitle track, the README says the Agent must state the limitation first and only switch to script mode with the user's agreement. That is a stricter contract than most captioning tools offer, and it is the part worth reading before anything else. The demo images in the repository are script-mode examples: real frames plus reviewed Chinese lines, shown to illustrate framing and bar density, not to suggest the source video carried those captions.
The pipeline from video to compact 3:4 output
The workflow in the README is a chain, not a single command. A local video or a YouTube URL enters; `yt-dlp` fetches video, metadata and auxiliary subtitle tracks in URL mode; the Agent inspects real frames to separate burned-in subtitles from a separate track; an optional subtitle track or Whisper builds a timestamped content index; an optional upstream Skill nominates a topic; the subtitle mode is locked; the Agent returns to real frames to calibrate the timestamp and the main image; then a manifest or lines JSON goes through the compact 3:4 renderer and a per-image QA pass. The layout numbers are stated: with the default one main image plus four subtitle bars, the main image takes roughly 70 percent of the height, each bar about 7.5 percent, and the gap between bars is 0. Those figures come from the repository's own style notes, which describe the compact layout as a fix for bars that were too tall, spacing that was too wide, and a main image that did not dominate. Three operating modes are named: local finished-video mode, which needs no `yt-dlp`; URL full mode; and a content-production mode where other Skills sit upstream and this one owns the final timestamps, real frames, subtitle-source labelling and QA.
Installing it and rendering a first image
The README gives two install paths for Codex. The first is to invoke `$skill-installer` and point it at the Skill directory URL. The second is manual: clone the repository, create `~/.codex/skills`, and copy the Skill folder into it. Reopening a Codex task makes `$native-subtitle-quote-image` available.
git clone https://github.com/chengyi-ai/native-subtitle-quote-image.git
mkdir -p ~/.codex/skills
cp -R native-subtitle-quote-image/skills/native-subtitle-quote-image ~/.codex/skills/Core dependencies install from the Skill's own requirements file, and the environment checker reports what is missing. The checker is read-only: the README states it does not install or modify software, and that the Agent should explain a missing component and ask before adding it.
python3 -m pip install -r skills/native-subtitle-quote-image/requirements.txt
python3 skills/native-subtitle-quote-image/scripts/check_environment.pyIf you plan to draw Chinese, Japanese or Korean lines in script mode, run the checker with `--script-mode` to verify a CJK font is present. Native mode does not need one. For URL work, add `yt-dlp` and a JavaScript runtime, then run the URL-mode diagnostic. The README notes that yt-dlp currently recommends Deno, and that an existing Node.js install works if commands carry `--js-runtimes node`.
python3 -m pip install -U "yt-dlp[default]"
python3 skills/native-subtitle-quote-image/scripts/check_environment.py --url-modeAfter that, the first real use is a task in the agent: name the video, name the line you want, and state which subtitle mode applies. The Skill produces a candidate-frame overview with timestamps, then the 3:4 JPG, a timestamp list and an overview sheet. Expect to inspect the candidate frames before accepting an output, because the timestamp calibration step is where the line and the picture are matched.
Where it stops being the right tool
The clearest failure mode is a video whose only captions are a toggleable track. Native mode cannot help there, because native mode reads pixels. The README does not offer OCR to fake it. The second limitation is environmental: URL mode depends on `yt-dlp`, a JavaScript runtime, and, when YouTube blocks a public request with a sign-in check, an explicit user decision to let `yt-dlp` read Chrome's logged-in cookies with `--cookies-from-browser chrome`. The README states those cookies are not exported, saved, uploaded or written into the repository, but the permission step is real and the Agent is told not to misread a login wall as proof that the Skill only handles local files. Third, script mode for CJK text needs a CJK font installed; without one the render is not going to produce the lines you reviewed. Fourth, this is not a video editor. It selects frames, crops, composes and exports JPGs. There is no documented trimming, no audio work, no timeline editing, and the README does not describe exporting video at all.
How it differs from ffmpeg one-liners and subtitle burners
The obvious alternative is doing this by hand: seek in a player, screenshot, crop to 3:4 in an image editor, and type the line underneath. That gives you full control and needs no Python. The difference is that nothing in that loop records where the text came from, and nothing keeps the frame choice reproducible. A second alternative is burning a subtitle track into a clip with FFmpeg and screenshotting the result, which is closer in spirit but inverts the guarantee: the text becomes pixels, so a later viewer cannot tell whether it was in the original video. This Skill keeps the two cases separate by construction, with `render` for pixel-native subtitles and `render-script` for approved lines, and it adds a per-image QA pass and a timestamp list that a manual loop does not produce. The trade-off is real: you take on a Python dependency chain, a font requirement for CJK, and an agent runtime, in exchange for a labelled subtitle source and a fixed layout recipe.
Updates, licence and what maintenance costs you
The repository is MIT licensed, and the last push was on 2026-08-24, so the code is recent. The README describes a non-blocking version check that runs once at the start of each new task: `check_update.py` reads the local version from the Skill's `VERSION` file and compares it against the project's GitHub Latest Release. It reuses a cache for 24 hours by default, so it does not hit the network on every use, and it only reports a version number and a release link. It does not overwrite your local Skill. If the network is down, GitHub is unreachable, or the user declines, the task continues. The cache holds the check time, the latest version number and the release link, and per the README nothing about accounts, source material or usage. You can force a check with `--force --verbose`. The upgrade cost is therefore manual: new releases are announced, not applied, so you re-copy the Skill directory when you want the new version. One licence caveat the README states directly: the example images and any third-party content inside them are outside the repository's MIT grant. If you publish outputs made from someone else's video, that is a separate rights question the licence does not answer.
Editorial conclusion
Adopt it if you already produce subtitle quote cards by hand and want the frame choice, the 3:4 layout and the subtitle-source labelling to happen in one agent task, and you are willing to install Python 3.10+, Pillow and FFmpeg first. Do not adopt it if your source only has a toggleable subtitle track and you need the original text untouched: the README is explicit that the Agent must explain the limitation and get consent before switching to script mode. Before trusting it, run check_environment.py in the mode you intend to use and open one output JPG to confirm the subtitle bar density and the 70 percent main-image height match the layout you want.
Frequently asked questions
Does native-subtitle-quote-image redraw or translate subtitles?
No. In native mode the text comes from the video pixels, with no OCR, redrawing or translation. Script mode draws reviewed lines onto a real frame, and the README requires those to be identified as post-production subtitles.
Can native-subtitle-quote-image handle a YouTube link?
Yes, in URL mode, which requires `yt-dlp` and a JavaScript runtime such as Deno, or Node.js with `--js-runtimes node`. If YouTube returns a sign-in check, the Agent should explain it and ask before using `--cookies-from-browser chrome`.
What layout does native-subtitle-quote-image produce?
A 3:4 JPG. With the default one main image plus four subtitle bars, the README states the main image takes about 70 percent of the height, each bar about 7.5 percent, and the gap between bars is 0.
Community notes