如何在FFmpeg中使用自定义曲线函数实现视频淡出?
实现FFmpeg自定义曲线的视频淡出效果
我之前也碰到过这个问题——fade滤镜确实只有线性过渡可选,没法像afade那样直接切换曲线,但geq滤镜绝对是解决这个需求的利器,我给你拆解下具体怎么实现:
核心思路
geq(Generic Equation)滤镜允许你通过数学表达式直接控制每个像素的RGB值,我们只需要给原像素值乘以一个随时间变化的“衰减系数”,这个系数的变化曲线就是你想要的淡出过渡曲线,和你用volume滤镜做音频自定义淡出的逻辑完全一致。
具体实现示例
1. 对应你音频的正弦曲线淡出
假设你的视频要从第3秒开始,用2秒时间完成正弦曲线的淡出(和你音频用的(sin(PI/2 * min(1, max(-1, 1/2 * (t - 3)))) + 1)/2逻辑匹配),可以用这个命令:
ffmpeg -i input.mp4 -vf "geq=r='r(X,Y)*(sin(PI/2 * min(1, max(0, (t - 3)/2))) + 1)/2':g='g(X,Y)*(sin(PI/2 * min(1, max(0, (t - 3)/2))) + 1)/2':b='b(X,Y)*(sin(PI/2 * min(1, max(0, (t - 3)/2))) + 1)/2'" -c:a copy output.mp4
- 表达式里的
(t - 3)/2是计算当前时间在淡出周期内的比例(0到1之间); min(1, max(0, ...))用来把比例限制在0-1区间,避免淡出开始前或结束后出现异常;- 正弦部分
sin(PI/2 * ...)把线性比例转换成平滑的S型过渡,最后+1)/2是把正弦输出的[-1,1]范围映射到[0,1]的衰减系数范围。
2. 简化写法(针对全颜色通道)
如果不想分别写RGB三个通道的表达式,可以用lum_expr参数,它会把亮度调整应用到所有颜色通道,更简洁:
ffmpeg -i input.mp4 -vf "geq=lum_expr='lum(X,Y)*(sin(PI/2 * min(1, max(0, (t - 3)/2))) + 1)/2'" -c:a copy output.mp4
3. 其他自定义曲线示例
你可以替换表达式里的曲线部分,实现任意过渡效果:
- Ease-In(淡入式淡出,开始慢结束快):用平方曲线
pow(min(1, max(0, (t - start)/duration)), 2) - Ease-Out(淡出式淡出,开始快结束慢):用平方根曲线
sqrt(min(1, max(0, (t - start)/duration))) - 自定义分段曲线:比如前1秒线性衰减,后1秒正弦衰减,直接写复合表达式就行
注意事项
- 记得把命令里的
start(淡出开始时间)和duration(淡出时长)换成你实际需要的数值; - 如果是处理灰度视频,只需要控制
lum_expr或者单通道表达式即可; - 测试的时候可以先剪一段短视频试效果,避免浪费时间。
内容的提问来源于stack exchange,提问作者Zoltan
相关产品推荐
相关产品推荐

