@speclip/pi-subtitles
v0.2.1
Published
Agent-reviewed subtitle timing, layout, and standard track export for Pi
Maintainers
Readme
@speclip/pi-subtitles
给 Pi 使用的字幕决策插件包。它把 ASR 词级时间戳映射到完成 A-roll 剪辑后的成片时间轴,由 Agent 审阅断句、标点和换行,再导出可追溯的 UTF-8 SRT / ASS 字幕轨道。
它不直接烧录视频,也不把任意 FFmpeg 参数塞进 Agent 工具。字幕判断与视频渲染保持分离:本包负责“字幕写什么、何时出现、如何分行”,支持字幕轨道的渲染器负责最终画面合成与视觉验收。
能力边界
- 输入:
pi-speech兼容的词级 JSON 转录,也兼容常见{ word, start, end }秒级结构。 - A-roll 映射:按保留源片段压缩时间轴;字幕不会跨越剪辑点。
- 自动分段:结合标点、停顿、字数、时长和阅读速度生成初稿。
- Agent 审阅:通过不可变 revision 修正 ASR 文本、标点和断句;横屏项目强制单行,审阅阶段也不能绕过。
- 导出:标准 SRT;可选带横屏/竖屏安全区预设的 ASS;两者都不覆盖已有文件。
- 溯源:绑定原转录哈希、精确 revision、输出哈希和持久化导出回执。
B-roll 只覆盖画面而保留 A-roll 主音频时,不会改变字幕时间。若后续改变了语速、主音频或 A-roll 片段顺序,应新建字幕项目。
环境要求
- Node.js 22.19+
- Pi 0.84.1–0.84.x
- 一份含词级时间戳的 JSON 转录
安装与验证
npm install
npm run check
pi install ./也可以安装发布包:
pi install npm:@speclip/pi-subtitles工具工作流
1. 创建字幕项目
无 A-roll 剪辑时,只传源时长:
subtitles_create {
projectId: "launch-captions",
transcriptPath: "transcripts/launch.json",
sourceDurationMs: 93224,
layoutPreset: "landscape"
}有 A-roll 剪辑时,必须传最终保留的源区间:
subtitles_create {
projectId: "launch-captions",
transcriptPath: "transcripts/launch.json",
sourceDurationMs: 93224,
timelineSegments: [
{ id: "a-001", sourceStartMs: 0, sourceEndMs: 12400 },
{ id: "a-002", sourceStartMs: 13100, sourceEndMs: 28700 },
{ id: "a-003", sourceStartMs: 29400, sourceEndMs: 93224 }
]
}计算关系为:
成片时间 = 前面所有保留片段的累计时长 + 词源时间 - 当前片段源起点若一个词跨过剪辑边界,工具会拒绝创建,要求回到 A-roll 调整到词间安全边界。
2. 分页审阅全部字幕
subtitles_get {
projectId: "launch-captions",
offset: 0,
limit: 100
}自动结果只是初稿。Agent 应结合实际音频检查文本、术语、标点、语义分组、阅读速度和画幅布局,并继续翻页直到 hasMore: false。
layoutPreset 默认为 landscape:横屏字幕严格单行,每条最多 16 个可见字符,目标 8–16 字。portrait 允许最多两行。两种画幅都以 1.5–4.5 秒、约 9 字/秒为节奏参考;这些节奏值用于找自然断点,不要求每条机械一致。
3. 写入 Agent 审阅版本
subtitles_apply {
projectId: "launch-captions",
expectedRevision: 1,
changeReason: "核对音频后修正产品名和语义标点",
cues: [
{ id: "cue-001", beginMs: 320, endMs: 2840, text: "这是修正后的第一条字幕。" }
]
}cues 必须是完整列表,不是某一页。时间必须递增、不重叠,且不能超过成片时长。expectedRevision 防止并发审阅互相覆盖;每次成功都会产生新的不可变快照。
4. 导出标准轨道
subtitles_export {
projectId: "launch-captions",
revision: 2,
srtPath: "deliverables/launch.zh-CN.srt",
assPath: "deliverables/launch.zh-CN.ass"
}工具会按项目画幅自动使用安全区样式,并返回 SRT / ASS 文件引用、SHA-256 和持久化导出回执。横屏使用固定 1920×1080 ASS 设计坐标,竖屏使用 1080×1920;这与源视频是 1080p 还是 4K 无关,libass 会等比缩放。不要把 4K 源分辨率直接写成 ASS 的 PlayRes。
横屏和竖屏统一使用 Source Han Sans SC Heavy。白色字形不再附着黑色描边,而是使用向右下偏移的半透明黑色柔化阴影;横屏保持下方安全区,竖屏仍上移并扩大右边距,避开常见交互区。字体、阴影和几何参数只能在安全范围内微调。渲染环境必须真实安装该字体,不能依赖静默字体回退。
本包的完成状态是“字幕轨道已生成并校验”,不是“字幕已经烧进视频”。最后应把轨道交给支持字幕的渲染器,并检查实际成片中的同步、遮挡、安全区、字体回退和漏字。
工作区数据
项目状态保存在:
.subtitles/projects/<projectId>/
├── project.json
├── snapshots/<revision>.json
└── exports/<exportId>.json源转录与导出文件都不会被覆盖。源转录字节变化后,旧项目会拒绝继续导出,避免把新内容误配到旧时间轴。
开发
npm ci
npm run check
npm pack --dry-runGitHub Release 标签必须与 package.json 完全一致,例如 v0.2.1。发布工作流会在标签快照上重新执行检查并通过 npm OIDC 发布。
License
MIT
