本页只展示中文字幕作品,均为 3:4、5 句。英文和韩文作品分别在 English 与 한국어 README 中。点击图片查看原图。
1. 安装 Skill
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/
Windows PowerShell:
New-Item -ItemType Directory -Force "$HOME\.codex\skills" | Out-Null
Copy-Item -Recurse skills\native-subtitle-quote-image "$HOME\.codex\skills\"
升级时请先删除旧目录再复制,否则新版本已删除的旧文件会残留(Claude Code 把
.codex换成.claude):rm -rf ~/.codex/skills/native-subtitle-quote-imageRemove-Item -Recurse -Force "$HOME\.codex\skills\native-subtitle-quote-image"
Claude Code:复制到 Claude Code 的 Skills 目录。
mkdir -p ~/.claude/skills && cp -R skills/native-subtitle-quote-image ~/.claude/skills/
Windows PowerShell:
New-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null
Copy-Item -Recurse skills\native-subtitle-quote-image "$HOME\.claude\skills\"
Codex Skill Installer:在 Codex 中调用 $skill-installer,让它安装这个目录:
https://github.com/chengyi-ai/native-subtitle-quote-image/tree/main/skills/native-subtitle-quote-image
其他 Agent:本项目使用开放的 Agent Skills 目录格式。把 skills/native-subtitle-quote-image/ 复制到目标 Agent 的 Skills 目录即可,具体位置以该 Agent 的文档为准。
2. 安装依赖并自检
python3 -m pip install -r skills/native-subtitle-quote-image/requirements.txt
python3 skills/native-subtitle-quote-image/scripts/check_environment.py
要处理 YouTube 链接,再装 yt-dlp:
python3 -m pip install -U "yt-dlp[default]"
python3 skills/native-subtitle-quote-image/scripts/check_environment.py --url-mode
要画中日韩台词,用 --script-mode 检查字体。环境自检是只读的,不会自动安装或修改任何软件;缺组件时,Agent 会先说明用途,征得你同意再装。
3. 重开一个 Agent 任务,说一句话
使用 $native-subtitle-quote-image,把这个带内嵌中文字幕的视频做成原生字幕拼图。
如果你没有指定模式,Agent 会先问“您当前是选择原生字幕还是脚本字幕?”,并用一句话解释两者区别,再按你的选择处理。
| 原生字幕 | 脚本字幕 | |
|---|---|---|
| 什么时候用 | 关掉播放器的 CC 后,字幕仍然烧在画面里 | 要把已核对的台词、翻译或观点画到真实画面上 |
| 图里的字从哪来 | 视频像素本身,不 OCR 重绘,不翻译改写 | 你审核过的 lines[].text,明确属于后期字幕 |
| 命令 | render | render-script |
[!IMPORTANT] 原生模式的字只能来自视频像素;脚本模式的字只能来自已审核的 JSON,不能冒充原字幕。 如果你要原生字幕,但视频只有可开关的字幕轨,Agent 会先说明限制,经你同意后才改用脚本模式。
flowchart LR
A[本地视频<br>或 YouTube 链接] --> B[获取视频<br>与字幕轨]
B --> C[检查真实帧<br>区分烧录字幕]
C --> D[按文字稿<br>选题选句]
D --> E{锁定模式}
E -->|原生| F[裁切画面<br>里的字幕条]
E -->|脚本| G[绘制已<br>审核台词]
F --> H[按模式渲染<br>逐张质检]
G --> H
Skill 支持三种工作方式:
yt-dlp。yt-dlp 获取你有权处理的视频、元数据和辅助字幕轨,再决定字幕模式。| 场景 | 对 Agent 说 |
|---|---|
| 视频自带烧录字幕 | 使用 $native-subtitle-quote-image,把这个带内嵌中文字幕的视频做成原生字幕拼图。 |
| 给的是链接 | 使用 $native-subtitle-quote-image,读取这个 YouTube 链接,先检查下载权限和烧录字幕,再选 3 个适合传播的主题,做成原生字幕拼图并逐张质检。 |
| 写稿配图一起做 | 先根据视频文字稿提炼选题并写文章,再用 $native-subtitle-quote-image 为每个核心观点选真实视频帧并出图;先判断原生或脚本字幕模式,不要混用。 |
| 用自己核对过的台词 | 使用 $native-subtitle-quote-image 的脚本字幕模式,把这份带时间点的中文台词画到真实视频帧上,做成紧凑 3:4 长图并逐张质检。 |
[!TIP]
$native-subtitle-quote-image是 Codex 的写法。在 Claude Code 里可以用/native-subtitle-quote-image,或者直接描述需求。
Agent 会先检查来源、字幕类型和候选帧,确定模式后再生成:
原生字幕时间点.json,或脚本模式的 lines JSON;final_contact_sheet.jpg 总览图。不经过 Agent 也可以直接跑脚本。下面的 VIDEO 换成你的视频路径。
自检来源:下载后先检查分辨率并解码前 10 秒,坏流或低清在抽帧前就失败(不传 --min-height 时低于 720p 只警告)。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py check-source VIDEO --min-height 720
挑帧:生成带时间点的候选帧总览,不用反复试时间点。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py sample VIDEO \
--start 30 --end 120 --interval 5 --out candidate-contact-sheet.jpg
不传 --start、--end 和 --interval 时,会在整段视频里均匀抽取最多 24 帧。已经知道大概时间点时,可以围绕每个点取前、中、后三帧,避开字幕切换的瞬间:
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py sample VIDEO \
-t 61.2 -t 68.9 -t 74.5 -t 82.0 -t 88.4 \
--around 0.8 --out focused-candidates.jpg
原生字幕:先用 band 确认字幕的裁切区域,再按 manifest 渲染一组成品。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py band VIDEO \
-t 61.2 --band-top 0.78 --band-bottom 0.96 --out band-preview.jpg
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render VIDEO \
--manifest manifest.json --out-dir output-v1 \
--band-top 0.78 --band-bottom 0.96
脚本字幕:准备 script.json,然后渲染。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render-script VIDEO \
--script script.json --out output.jpg --aspect 3:4 --width 1440
可选六句卡:script.json 中放 6 句已核对、时间点严格递增的台词。此预设在 1080×1440 画布上使用 870px 主画面和下方 5 条各 114px 的连续字幕条,首句与后五句等距;默认脚本布局不变。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render-script VIDEO \
--script script.json --out six-line.jpg --six-line-card --aspect 3:4 --width 1080
--six-line-card 仅用于后期绘制的脚本字幕,不接受 --layout natural 或 --hero-fraction。字幕条默认从源画面高度的 60% 处取样,可用 --band-center 调整;仍须逐句核对来源和逐张检查画面。
固定机位源与 --hero-zoom:优先选多机位、景别有变化的视频;固定机位视频(大师课、网课式录制)是高风险素材,六张主图容易几乎一样。render 与 render-script 支持可选的 --hero-zoom 1.0,0.9,0.95:逗号分隔的每卡主图缩放系数,范围 0.8–1.0,按卡循环,默认不启用且输出不变。它只裁掉更多主图画面再放大,字幕条、文字、条间距和六句卡几何不变,原生模式的裁切窗口不会进入字幕条。因为是裁切后放大,源视频清晰度不足时主图会更模糊,不等于真实清晰度提升。render-script 只输出一张图,取第一个系数。
呼吸缝 --strip-gap 与分隔线 --hero-divider:render 与 render-script 支持可选的 --strip-gap N(字幕条之间插入 N 像素黑色缝隙,0–8,默认 0)和 --hero-divider line(主图与字幕条之间插入 2px 细分隔线,默认 none)。二者只新增背景像素,不覆盖、不重绘原画面,原生字幕仍只经历整图统一缩放;固定画布总尺寸不变,字幕条相应变矮;与 --six-line-card 不兼容。
可选说话人前缀:问答、对谈类脚本字幕图,可以在 script.json 每句加 "speaker": "主持人",再加 --speaker-prefix on-change,只在换人时画出「主持人:」这类前缀;every 每句都画,none(默认)不画。前缀比台词小一号、用强调色,台词字号不会因为前缀而变小。说话人写在 speaker 字段里,不写进 text。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render-script VIDEO \
--script script.json --out qa.jpg --speaker-prefix on-change
可选金句强调:脚本字幕图可用 --emphasize-line last(最后一句)或 --emphasize-line 3(第 3 句,从 1 起算)给一句台词加暖色、加粗描边和轻微半透明底衬,方便截图搬走;也可在 script.json 的某句写 "emphasis": true。默认不启用,输出不变;行号越界会报错。只用于脚本模式,原生字幕模式不会重绘任何字幕。
保留人物原比例与横屏构图(v2.2.0):两种字幕模式都支持 --layout natural。不指定宽度时保留源宽度,图片高度按实际内容计算,不强制 3:4;指定 --width 也只做等比缩放。
# 原生字幕:保留画面像素,不重绘文字
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render VIDEO \
--manifest manifest.json --out-dir output-natural --layout natural
# 脚本字幕:仅裁去不需要的底部区域,不把剩余画面拉高
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render-script VIDEO \
--script script.json --out natural.jpg --layout natural --frame-bottom 0.72
0.72 是示例裁切边界,需按视频实测;默认 --frame-top 0 --frame-bottom 1 保留全帧。--band-center 相对裁切后的画面。原比例布局不与 --aspect / --hero-fraction 合用。“原比例”只描述画面几何,脚本字幕仍是后期绘制。
默认原生布局修正(v2.2.2):render 不传布局或比例时,默认按内容计算高度、保留源宽度。明确加 --aspect 3:4 --width 1440 时仍输出 1440×1920,但对整张拼图统一等比缩放,保留完整字幕,不分别填满主图和字幕条(v2.2.2 用留黑边适配画布,v2.3.0 起默认先统一裁两侧,见下)。原生模式的 --hero-fraction 仅调整源主图裁切高度,受源帧限制;脚本字幕仍默认固定 3:4。输出比例不匹配时,不能用非等比 resize 硬改。
横屏视频出 3:4 少留黑边(v2.3.0):原生 render 的固定画布默认 --fit crop:先自动识别每句字幕的左右边界,再对整张拼图统一裁去两侧,最多裁到字幕安全边界,剩余差额才留黑边。所有字幕仍是同一缩放倍数;任何一句识别不到字幕边界时不裁切,退回整图留边。人物偏左或偏右时,用 --crop-center 0.4 这类数值移动裁切窗口,窗口始终包含全部字幕。想要 v2.2.2 的纯留边效果,加 --fit pad。裁切后仍要逐张检查字幕两端是否完整。
script.json 的格式每个 text 必须是已复核的单行台词,t 是严格递增的真实时间点:
{
"lines": [
{"t": 61.6, "text": "第一句已核对台词"},
{"t": 69.3, "text": "第二句已核对台词"},
{"t": 75.0, "text": "第三句已核对台词"},
{"t": 82.4, "text": "第四句已核对台词"},
{"t": 88.8, "text": "第五句已核对台词"}
]
}
脚本会自动尝试常见的系统 CJK 字体(台词含韩文时优先 Apple SD Gothic Neo / Malgun Gothic),找不到时用 --font /path/to/font.ttc 指定。台词太长就拆句,不要靠缩小字号硬塞。
几条默认行为:
0.78–0.96 区域开始预览。--overwrite。--tmp-dir <可写目录>(或设置环境变量 NSQI_TMP_DIR,参数优先)指定抽帧临时文件位置;不指定则沿用系统临时目录,目录不存在或不可写会明确报错。render 默认遇到失败就中止;加 --keep-going 则单张失败不影响其余,结束时输出失败清单(第几张、时间点、原因)并写入输出目录的 渲染失败报告.json,退出码非零。修正后加 --resume 只补渲缺失或损坏的图;已有效的图即使 manifest 改了也不会重渲,总览图和时间点文件会重新生成。--allow-duplicate-frames。--help 查看。| 适合 | 不适合 |
|---|---|
| 关掉 CC 后字幕仍在画面里,想原样保留 | 想要原生字幕,但视频只有可单独开关、切换或下载的字幕轨 |
| 手里有可复核的时间点和已审核台词,想画到真实画面上 | 台词或翻译还没复核,或者希望 Agent 编造来源里没有的引语 |
| 你有权处理和发布这段视频及生成的画面 | 想把低清视频"增强"成真实的高清画质 |
素材优先用自己拍摄并加过字幕的视频、已获授权的素材,或明确允许再利用的公开视频。公开发布前,请再确认一遍素材使用权。
很多视频的字幕是播放器里可开关的字幕轨(CC),下载下来的画面是干净的,这类视频做不了原生模式。
先判断:关掉播放器字幕再看画面;或者下载后用 sample 生成候选帧总览,画面里仍有字幕才是烧录字幕。只下载到 VTT/SRT 字幕文件,不代表画面里有字幕。
更容易找到的来源:
还是找不到:改用脚本字幕模式。用视频自带的字幕轨或 Whisper 文字稿定位时间点,核对台词后写进 script.json,再运行 render-script。成品会标明是后期字幕,不冒充原字幕。
拼图本身只按时间顺序排列,不识别谁在说话;字幕条只裁画面底部,读者会默认整张图都是主画面里那个人说的。YouTube 字幕轨和普通 Whisper 文字稿也都不标说话人。所以多人视频如果直接按"连续几句"选,就容易把主持人的问题和嘉宾的回答拼在一起,看起来分不清谁说的、顺序也乱。
Skill 现在会这样处理:
--speaker-prefix。调用时可以直接说明:"这是两人访谈,只选嘉宾连续说的几句。"
渲染器不识别人脸,也不自动挑帧,主图用哪一帧由 Agent 决定。为了避免切头顶、下巴贴着字幕条、脸偏到一侧,Skill 会在出图后逐张目测主图(固定比例裁切时看裁切后的画面):
不达标时,先在原时间点前后约 1.5 秒内重找;还找不到就用最接近的一帧,并在交付时说明哪张主图哪一项不达标。这些比例只是目测参考,不是程序校验,也不需要额外安装人脸检测依赖。想要特写或刻意偏置的构图,直接告诉 Agent 即可。
| 组件 | 本地模式 | URL 模式 | 用途 |
|---|---|---|---|
native-subtitle-quote-image | 必需 | 必需 | 选帧、裁切、拼图和最终质检 |
| Python 3.10+ | 必需 | 必需 | 运行 Skill 脚本 |
| Pillow | 必需 | 必需 | 裁图、拼图、导出 JPG |
imageio-ffmpeg 或 FFmpeg | 必需 | 必需 | 读取视频、精确取帧 |
yt-dlp | — | 必需 | 获取在线视频、元数据和字幕轨 |
| Deno,或显式启用 Node.js | — | YouTube 必需 | 完整解析 YouTube 格式 |
| Whisper / 语音识别 Skill | 可选 | 可选 | 没有字幕轨时生成时间索引 |
| CJK 字体 | 中日韩脚本模式必需 | 中日韩脚本模式必需 | 绘制中日韩台词;原生模式不需要 |
| 选题、写作或视频理解 Skill | 可选 | 可选 | 从文字稿提名主题、生产配套内容 |
URL 模式会先尝试公开访问。如果 YouTube 返回登录验证、年龄验证,或者是你自己的非公开视频,Agent 不会误判成"只能处理本地视频",而是说明原因,并询问你是否允许 yt-dlp 临时读取 Chrome 里的登录 Cookie。
你授权后,元数据、字幕和视频下载命令都会加上 --cookies-from-browser chrome:
yt-dlp --cookies-from-browser chrome --js-runtimes node \
--no-playlist --skip-download \
--print "%(id)s | %(title)s | %(duration_string)s" \
"URL"
Cookie 不导出、不保存、不上传,也不写进仓库。yt-dlp 官方目前推荐用 Deno 做 JavaScript 运行时;已经装了 Node.js 的话也可以用,但要加 --js-runtimes node。完整授权边界和故障处理见 URL 获取参考。
每个新任务开始时,Skill 会做一次不阻塞任务的版本检查:读取自带的 VERSION,和本项目 GitHub 上的 Latest Release 比较。
python3 skills/native-subtitle-quote-image/scripts/check_update.py --json
想立刻重新检查:
python3 skills/native-subtitle-quote-image/scripts/check_update.py --force --verbose
头图由 scripts/render_banners.py 生成,中文、英文、韩文各一张 2560×1280 的 JPG,放在 assets/ 里。背景铺满 examples/gallery 的成品案例,自带深色底,GitHub 浅色和深色主题共用。改文字时编辑脚本顶部的 COPY,改背景墙用哪些案例时编辑 WALL,然后运行:
python3 scripts/render_banners.py
需要本机装有 Chrome 或 Chromium,渲染时会从 Google Fonts 加载字体。找不到浏览器时,用 --chrome /path/to/chrome 指定。Linux 上若图片底部被截掉一截,改用 chrome-headless-shell 渲染。
中文头图 assets/banner-zh.jpg 同时用作仓库社交预览图:在仓库 Settings → General → Social preview 上传,分享仓库链接时就会显示。
python3 scripts/validate_repo.py
python3 -m unittest discover -s tests -v
python3 skills/native-subtitle-quote-image/scripts/check_environment.py
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py --help
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render-script --help
每次推送和 Pull Request 都会在 Python 3.10 和 3.13 上通过 GitHub Actions 自动检查。
Windows 等默认编码不是 UTF-8 的系统(如简体中文 Windows 的 GBK),建议先设置 PYTHONUTF8=1(PowerShell:$env:PYTHONUTF8=1;cmd:set PYTHONUTF8=1)再运行上述命令;check_environment.py 会在检测到非 UTF-8 默认编码时给出提示。
深入文档
欢迎在 Issues 提问题或建议,渲染问题请附上出问题那一页的截图;也可以在社交媒体上直接找作者反馈。新 issue 会由 Agent 自动评估可行性,符合条件的需求由 Agent 编码、测试并提交 PR,维护者审查合并后自动发版。完整流程见 Agent 工作流说明。
| 平台 | 账号 |
|---|---|
| 𝕏 Twitter | @ChengYi3629 |
| 📕 小红书 | 程意 |
代码与 Skill 指令采用 MIT License。示例图片只用于展示输出效果;输入视频、生成图片及其中出现的第三方内容,不因本许可证获得额外授权。
830 followers · starred Sep 2026
180 followers · starred Oct 2026
19 followers · starred Oct 2026
43 followers · starred Sep 2026
本页只展示中文字幕作品,均为 3:4、5 句。英文和韩文作品分别在 English 与 한국어 README 中。点击图片查看原图。
1. 安装 Skill
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/
Windows PowerShell:
New-Item -ItemType Directory -Force "$HOME\.codex\skills" | Out-Null
Copy-Item -Recurse skills\native-subtitle-quote-image "$HOME\.codex\skills\"
升级时请先删除旧目录再复制,否则新版本已删除的旧文件会残留(Claude Code 把
.codex换成.claude):rm -rf ~/.codex/skills/native-subtitle-quote-imageRemove-Item -Recurse -Force "$HOME\.codex\skills\native-subtitle-quote-image"
Claude Code:复制到 Claude Code 的 Skills 目录。
mkdir -p ~/.claude/skills && cp -R skills/native-subtitle-quote-image ~/.claude/skills/
Windows PowerShell:
New-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null
Copy-Item -Recurse skills\native-subtitle-quote-image "$HOME\.claude\skills\"
Codex Skill Installer:在 Codex 中调用 $skill-installer,让它安装这个目录:
https://github.com/chengyi-ai/native-subtitle-quote-image/tree/main/skills/native-subtitle-quote-image
其他 Agent:本项目使用开放的 Agent Skills 目录格式。把 skills/native-subtitle-quote-image/ 复制到目标 Agent 的 Skills 目录即可,具体位置以该 Agent 的文档为准。
2. 安装依赖并自检
python3 -m pip install -r skills/native-subtitle-quote-image/requirements.txt
python3 skills/native-subtitle-quote-image/scripts/check_environment.py
要处理 YouTube 链接,再装 yt-dlp:
python3 -m pip install -U "yt-dlp[default]"
python3 skills/native-subtitle-quote-image/scripts/check_environment.py --url-mode
要画中日韩台词,用 --script-mode 检查字体。环境自检是只读的,不会自动安装或修改任何软件;缺组件时,Agent 会先说明用途,征得你同意再装。
3. 重开一个 Agent 任务,说一句话
使用 $native-subtitle-quote-image,把这个带内嵌中文字幕的视频做成原生字幕拼图。
如果你没有指定模式,Agent 会先问“您当前是选择原生字幕还是脚本字幕?”,并用一句话解释两者区别,再按你的选择处理。
| 原生字幕 | 脚本字幕 | |
|---|---|---|
| 什么时候用 | 关掉播放器的 CC 后,字幕仍然烧在画面里 | 要把已核对的台词、翻译或观点画到真实画面上 |
| 图里的字从哪来 | 视频像素本身,不 OCR 重绘,不翻译改写 | 你审核过的 lines[].text,明确属于后期字幕 |
| 命令 | render | render-script |
[!IMPORTANT] 原生模式的字只能来自视频像素;脚本模式的字只能来自已审核的 JSON,不能冒充原字幕。 如果你要原生字幕,但视频只有可开关的字幕轨,Agent 会先说明限制,经你同意后才改用脚本模式。
flowchart LR
A[本地视频<br>或 YouTube 链接] --> B[获取视频<br>与字幕轨]
B --> C[检查真实帧<br>区分烧录字幕]
C --> D[按文字稿<br>选题选句]
D --> E{锁定模式}
E -->|原生| F[裁切画面<br>里的字幕条]
E -->|脚本| G[绘制已<br>审核台词]
F --> H[按模式渲染<br>逐张质检]
G --> H
Skill 支持三种工作方式:
yt-dlp。yt-dlp 获取你有权处理的视频、元数据和辅助字幕轨,再决定字幕模式。| 场景 | 对 Agent 说 |
|---|---|
| 视频自带烧录字幕 | 使用 $native-subtitle-quote-image,把这个带内嵌中文字幕的视频做成原生字幕拼图。 |
| 给的是链接 | 使用 $native-subtitle-quote-image,读取这个 YouTube 链接,先检查下载权限和烧录字幕,再选 3 个适合传播的主题,做成原生字幕拼图并逐张质检。 |
| 写稿配图一起做 | 先根据视频文字稿提炼选题并写文章,再用 $native-subtitle-quote-image 为每个核心观点选真实视频帧并出图;先判断原生或脚本字幕模式,不要混用。 |
| 用自己核对过的台词 | 使用 $native-subtitle-quote-image 的脚本字幕模式,把这份带时间点的中文台词画到真实视频帧上,做成紧凑 3:4 长图并逐张质检。 |
[!TIP]
$native-subtitle-quote-image是 Codex 的写法。在 Claude Code 里可以用/native-subtitle-quote-image,或者直接描述需求。
Agent 会先检查来源、字幕类型和候选帧,确定模式后再生成:
原生字幕时间点.json,或脚本模式的 lines JSON;final_contact_sheet.jpg 总览图。不经过 Agent 也可以直接跑脚本。下面的 VIDEO 换成你的视频路径。
自检来源:下载后先检查分辨率并解码前 10 秒,坏流或低清在抽帧前就失败(不传 --min-height 时低于 720p 只警告)。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py check-source VIDEO --min-height 720
挑帧:生成带时间点的候选帧总览,不用反复试时间点。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py sample VIDEO \
--start 30 --end 120 --interval 5 --out candidate-contact-sheet.jpg
不传 --start、--end 和 --interval 时,会在整段视频里均匀抽取最多 24 帧。已经知道大概时间点时,可以围绕每个点取前、中、后三帧,避开字幕切换的瞬间:
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py sample VIDEO \
-t 61.2 -t 68.9 -t 74.5 -t 82.0 -t 88.4 \
--around 0.8 --out focused-candidates.jpg
原生字幕:先用 band 确认字幕的裁切区域,再按 manifest 渲染一组成品。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py band VIDEO \
-t 61.2 --band-top 0.78 --band-bottom 0.96 --out band-preview.jpg
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render VIDEO \
--manifest manifest.json --out-dir output-v1 \
--band-top 0.78 --band-bottom 0.96
脚本字幕:准备 script.json,然后渲染。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render-script VIDEO \
--script script.json --out output.jpg --aspect 3:4 --width 1440
可选六句卡:script.json 中放 6 句已核对、时间点严格递增的台词。此预设在 1080×1440 画布上使用 870px 主画面和下方 5 条各 114px 的连续字幕条,首句与后五句等距;默认脚本布局不变。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render-script VIDEO \
--script script.json --out six-line.jpg --six-line-card --aspect 3:4 --width 1080
--six-line-card 仅用于后期绘制的脚本字幕,不接受 --layout natural 或 --hero-fraction。字幕条默认从源画面高度的 60% 处取样,可用 --band-center 调整;仍须逐句核对来源和逐张检查画面。
固定机位源与 --hero-zoom:优先选多机位、景别有变化的视频;固定机位视频(大师课、网课式录制)是高风险素材,六张主图容易几乎一样。render 与 render-script 支持可选的 --hero-zoom 1.0,0.9,0.95:逗号分隔的每卡主图缩放系数,范围 0.8–1.0,按卡循环,默认不启用且输出不变。它只裁掉更多主图画面再放大,字幕条、文字、条间距和六句卡几何不变,原生模式的裁切窗口不会进入字幕条。因为是裁切后放大,源视频清晰度不足时主图会更模糊,不等于真实清晰度提升。render-script 只输出一张图,取第一个系数。
呼吸缝 --strip-gap 与分隔线 --hero-divider:render 与 render-script 支持可选的 --strip-gap N(字幕条之间插入 N 像素黑色缝隙,0–8,默认 0)和 --hero-divider line(主图与字幕条之间插入 2px 细分隔线,默认 none)。二者只新增背景像素,不覆盖、不重绘原画面,原生字幕仍只经历整图统一缩放;固定画布总尺寸不变,字幕条相应变矮;与 --six-line-card 不兼容。
可选说话人前缀:问答、对谈类脚本字幕图,可以在 script.json 每句加 "speaker": "主持人",再加 --speaker-prefix on-change,只在换人时画出「主持人:」这类前缀;every 每句都画,none(默认)不画。前缀比台词小一号、用强调色,台词字号不会因为前缀而变小。说话人写在 speaker 字段里,不写进 text。
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render-script VIDEO \
--script script.json --out qa.jpg --speaker-prefix on-change
可选金句强调:脚本字幕图可用 --emphasize-line last(最后一句)或 --emphasize-line 3(第 3 句,从 1 起算)给一句台词加暖色、加粗描边和轻微半透明底衬,方便截图搬走;也可在 script.json 的某句写 "emphasis": true。默认不启用,输出不变;行号越界会报错。只用于脚本模式,原生字幕模式不会重绘任何字幕。
保留人物原比例与横屏构图(v2.2.0):两种字幕模式都支持 --layout natural。不指定宽度时保留源宽度,图片高度按实际内容计算,不强制 3:4;指定 --width 也只做等比缩放。
# 原生字幕:保留画面像素,不重绘文字
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render VIDEO \
--manifest manifest.json --out-dir output-natural --layout natural
# 脚本字幕:仅裁去不需要的底部区域,不把剩余画面拉高
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render-script VIDEO \
--script script.json --out natural.jpg --layout natural --frame-bottom 0.72
0.72 是示例裁切边界,需按视频实测;默认 --frame-top 0 --frame-bottom 1 保留全帧。--band-center 相对裁切后的画面。原比例布局不与 --aspect / --hero-fraction 合用。“原比例”只描述画面几何,脚本字幕仍是后期绘制。
默认原生布局修正(v2.2.2):render 不传布局或比例时,默认按内容计算高度、保留源宽度。明确加 --aspect 3:4 --width 1440 时仍输出 1440×1920,但对整张拼图统一等比缩放,保留完整字幕,不分别填满主图和字幕条(v2.2.2 用留黑边适配画布,v2.3.0 起默认先统一裁两侧,见下)。原生模式的 --hero-fraction 仅调整源主图裁切高度,受源帧限制;脚本字幕仍默认固定 3:4。输出比例不匹配时,不能用非等比 resize 硬改。
横屏视频出 3:4 少留黑边(v2.3.0):原生 render 的固定画布默认 --fit crop:先自动识别每句字幕的左右边界,再对整张拼图统一裁去两侧,最多裁到字幕安全边界,剩余差额才留黑边。所有字幕仍是同一缩放倍数;任何一句识别不到字幕边界时不裁切,退回整图留边。人物偏左或偏右时,用 --crop-center 0.4 这类数值移动裁切窗口,窗口始终包含全部字幕。想要 v2.2.2 的纯留边效果,加 --fit pad。裁切后仍要逐张检查字幕两端是否完整。
script.json 的格式每个 text 必须是已复核的单行台词,t 是严格递增的真实时间点:
{
"lines": [
{"t": 61.6, "text": "第一句已核对台词"},
{"t": 69.3, "text": "第二句已核对台词"},
{"t": 75.0, "text": "第三句已核对台词"},
{"t": 82.4, "text": "第四句已核对台词"},
{"t": 88.8, "text": "第五句已核对台词"}
]
}
脚本会自动尝试常见的系统 CJK 字体(台词含韩文时优先 Apple SD Gothic Neo / Malgun Gothic),找不到时用 --font /path/to/font.ttc 指定。台词太长就拆句,不要靠缩小字号硬塞。
几条默认行为:
0.78–0.96 区域开始预览。--overwrite。--tmp-dir <可写目录>(或设置环境变量 NSQI_TMP_DIR,参数优先)指定抽帧临时文件位置;不指定则沿用系统临时目录,目录不存在或不可写会明确报错。render 默认遇到失败就中止;加 --keep-going 则单张失败不影响其余,结束时输出失败清单(第几张、时间点、原因)并写入输出目录的 渲染失败报告.json,退出码非零。修正后加 --resume 只补渲缺失或损坏的图;已有效的图即使 manifest 改了也不会重渲,总览图和时间点文件会重新生成。--allow-duplicate-frames。--help 查看。| 适合 | 不适合 |
|---|---|
| 关掉 CC 后字幕仍在画面里,想原样保留 | 想要原生字幕,但视频只有可单独开关、切换或下载的字幕轨 |
| 手里有可复核的时间点和已审核台词,想画到真实画面上 | 台词或翻译还没复核,或者希望 Agent 编造来源里没有的引语 |
| 你有权处理和发布这段视频及生成的画面 | 想把低清视频"增强"成真实的高清画质 |
素材优先用自己拍摄并加过字幕的视频、已获授权的素材,或明确允许再利用的公开视频。公开发布前,请再确认一遍素材使用权。
很多视频的字幕是播放器里可开关的字幕轨(CC),下载下来的画面是干净的,这类视频做不了原生模式。
先判断:关掉播放器字幕再看画面;或者下载后用 sample 生成候选帧总览,画面里仍有字幕才是烧录字幕。只下载到 VTT/SRT 字幕文件,不代表画面里有字幕。
更容易找到的来源:
还是找不到:改用脚本字幕模式。用视频自带的字幕轨或 Whisper 文字稿定位时间点,核对台词后写进 script.json,再运行 render-script。成品会标明是后期字幕,不冒充原字幕。
拼图本身只按时间顺序排列,不识别谁在说话;字幕条只裁画面底部,读者会默认整张图都是主画面里那个人说的。YouTube 字幕轨和普通 Whisper 文字稿也都不标说话人。所以多人视频如果直接按"连续几句"选,就容易把主持人的问题和嘉宾的回答拼在一起,看起来分不清谁说的、顺序也乱。
Skill 现在会这样处理:
--speaker-prefix。调用时可以直接说明:"这是两人访谈,只选嘉宾连续说的几句。"
渲染器不识别人脸,也不自动挑帧,主图用哪一帧由 Agent 决定。为了避免切头顶、下巴贴着字幕条、脸偏到一侧,Skill 会在出图后逐张目测主图(固定比例裁切时看裁切后的画面):
不达标时,先在原时间点前后约 1.5 秒内重找;还找不到就用最接近的一帧,并在交付时说明哪张主图哪一项不达标。这些比例只是目测参考,不是程序校验,也不需要额外安装人脸检测依赖。想要特写或刻意偏置的构图,直接告诉 Agent 即可。
| 组件 | 本地模式 | URL 模式 | 用途 |
|---|---|---|---|
native-subtitle-quote-image | 必需 | 必需 | 选帧、裁切、拼图和最终质检 |
| Python 3.10+ | 必需 | 必需 | 运行 Skill 脚本 |
| Pillow | 必需 | 必需 | 裁图、拼图、导出 JPG |
imageio-ffmpeg 或 FFmpeg | 必需 | 必需 | 读取视频、精确取帧 |
yt-dlp | — | 必需 | 获取在线视频、元数据和字幕轨 |
| Deno,或显式启用 Node.js | — | YouTube 必需 | 完整解析 YouTube 格式 |
| Whisper / 语音识别 Skill | 可选 | 可选 | 没有字幕轨时生成时间索引 |
| CJK 字体 | 中日韩脚本模式必需 | 中日韩脚本模式必需 | 绘制中日韩台词;原生模式不需要 |
| 选题、写作或视频理解 Skill | 可选 | 可选 | 从文字稿提名主题、生产配套内容 |
URL 模式会先尝试公开访问。如果 YouTube 返回登录验证、年龄验证,或者是你自己的非公开视频,Agent 不会误判成"只能处理本地视频",而是说明原因,并询问你是否允许 yt-dlp 临时读取 Chrome 里的登录 Cookie。
你授权后,元数据、字幕和视频下载命令都会加上 --cookies-from-browser chrome:
yt-dlp --cookies-from-browser chrome --js-runtimes node \
--no-playlist --skip-download \
--print "%(id)s | %(title)s | %(duration_string)s" \
"URL"
Cookie 不导出、不保存、不上传,也不写进仓库。yt-dlp 官方目前推荐用 Deno 做 JavaScript 运行时;已经装了 Node.js 的话也可以用,但要加 --js-runtimes node。完整授权边界和故障处理见 URL 获取参考。
每个新任务开始时,Skill 会做一次不阻塞任务的版本检查:读取自带的 VERSION,和本项目 GitHub 上的 Latest Release 比较。
python3 skills/native-subtitle-quote-image/scripts/check_update.py --json
想立刻重新检查:
python3 skills/native-subtitle-quote-image/scripts/check_update.py --force --verbose
头图由 scripts/render_banners.py 生成,中文、英文、韩文各一张 2560×1280 的 JPG,放在 assets/ 里。背景铺满 examples/gallery 的成品案例,自带深色底,GitHub 浅色和深色主题共用。改文字时编辑脚本顶部的 COPY,改背景墙用哪些案例时编辑 WALL,然后运行:
python3 scripts/render_banners.py
需要本机装有 Chrome 或 Chromium,渲染时会从 Google Fonts 加载字体。找不到浏览器时,用 --chrome /path/to/chrome 指定。Linux 上若图片底部被截掉一截,改用 chrome-headless-shell 渲染。
中文头图 assets/banner-zh.jpg 同时用作仓库社交预览图:在仓库 Settings → General → Social preview 上传,分享仓库链接时就会显示。
python3 scripts/validate_repo.py
python3 -m unittest discover -s tests -v
python3 skills/native-subtitle-quote-image/scripts/check_environment.py
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py --help
python3 skills/native-subtitle-quote-image/scripts/native_subtitle_stitch.py render-script --help
每次推送和 Pull Request 都会在 Python 3.10 和 3.13 上通过 GitHub Actions 自动检查。
Windows 等默认编码不是 UTF-8 的系统(如简体中文 Windows 的 GBK),建议先设置 PYTHONUTF8=1(PowerShell:$env:PYTHONUTF8=1;cmd:set PYTHONUTF8=1)再运行上述命令;check_environment.py 会在检测到非 UTF-8 默认编码时给出提示。
深入文档
欢迎在 Issues 提问题或建议,渲染问题请附上出问题那一页的截图;也可以在社交媒体上直接找作者反馈。新 issue 会由 Agent 自动评估可行性,符合条件的需求由 Agent 编码、测试并提交 PR,维护者审查合并后自动发版。完整流程见 Agent 工作流说明。
| 平台 | 账号 |
|---|---|
| 𝕏 Twitter | @ChengYi3629 |
| 📕 小红书 | 程意 |
代码与 Skill 指令采用 MIT License。示例图片只用于展示输出效果;输入视频、生成图片及其中出现的第三方内容,不因本许可证获得额外授权。
830 followers · starred Sep 2026
180 followers · starred Oct 2026
19 followers · starred Oct 2026
43 followers · starred Sep 2026