先找第一次卡顿出现在哪一层

画面静止时很清晰、运动时却一顿一顿,先不要把问题归为模糊、音画不同步或动作生成过慢。把同一动作附近的四次观察写在一张表中;每次都从同一入点开始,以正常速度播放,不边看边改。

对比结论与下一步
原片在同一播放器已经运动不均匀检查原生拍摄帧率、快门与主体位移;另选镜头或重新拍摄。提高导出帧率只能重复现有画面,不能补回没拍到的动作。
原片正常,剪辑中间片首次卡顿检查时间线解释、速度变化、代理替换和中间片导出;先修这一层,不继续压最终版。
中间片正常,最终导出片首次出现规律性停顿对照正常中间片逐帧核画面和时间戳,检查重复或漏掉的运动状态,再决定是否从中间片制作恒定帧率候选。
同一最终文件在播放器 A 卡、播放器 B 正常先降低播放分辨率或关闭昂贵叠加,检查硬件解码和系统负载;保留同一文件,避免把播放器过载误判为文件节奏。

用文件哈希或绝对路径确认两个播放器打开的是同一份成片。播放器比较只能定位故障层,不能作为任一播放器已通过交付复核的证据。若原片本来就是低帧率快速横移,本文的恒定帧率候选不会恢复缺失的运动采样。

探测解码帧时间,不只看一个帧率数字

为原片、中间片和最终片分别运行下面的只读命令,并把 JSON 与文件路径一起保存:

ffprobe -v error -select_streams v:0 -show_entries format=duration:stream=codec_name,width,height,avg_frame_rate,r_frame_rate,time_base,duration:frame=best_effort_timestamp_time,duration_time -of json INPUT

逐帧查看 best_effort_timestamp_time 的间隔是否稳定、是否出现相同画面跨多个时刻,以及变化从哪一层开始。本文实际检查过自生成样本的这组输出;当前 ffprobe 9.0.1 返回 duration_time,因此命令没有使用旧字段 pkt_duration_time。字段是否存在仍取决于文件和构建;缺失时记录“未报告”,不要补造数值。

avg_frame_rate、r_frame_rate 与 time_base 是线索,不是运动质量结论。还要记录第一帧时间、最后一帧时间、帧数、容器时长和预期切点。可变帧率素材不因数值变化就自动有错;恒定帧率也不排除大量重复画面。可另存解码帧哈希:相邻相同哈希能确认像素完全相同的重复;有损编码后哈希不同,仍可能是同一来源画面,不能据此排除重复。漏掉画面的判断要对齐正常中间片的画面、时间戳和动作顺序,逐帧核查,不能只看哈希。

实测边界:24 转 30 只复制了既有画面

本地使用 FFmpeg 9.0.1 生成了 320×180、24 fps、2 秒的 testsrc2,编码为无损 FFV1 Matroska,不含音频;随后用外部 fps=30 滤镜重编码为另一份 FFV1 文件。结果只支持滤镜机制与时间戳观察。

实测项结果
输入与输出解码帧数48 → 60
输入与输出唯一像素哈希数48 → 48
输出相邻重复转换12 次
输出画面来源60 帧的像素哈希全部来自输入;48 个输入哈希全部保留。
解码时间戳输入首帧 0.000 秒、末帧 1.958 秒;输出首帧 0.000 秒、末帧 1.967 秒。
量化边界Matroska 的毫秒时间基使输入间隔显示为 0.041/0.042 秒,输出为 0.033/0.034 秒。

这次测试没有正常速度观看,没有使用真实摄影、可变帧率或音频,也没有完成生产链路。它没有证明观感更顺、没有证明任何真实素材会保留全部画面,也没有证明时长或同步通过。它只表明这一受控样本从 24 转 30 时新增了重复帧,没有合成新的运动状态。

只有交付帧率已确认时,才做外部候选

先从书面交付规范、已接受的同系列母版或明确的项目设置确认目标帧率。下面以已确认的 30/1 为例;若证据不是 30/1,就不要照抄。把最后一份已确认正常的中间片指定为 ACCEPTED_INTERMEDIATE;原片与坏导出片只作对照,不能从已漏帧的坏导出片恢复画面。输入保持只读,输出到新路径:

ffmpeg -n -i ACCEPTED_INTERMEDIATE -map 0:v:0 -vf fps=30 -an -sn -c:v libx264 -pix_fmt yuv420p cadence-candidate-30.mp4

这是画面专用诊断候选。fps 滤镜通过复制或丢弃既有画面建立恒定帧率;滤镜要求解码、过滤和重新编码,不能搭配 -c:v copy。不要用改变播放速度来凑时长,不要把输出 -r 当成本文已验证的等价修复,也不要把重复帧描述为运动插值。

采用默认边界行为前,核对输入首个 PTS、源时钟、预期入点与尾端。若必须设置 fps 的 start_time、round 或 eof_action,先根据当前交付的首帧与尾帧规则写出预期,再逐帧验证;本文不为未知素材指定通用值。较高帧率也不是通用修复:若原片只含低频运动采样,输出仍只是更密地安排既有画面。

音频没有进入上面的候选。只有画面候选的时长、切点和边界符合计划后,才把已采用音轨作为独立资产进入下游合成;明确核对采用版本、首尾、完整试听与同步。本文不承诺音频会因画面重采样自动保持不变。

原创案例:河堤壁画短片的首个故障层

“风沿着墙走”是本文虚构的教学案例。创作者拍了一段骑行者掠过河堤壁画的短片:暂停时车轮辐条和壁画字母都清楚,导出后横移却每隔几步停一下。案例没有真实媒体、播放测试或成功结果。

创作者先把原片 ridge-ride-source.mov、剪辑中间片 ridge-ride-edit.mov 和最终片 ridge-ride-final.mp4 放进同一播放器,从骑行者进入蓝色字母的时刻开始观察。原片与中间片的运动一致,最终片首次出现规律停顿;同一最终文件在另一个播放器仍出现相同节奏。这个纸面证据把下一步限定为最终导出的时间戳与重复帧检查;锐化与播放器设置暂不调整。

假设探测随后显示项目交付规范已明确为 30/1,并且最终片的重复模式由该导出层新增,创作者才从已确认正常的 ridge-ride-edit.mov 制作 picture-only cadence-candidate-30.mp4;ridge-ride-final.mp4 只保留为故障对照。候选状态写“等待边界与观看复核”,不写“已修好”。创作者对照中间片核查第一帧、最后一帧、骑行者经过每个字母的切点和总时长,再以正常速度在目标设备完整观看。若节奏仍不可接受,就保留证据并回到原始拍摄/镜头选择;不会继续把帧率抬高来制造成功。已采用的环境声独立交给后续装配,并在合成后完整试听与检查同步。

用这张表决定候选能否交给普通剪辑

机械检查、正常速度观看与声音检查分别记录。任何一栏未完成,文件仍是兼容性候选,不是已修复母版。

记录项填写内容
故障层原片 / 中间片 / 最终片 / 特定播放器;同一动作的观察入点。
帧证据三个文件的 ffprobe JSON;首末 PTS、帧数、间隔模式;重复与漏帧以正常中间片对齐核查,记录哈希的有损限制。
目标依据已确认的交付帧率与来源;不是“越高越好”。
候选命令完整画面命令、编码器、滤镜值、输出路径与文件哈希。
边界检查时长、第一帧、最后一帧、每个切点与字幕/画面事件落点。
实际观看目标设备正常速度完整播放;横移、快速主体和过剪点的真实观察。
采用声音独立音轨的版本/哈希;完整试听、首尾、同步和采用内容。
决定通过后才写“可进入普通编辑”;否则写失败位置和下一候选。

固定版 Video Recap 的多来源剪辑会从所用素材选择输出帧率,并在拼接前把每段归一化到该帧率;普通装配路径按视觉操作决定复制画面或编码 H.264 yuv420p,但没有面向任意成片的通用 FPS 修复旋钮。因此本文的候选是外部、待验证的兼容性输入。检查通过后,才把它和独立确认的已采用声音交给普通 Video Recap 编辑;不要把这一步描述为该 skill 原生修复了所有卡顿。

常见问题

把 24 fps 导出成 60 fps 会更顺吗?

不能据此保证。fps 滤镜只能复制或丢弃已有画面;提高数字不会恢复未拍到的运动状态。先定位第一次失败的阶段,并使用已确认的交付帧率制作待观看候选。

为什么帧率显示 30,画面仍会卡顿?

一个帧率数字无法显示相邻画面是否重复、时间戳是否均匀,也无法排除播放器解码过载。对比各阶段,检查解码帧时间戳和画面哈希,再用另一播放器打开同一文件。

用 skill 来做

用 $video-recap 从我已完成正常速度观看、边界检查和声音采用核对的兼容性候选继续普通视频回顾编辑。候选路径、文件哈希、确认的帧率依据和独立采用音轨都在交接表中。请把外部帧率诊断记录保留为上游证据,不把它描述成该 skill 的通用原生 FPS 修复;先读取实际媒体,再规划剪辑、旁白、字幕和新输出,并报告仍需人工观看、试听的项目。

查看具体方法: 多来源剪辑的帧率归一化 · 多来源输出帧率选择 · 普通装配的复制与重编码边界 · Video Recap 普通编辑与交付复核 · FFmpeg fps 滤镜官方文档 · ffprobe 官方文档

了解 Video Recap Skills在 GitHub 查看 video-recap

全部指南