技术配方
按整数帧时间线组装视频分镜
把已解码 CFR/VFR 源映射到逐镜整数帧预算,检查真实的 22 帧、24fps 示例,以及切点图像与末帧时长。
v24.18.0; ffmpeg version 6.0 Copyright (c) 2000-2023 the FFmpeg developers; ffprobe version n4.4.1 Copyright (c) 2007-2021 the FFmpeg developers · acacbe00027ce51deb248c719def42893a97abd9 · 环境与执行范围见正文。
练习素材示意,不代表模型生成效果。
按整数帧时间线组装视频分镜
当多段已准备好的视频必须占用准确的输出帧数时,使用这套离线方法。先区分源时间戳与输出帧网格,再检查每个切点两侧究竟是哪一张图像。
示例使用原创几何画面与一份真实的 22 帧 MP4。2026 年 10 月 17 日,使用 Node v24.18.0、FFmpeg 6.0 和 ffprobe n4.4.1 完成了编码、解码及检查,并测试了三个受控负例。这是本地技术结果,不是 MiniMax H3 输出,也没有进行模型生成或调用提供商。尚未进行人工播放与观感评审。
先用帧数定义交付
把输出帧率写成有理数,例如 24/1,为每个镜头指定整数 outputFrames。各镜头之和必须等于 expectedTotalFrames。已记录的 24fps、22 帧夹具准确时长为 11/12 秒,不用播放器四舍五入后的秒数验收。三个镜头分别占 7、7、8 帧;按从 0 开始编号,两个切点位于第 6/7 帧和第 13/14 帧之间。
以更长的交付计划为例:3:24、24fps 对应 204 秒、4,896 帧;25 段完整八秒镜头占 4,800 帧,最后还需 96 帧。这只是规划计算:配套测试实际只编码 22 帧,没有编码 204 秒,也不证明长片源素材已经存在或模型能一次生成整段。
读取源视频的真实时间戳
准备命令会绘制 25 张原创 PNG 输入与三份 SVG 设计草图。每张栅格图都有源与帧编号标记,并包含移动的几何元素。原输入中 A 有 8 张、B 有 10 张、C 有 7 张;真实运行前后,这 25 张 PNG 的实际哈希全部一致。
编码后再解码得到的库存分别为 8、10、8 帧。变帧率 C 的 concat 输入会重复末张图,因此第八个解码帧不是新画出的第 26 张输入。A 实测为 24000/1001 fps、time base 为 1/48000;B 的相邻 PTS 间距为 40ms、time base 为 1/51200。C 从 2 秒开始,实际 PTS 依次为 2.00, 2.04, 2.12, 2.24, 2.28, 2.36, 2.40, 2.44 秒。
必须把原始观测与显示规则分开。C 的 ffprobe 对每帧都报告 pkt_duration=2048、time base 为 1/51200,即 40ms;部分相邻 PTS 却相隔 80 或 120ms。本包保留原始 packet 时长,不把它改写成“ffprobe 实测了更长的显示时长”。记录中的 shot-a.probe.raw.json、shot-b.probe.raw.json、shot-c.probe.raw.json 保留实际 stdout 字节,并通过哈希绑定到解码库存。
让每个镜头绑定到真实源文件
EDL 每行包含镜头 ID、源 ID、准确的源文件 SHA-256、相对源起点的偏移与输出帧预算。源的首个解码 PTS 是其时间原点:源从两秒开始,不应因此在成片前面添加两秒空白。
声明的协议为 active-at-or-before-no-interpolation:每个目标时刻选择 PTS 不晚于该时刻的最后一帧。对非末帧,实际采用的显示窗口明确推导为 下一实际 PTS - 当前实际 PTS。这是协议推导的保持窗口,不是探针报告的 packet 时长。末帧没有下一 PTS,必须使用实际读取到的正数 duration 或 pkt_duration。时长缺失或为零、PTS 不递增、区间越界或采样点落在覆盖空隙都会失败,不用平均 FPS 猜测。
区间含开始、不含结束。规则可以重复或丢弃源图像,不生成新运动。不要为了凑时长偷偷改速度;需要调整时,明确修改源区间或帧预算,记录决定后重建映射。文件分给错镜头时,先看镜头身份与文件绑定。
先准备输入,不编码视频
在解压后包含 run-recipe.mjs 的目录运行:
node --test frame-budget.test.mjs encoded-negative-cases.test.mjs
node run-recipe.mjs --out ./new-original-inputs输出目录必须不存在。准备命令只绘制原创栅格输入,并写入 mediaExecuted:false 的状态。即使下方另有已执行的记录,默认入口仍然不编码。它不联网、不提交模型任务、不生成编码视频。随包逻辑与准备测试有助于检查规则,但纯测试通过本身不是编码运行回执。
查看已记录运行,或另开目录重跑
成功运行记录位于 media-runs/actual-small-root-20261017-02/,其中 media-execution-receipt.json 的时间为 2026-10-17T01:33:47.353Z。command-log.json 记录了 48 次成功工具调用;该运行产出 22 帧正片,检查两个切点和全部 22 帧源标记,并执行下方三个真实负例。正片文件为 assembled-review.mp4,SHA-256 为:
3b624e031f6a082e2ac2ae89b8c36cb91873bd67c5d64f8c5fa1427059db96f1无需重新调用工具,也能把 MP4 与原始源探针、解码库存、EDL、帧映射、标记证明及输出探针一起查看。命令日志记录实际工具调用,runtime-source-binding.json 标识执行源码。复现比较时,把这些记录与结果成套保存。
要重新运行,使用另一个不存在的输出目录与已安装的本地工具:
ALLOW_LOCAL_MEDIA_EXECUTION=1 node run-recipe.mjs --out ./new-media-run --execute-media --ffmpeg /absolute/path/to/ffmpeg --ffprobe /absolute/path/to/ffprobe显式开关会启用本地媒体执行。脚本使用 96×64 小输入、串行工具调用、单线程设置、进程超时和有上限的缓冲区;先编码源、实读解码时间戳和真实哈希,把选中标记与原始输入定义核对后,再组装 22 帧 MP4 并检查三个小负例。已记录工具版本只是一套实际通过的配置,不保证任意 FFmpeg 构建都支持;缺少滤镜、FFV1 或 libx264 就失败,不安装工具或调用外部服务。
该命令不会编码 204 秒夹具。全长基准需要另一次真实运行与回执。
检查解码成片与负例对照
小夹具的技术验收要求三个条件同时成立:实际解码帧数等于预算;所有 PTS 位于声明的 CFR 网格;每一帧的源/编号标记都符合规划位置。已记录正片在 24fps、11/12 秒下通过这些检查。单有正确时长,仍不能证明切点接上了正确画面。
把源哈希、原始探针、解码库存、EDL、完整帧映射、原创标记证明及编码/探测命令与输出放在一起。原始探针和库存/EDL 会在规划前保存,因此规划失败也能留下诊断事实,但不会获得成功回执。正负例共用同一个校验器,并读取实际 packet 的 PTS、DTS 和时长。
帧索引从 0 开始:索引 7 是第 8 张画面,索引 21 是末帧。已记录运行中,三个负例都实际经过编码或容器修改、解码及探测,各自只出现预期的一条问题,没有第二处校验缺陷:
| 已记录产物 | 受控差异 | 实际唯一拒绝理由 |
|---|---|---|
negative-media/short-21-of-22.mp4 | 解码图像、frame 观测与 packet 均为 21,而非 22 | OUTPUT_FRAME_COUNT |
negative-media/wrong-cut-image.mp4 | 仍为相同网格的 22 帧;从 0 编号的第 7 帧图像错误 | 第 7 帧 OUTPUT_FRAME_ID_MISMATCH |
negative-media/bad-terminal-duration.mp4 | 22 张图像、PTS 和编码 sample 字节不变;末帧时长减半 | 第 21 帧 OUTPUT_TERMINAL_DURATION |
最后一项修改真实 MP4 的 sample 时序字节,不修改探针 JSON。修改器只接受本夹具的单视频轨、无分片/编辑列表、moov 在 mdat 后且为最后 box、无显示重排、media time scale 为 24,000、正常每帧 1,000 tick 的布局。它保留 21 个正常 sample,把末帧时长改为 500 tick,同步容器时长并保留媒体数据。实际正负观测各有 22 个 frame 与 packet;正例全部时长和负例前 21 个时长均为 1,000 tick,负例末 frame 与 packet 都为 500 tick。packet 位置、全部 PTS/DTS 和 22 个编码 sample 的 payload 哈希均保持一致。时长缺失、非法或为零会导致观测失败,不能算负例通过。
编码失败、探测失败、不支持的容器或意外校验问题都不能当作成功负例。默认仅准备输入的命令仍把这些用例列为 planned;已执行结果记录在另存的真实媒体运行中。时序与标记检查不能判断创意切镜是否好看;使用自己的素材时,另行检查运动、光线和叙事衔接。
如果源本身姿态或光线跳变,准确组装会保留跳变。检查某一张源帧时,使用按时间戳取帧;素材是静态图片时,使用已有的PNG 序列审片流程。
保持页面的职责
本页用于片段已经存在之后的时间线与切点身份检查。策划各个镜头时,可先浏览实用工作流。开始组装帧时间线前,用镜头清单记录创作决定与通过的片段版本。准确组装会保留输入的画面,也会保留素材本身不理想的视觉跳变。
原创示例代码与夹具随附 LICENSE.txt,包内不含 FFmpeg、ffprobe 可执行文件。技术参考为 FFmpeg 官方 concat、fps 和 setpts。结合配套观测检查示例;文档里存在某条命令,并不代表你的导出文件已经正确。