Model or dataset
pengchujin/jzsub avatar
pengchujin/jzsub

JZSub: a Codex skill that turns one video link into a burned-in bilingual MP4

JZSub — 一条视频链接,自动交付最高画质、封面和 GPT 双语字幕 MP4。

990 stars105 forksPythonMIT

At a glance

What is it?
JZSub wraps yt-dlp, FFmpeg and a GPT translation pass into a single Codex skill. It is aimed at people who want a finished bilingual subtitle video from a URL, not a pile of intermediate files.
Who is it for?
Adopt JZSub if you already run Codex and want a repeatable one-link path to a burned-in bilingual MP4, and if you accept Python 3.10+, yt-dlp, Deno 2.3+, an FFmpeg build with libass, and the MiSans Bold font you must fetch yourself. Skip it if you need an API service, a GUI, or a pipeline that does not depend on a Codex skill.
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 53 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 19, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What JZSub actually removes from the workflow

The gap JZSub targets is the stretch between a video URL and a finished bilingual file. That stretch normally involves picking a yt-dlp format string, deciding whether to keep separate subtitle files, translating them, restyling them, and re-muxing or burning them in. JZSub collapses that into one instruction: hand it a link, get back the highest-quality video, a cover image, and a bilingual subtitle MP4.

The audience is narrow and specific. You need to be working inside Codex, because JZSub ships as a Codex skill rather than a standalone CLI product. The README lists YouTube, Bilibili, Vimeo, Twitch, Dailymotion and TikTok, plus whatever else yt-dlp supports, and it is explicit that the formats, subtitles and login requirements actually available are decided by the platform, not by JZSub. If you want a hosted service or a web UI, this is not that.

The pipeline: download, translate in batches, burn with libass

The mechanism is a script, skills/jzsub/scripts/fetch_video.py, that orchestrates several tools. yt-dlp handles retrieval and format selection. Deno is listed as a dependency, which is consistent with yt-dlp's JavaScript-related extraction needs. FFmpeg and ffprobe with libass do the rendering and burning. MiSans Bold is the subtitle font.

The translation design is the part worth reading twice. The README says translation runs through a compact queue in batches, with context carried between batches, and that the result is re-split along sentence boundaries while the original text stays unchanged. It also states that JZSub reads only the compact subtitle document and not the full manifest, and that burn-in reports progress every 5 percent. The default target language is Chinese, and --target-lang accepts others such as Japanese or French.

Delivery is declared up front. The README says filenames come from the download manifest, and that resume and delivery verification use the same name, so the check at the end is against the declared target rather than against whatever files happen to exist. That is a sensible way to avoid declaring success on a half-finished job.

Installing JZSub as a Codex skill

The README gives an npx path as the recommended install. It requires Node.js 18 or later, pulls the latest version from GitHub, and installs JZSub globally for Codex.

bash
npx skills add pengchujin/jzsub --skill jzsub -g -a codex -y

If you prefer to control the files, the manual route clones the repository and copies the skill directory into the Codex skills folder. The README shows exactly this pair of commands.

bash
git clone https://github.com/pengchujin/jzsub.git
mkdir -p ~/.codex/skills
cp -R jzsub/skills/jzsub ~/.codex/skills/

Dependencies come next. Python 3.10 or later, yt-dlp, Deno 2.3 or later, FFmpeg and ffprobe built with libass, and MiSans Bold. On macOS the README suggests one Homebrew line.

bash
brew install yt-dlp ffmpeg-full deno

The font is not in the repository. The README points to the Xiaomi HyperOS font download page, and you have to place MiSans Bold yourself. Skip that and the burn-in step has nothing to render with.

First real use is a message in a new Codex task. The README gives this exact form.

text
$jzsub https://www.youtube.com/watch?v=VIDEO_ID

What you should end up with, per the README, is 封面-视频名.jpg and 双语字幕版「视频名」.mp4 for the default Chinese delivery.

Choosing --deliver before you start a long job

JZSub has four delivery targets, and picking the wrong one wastes either time or output. full is the default and runs the whole pipeline: video, cover, subtitles, and the burned bilingual MP4. video stops after download and skips translation and burn-in, though it still saves the original subtitle file when the platform provides one. subs skips the video stream entirely and produces the original subtitles plus derived SRT. bilingual-subs skips the video too and produces the original subtitles plus translated bilingual SRT and ASS files.

You can drive the script directly rather than going through the agent. The README shows this invocation.

bash
python3 skills/jzsub/scripts/fetch_video.py "<url>" \
  --output-dir job --deliver video --browser-cookies auto

The completion rules differ by target and are stated in the README. video and subs finish when the download finishes. full and bilingual-subs continue into translation, and the delivery check judges success against the declared target. The subs family is the one to watch: when the platform has no suitable subtitles, those targets raise an explicit error rather than quietly returning video. That is the correct behaviour, but it means a subtitle-only run can fail on a video that a full run would have handled by delivering video and cover alone.

Where JZSub is the wrong tool

The dependency list is the first real constraint. Python 3.10+, yt-dlp, Deno 2.3+, FFmpeg with libass, and MiSans Bold is a lot of surface area for what looks like a one-command tool. The font is the awkward one, because the repository does not include it and the README sends you to an external download page. Anywhere you cannot install that font, burn-in is blocked.

The second constraint is the Codex dependency itself. JZSub is distributed as a skill, so the primary documented interface is a Codex task, not a shell command you can drop into a cron job. The script can be called directly, as the README shows, but the surrounding agent behaviour is where the deliverable selection and the continuous execution live.

Third, the README is explicit about scope: JZSub does not bypass DRM, paywalls, captchas or platform security limits, and it asks you to download only what you have the right to access and save. If your source needs authentication beyond what the browser-cookie path provides, JZSub is not going to solve it.

Finally, subtitle availability is not guaranteed. The README says JZSub still works when the platform has no subtitles, delivering video, MP4 and cover. But that only holds for full and video. For subs and bilingual-subs, absence of subtitles is a hard stop.

How this differs from driving yt-dlp and FFmpeg yourself

The obvious alternative is a hand-written yt-dlp plus FFmpeg pipeline, and the difference is not in the download step. yt-dlp already does format selection well, and the README's own dependency list treats it as the retrieval layer rather than replacing it.

The difference is in the middle. A manual pipeline leaves translation to you: export subtitles, chunk them, translate them, re-time them, and convert to a burnable format. JZSub's batching, cross-batch context, and sentence-boundary re-splitting are the parts you would otherwise build and maintain. The other difference is the delivery contract. JZSub declares an output target, names files from the manifest, and verifies against that declaration, including on resume. A shell script that runs four commands in sequence will happily exit zero with a missing final file.

What you give up is control and portability. A manual pipeline runs anywhere FFmpeg runs. JZSub assumes Codex, assumes the font is present, and assumes the platform exposes what the run needs.

Maintenance, upgrade cost and the MIT licence

The last push to the repository was on 2026-07-29, and the most recent release listed is v1.8.1 from 2026-07-13, with v1.8.0 and v1.7.0 earlier the same day. The repository is not archived. There is a TODO.md at the top level, which suggests work is tracked in the open, but the README does not document a rollback path or a version pinning scheme for the npx install, so an upgrade means re-running the install command and taking whatever is current.

The practical upgrade cost sits in the dependency chain rather than in JZSub itself. yt-dlp changes frequently because platforms change; FFmpeg builds vary in whether libass is compiled in; Deno has a minimum version stated as 2.3+. A JZSub upgrade that looks trivial can break because one of those moved underneath it.

On licensing: JZSub is MIT, which is permissive and places few obligations on reuse. The README notes separately that platform logos and trademarks belong to their respective owners. That is a statement about assets in the repository, not legal advice about your use of downloaded video, and the two questions are independent. The MIT grant covers JZSub's code; it says nothing about the material you point it at.

Editorial conclusion

Adopt JZSub if you already run Codex and want a repeatable one-link path to a burned-in bilingual MP4, and if you accept Python 3.10+, yt-dlp, Deno 2.3+, an FFmpeg build with libass, and the MiSans Bold font you must fetch yourself. Skip it if you need an API service, a GUI, or a pipeline that does not depend on a Codex skill. Before trusting it on real work, run the self-test and unit tests from the README, confirm your platform actually exposes subtitles, and check what --deliver mode you need, because subs and bilingual-subs error out when the platform has no usable subtitle track.

Frequently asked questions

What is JZSub and what does it produce?

JZSub is a Codex skill that takes a video link and returns the highest-quality video, a cover image, and a bilingual subtitle MP4. The default delivery is Chinese, producing 封面-视频名.jpg and 双语字幕版「视频名」.mp4. It supports YouTube, Bilibili, Vimeo, Twitch, Dailymotion, TikTok and other sites yt-dlp handles.

How do I install JZSub in Codex?

The README recommends npx skills add pengchujin/jzsub --skill jzsub -g -a codex -y, which needs Node.js 18 or later. Alternatively, clone the repository and copy jzsub/skills/jzsub into ~/.codex/skills/. You also need Python 3.10+, yt-dlp, Deno 2.3+, FFmpeg with libass, and MiSans Bold.

Can JZSub translate subtitles into a language other than Chinese?

Yes. Chinese is the default target language, and the --target-lang option accepts others such as Japanese or French. The README describes translation as running in compact batches with context carried between batches, then re-split at sentence boundaries while the original text stays unchanged.

Official sources

  1. Issues
  2. License: MIT
  3. pengchujin/jzsub on GitHub
  4. README
  5. Releases
Community notes

Community notes