Composer无法检测或清理关键帧——它只是PHP依赖管理工具,不处理视频、动画或时间轴数据;关键帧属FFmpeg、Jetpack Compose、Lottie等工具范畴。

Composer 是 PHP 的依赖管理工具,它不处理视频、动画或关键帧(keyframe)——这些属于视频编码(如 FFmpeg)、前端动画(CSS/JS)或专业创作软件(如 After Effects)的范畴。
所以:Composer 无法检测或清理密集关键帧,它根本不知道“关键帧”是什么。
如果你在视频处理、Web 动画或 Lottie 场景中看到“Composer”这个词,很可能是混淆了:
- Android 的
Jetpack Compose(声明式 UI 框架),它用animate*AsState或Transition控制动画,但也不直接暴露“关键帧密度”这个概念; - 或者误把
ffmpeg、ffprobe、lottie-web、gsap等工具当成了 Composer。
下面分场景说清楚「怎么做」和「为什么容易搞错」:
用 FFmpeg 检测并删减视频关键帧(I帧)
视频的关键帧(I-frame)由编码器决定,密集 I 帧会增大体积、影响流媒体缓冲。FFmpeg 可强制重编码并控制 GOP(Group of Pictures)结构:
-
ffmpeg -i input.mp4 -c:v libx264 -g 250 -keyint_min 250 -sc_threshold 0 -c:a copy output.mp4:强制每 250 帧一个 I 帧,禁用场景切换插入(-sc_threshold 0) -
ffprobe -show_frames -select_streams v:0 input.mp4 2>/dev/null | grep "pict_type=I" | wc -l:统计原始 I 帧数量 - 注意:
-g是最大 GOP 长度,-keyint_min是最小,二者相等才能严格固定 I 帧间隔 - 盲目删 I 帧会导致解码失败——你只能重编码时“减少密度”,不能从已编码流里“抠掉”个别 I 帧
在 Jetpack Compose 中避免动画卡顿(常被误称为“关键帧太密”)
Compose 的动画基于状态驱动,没有传统时间轴上的“关键帧”。所谓“太密”,通常是 animate*AsState 被高频更新触发,或 LaunchedEffect 内反复启动动画:
- 检查是否在
remember外部、或mutableStateOf赋值过于频繁(比如 onTouchEvent 里直接改 state) - 用
Animatable.snapTo()替代连续animateTo(),避免堆积未完成动画 - 开启
Logcat过滤Animation,看是否有Skipped frames或Animation is already running报错 - 不要用
withFrameNanos手写关键帧循环——Compose 不需要、也不鼓励这种底层控制
解析 Lottie JSON 并调整关键帧采样(非 Composer,但常被混提)
Lottie 动画导出的 JSON 文件里有 layers[].ks.k(关键帧数组)。所谓“密集”,其实是 AE 导出时启用了“关键帧缩减”(Keyframe Reduction)没生效:
- 用
lottie-api或简单JSON.parse()读取后遍历k数组,按时间戳去重或插值降采样(需保留首尾帧) - 更稳妥的是回 AE 修改:合成设置 → “关键帧缩减”调高(如 95%),再重新导出
- 注意:Lottie Web 渲染器本身会做运行时插值,原始 JSON 关键帧多≠播放卡——除非文件体积暴涨导致加载/解析慢
关键点就一句:所有“关键帧”相关操作都发生在媒体处理链或 UI 框架层,Composer 只负责下载 vendor/autoload.php 和执行 composer install——它连视频文件都不会打开。
如果命令行里真出现了 composer + “关键帧”组合,大概率是脚本里混写了其他工具调用,得顺着 exec() 或 shell 脚本往底层扒。


















