人物小窗 + 知识卡片轮动视频(pip-knowledge-card-video)
一句话定位
丢给我 一段真人竖屏视频 + 一份分镜文案,我产出 一条 1080×1920 竖屏成片:
左上真人口播小窗 + 右侧同高标题列 + 3~4 节点流程条 + 白色知识卡片逐场景轮动 + 底部字幕条。
何时触发
用户说「做个真人小窗+知识卡片的视频」「口播视频配卡片」「人物小窗和文字轮动」「把这段文案做成讲解视频」,
或直接发来一段真人口播视频 + 文案,要求做成竖屏讲解片时,直接走本 skill。
输入 / 产出
| 说明 | |
|---|---|
| 输入 1 | 真人竖屏视频(有原声;mp4/mov 均可,1080×1920 最佳) |
| 输入 2 | 分镜文案:按「场景」拆成若干段,每段给 kicker(小标签)、headline(大标题,可 1~3 行)、sup(副标题)、points(要点,逐条出现) |
| 产出 | out/成片.mp4(1080×1920 / 30fps / H.264 + AAC 原声)+ 关键帧预览图 + 发布文案(标题×3 + 5 个标签) |
> 字幕两种模式:简单整行用 caps(模板默认);要"播到哪字亮哪字"的卡拉OK效果用 karaoke(examples/scenes_karaoke.json 为完整示例)。
> 出片必带发布文案:每次交付都要给 ① 推荐标题(主推 + 2~3 个备选)② 5 个通用发布标签(带 #)③ 可直接粘贴的正文,存成 out/发布文案.md。不要等用户追问。
快速开始(3 步)
# 1) 编辑分镜(也可直接改 examples/scenes.json 当模板)
vi examples/scenes.json
# 2) 一键出片(渲染背景 + 合成小窗与原声)
bash scripts/build.sh "/path/to/真人视频.mp4" examples/scenes.json out/成片.mp4
# 3) 改版式时先单帧预览,不必整片重渲(默认抽 3/20/46 秒)
bash scripts/preview.sh "/path/to/真人视频.mp4" 3 20 46
分步也可以:
bash scripts/render_bg.sh examples/scenes.json work/bg_silent.mp4 # 只渲无声背景
bash scripts/compose.sh "/path/to/真人视频.mp4" work/bg_silent.mp4 out/成片.mp4 # 只合成
分镜数据格式(scenes.json)
{
"branding": { // 顶部右侧标题列
"brand": "AI干货 · 星瑶", // 左上品牌胶囊
"title": "单图三镜头", // 大标题
"subtitle": "一张照片,能动的只有三样" // 副标题
},
"flow": { // 中间横向三要素流程条
"sticker": "1 张图 → 1 条片", // 右下角橙贴纸
"nodes": [
{"label": "环境", "sub": "只让云雾动"},
{"label": "人物", "sub": "只让人动"},
{"label": "镜头", "sub": "只让镜头动"}
]
},
"scenes": [
{
"id": "s1", // 唯一 id
"start": 0.0, // 起始秒(与上一场景无缝衔接)
"dur": 5.0, // 持续秒
"variant": "v-a", // v-a / v-b / v-c:卡片强调色(青/橙/红)
"kicker": "开场", // 卡片顶部小胶囊
"headline": ["同一张照片", "丢给 <span class=\"hl\">AI</span>"],
"fs": 96, // 可选:强制字号;不填自动按字数
"sup": "同样的素材,十个人十条片子",
"points": [["人定住,像延时摄影", 1.0], ["适合突出人", 3.6]],
"flow": [1, 2, 3] // 本场景点亮流程条的第几个节点
}
],
"caps": [ // 底部字幕,[文本, 出现秒, 消失秒]
["同一张照片丢给 AI。", 0.0, 5.0]
]
}
规则
- headline 里每行用 <span class="hl">词</span> 标出高亮词(会渲染成强调色);<span class="cl"> 由脚本自动包,不用手写。
- points 的第二个数字是相对本场景起点的偏移秒;不填 null 则不出要点。
- flow.nodes 支持 3 或 4 个节点(nodes 数组长度决定);scene.flow 写本场景要点亮的第几个节点(如 [1,2,3] 或 [1,2,3,4])。流程条会自动按节点数排布并配色。
- 底部字幕支持两种格式(二选一,脚本自动识别):
- caps(整行,简单):[文本, 出现秒, 消失秒],整行一次性显示,不做逐字点亮。例:["同一张照片丢给 AI。", 0.0, 5.0]。
- karaoke(逐字卡拉OK,推荐):见下方结构——每个字带真实发声时刻 t,播到哪个字哪个字变暖黄高亮。时间轴必须与真人声对齐(转写工具见 README)。
"karaoke": [
{"show": 1.70, "hide": 5.80, "chars": [["一",1.70],["部",1.92],["手",2.14],["机",2.36]]},
{"show": 6.10, "hide": 9.00, "chars": [["第",6.10],["一",6.30],["步",6.50],[",",6.70]]}
]
- 时间必须是绝对秒,且覆盖 0 ~ 总时长。总时长 = 最后一个 scene 的
start + dur。 start/dur与真实人声节奏对齐,字幕才不会飘(转写工具见 README)。examples/scenes_karaoke.json是一份完整卡拉OK示例(逐字对齐到真实口播)。
可调参数(config.json)
| 键 | 默认 | 说明 |
|---|---|---|
paths.* |
本机路径 | python / node / ffmpeg / hyperframes / chrome 绝对路径,可用同名环境变量覆盖 |
pip.w pip.h |
340 / 356 | 真人小窗尺寸;改这里同时要改 assets/style.css 的 .pipbox(两处必须一致) |
pip.x pip.y |
40 / 44 | 小窗左上角坐标;改这里也要同步 .topbar 的 left/top |
pip.corner |
44 | 圆角半径(geq 实时算遮罩) |
pip.border |
5 | 白描边宽度 |
pip.crop_offset |
0.22 | 源视频竖向裁切位置(0=顶部,1=底部) |
render.fps |
30 | 帧率 |
render.quality |
delivery | HyperFrames 画质档 |
只改配色/文案不用改代码:配色在 assets/style.css 的 :root 与 index.html 内联 :root;文案全在 scenes.json。
环境依赖
| 组件 | 用途 | 找不到时 |
|---|---|---|
| Python 3 | 生成 index.html | PYTHON=/path/python bash ... |
| Node + HyperFrames | 把 HTML 渲成视频 | HYPERFRAMES=/path/hyperframes.mjs NODE=/path/node bash ... |
| chrome-headless-shell | HyperFrames 的渲染内核 | HF_BROWSER=/path/chrome-headless-shell bash ... |
| ffmpeg | 小窗合成、抽帧 | FFMPEG=/path/ffmpeg bash ... |
三条命令都读 config.json,也都能用上面这些环境变量临时覆盖,换机器只改 config.json 的 paths 即可。
Agent 执行工作流
- 读视频时长与音轨:
ffprobe -v error -show_entries format=duration -of csv=p=0 <视频>;确认有音轨(本片用原声,不加 TTS)。 - 拆分镜:按文案语义切成场景,
start累加,最后一个场景的start+dur= 视频时长;字幕按句子切分。 - 写
scenes.json:套用examples/scenes.json结构,品牌/大标题/副标题按客户账号改。 - 单帧预览:
bash scripts/preview.sh <视频> 3 <中间点> <结尾点>,看三帧版式(顶部是否同线、卡片是否压字、字幕是否出界)。 - 整片出片:
bash scripts/build.sh <视频> scenes.json out/成片.mp4(渲染约 15~25 分钟,建议后台跑)。 - 抽帧校验:从头/中/尾各抽一帧确认无黑帧、无错位。
- 交付:成片 + 预览图 +
out/发布文案.md(标题×3 + 5 标签 + 正文)。
设计规范(改版式时别破坏)
- 顶部一条线:小窗
340×356 @ (40,44),右侧标题列四行绝对坐标对齐(44 → 400),不要用 flexspace-between(会让末条与窗底差 40px)。 - 内容卡从 y≈620 起、宽 1000、圆角 40,左侧 13px 青色竖条;卡片内文字左对齐、整体居中。
- 要点强调条:
18×6圆角、left:24、top:50%垂直居中,padding-left:58,不许贴字(贴字会像错字)。 - 小窗圆角:必须用 ffmpeg
geq实时算(mask PNG 用 scale 会把圆角拉成椭圆,alphamerge 黑底会让窗内发白)。 - 背景:
assets/bg_wall5.jpg+ 顶部柔光 + 绿灰渐进压暗,别调亮到抢内容卡。
常见坑
| 现象 | 原因 / 解法 |
|---|---|
window.__hf not ready after 45000ms / HTTP500 index.html |
Windows 下 Chrome 要写 puppeteer 配置、读系统字体,被沙箱拦了 → 渲染这步需要放开沙箱(或用 dangerouslyDisableSandbox)。沙箱 stderr 里 KERNELBASE.dll.mui 之类告警非致命,看 EXIT=$? 和成片为准。 |
| 小窗里全白 / 圆角变椭圆 | 用了 mask PNG。改用 compose.sh 的 geq 方案。 |
| 字幕与声音不同步 | caps 时间没对齐人声。先转写(README 给命令)再填时间。 |
| 视频比预期短/长 | 总时长 = 最后 scene 的 start+dur,HyperFrames 按这个渲;合成时 -shortest 取音频与视频较短者。 |
| 卡片文字压到流程条 | .scene{padding-top:620px} 是安全区,别小于 620。 |