当你看到这样的动图时,你会想到这是用FFmpeg做出来的吗?

FFmpeg,作为一款强大的视频编辑处理工具,在基础的视频处理上十分可靠,在音视频编解码上大放异彩,那么它在动态效果上的应用怎么样呢,笔者为此做了一定的实践,踩了不少坑,现将FFmpeg文字方框动效实现的工作总结如下。

下文将按照实现最终动效的探索顺序一步一步展示。

1、文字淡入淡出

首先要实现的第一个动效是:文字淡入淡出
经过查询,可以用fade函数来控制文字的淡入淡出,用enable来控制时间。

话不多说,直接上案例代码:

ffmpeg -i test.mp4 -lavfi "drawtext=text='Summer Video':fontsize=40:box=1:x=w/2:y=h/2:enable='between(t,8,15)',fade=t=in:start_time=8:d=1:alpha=1,fade=t=out:start_time=14.5:d=1:alpha=1[fg];[0][fg]overlay=format=auto,format=yuv420p" -c:a copy output2.mp4

tips及小坑:

  • “-lavfi” 等价于 “-filter_complex”
  • -y无条件覆盖之前的输出
  • -c:a copy对音频可以不用编码所以直接复制比较快
  • fade函数的alpha必须等于1,否则会黑屏

2、向上向下擦除效果

要实现向上向下擦除效果,目前ffmpeg并没有特定的滤镜实现,因此只能曲线救国,通过控制x,y与时间戳t参数的计算公式的方式去实现。具体代码如下:

ffmpeg -i test.mp4 -lavfi "drawtext=text='Summer Video':fontsize=50:box=1:boxcolor=white:alpha=0.5:x=(w-tw)/2:y='if(lte(t,9),(h-th)/2+(t-9)*30,if(gte(t,14),(h-th)/2+(t-14)*30,(h-th)/2))':enable='between(t,8,15)',fade=t=in:start_time=8:d=1:alpha=1,fade=t=out:start_time=14:d=1:alpha=1[fg];[0][fg]overlay,format=yuv420p" -c:a copy output2.mp4

通过写x,y与t的表达式,可以人工去制造x,y的动态变化,同时从此例可以看到,ffmpeg的if语法以及lte,gte函数的使用。

3、背景框+文字

如果想要背景框和文字一起出现,那么可以用以下代码实现:

ffmpeg -i test.mp4 -filter_complex "drawbox=(iw-w)/2:(ih-h)/2:360:100:pink@0.5:t=fill:enable='between(t,8,15)',drawtext=text='Summer Video':fontsize=50:x=(w-tw)/2:y='if(lte(t,9),(h-th)/2+(t-9)*30,if(gte(t,14),(h-th)/2+(t-14)*30,(h-th)/2))':enable='between(t,8,15)',fade=t=in:start_time=8:d=1:alpha=1,fade=t=out:start_time=14:d=1:alpha=1[fg];[0][fg]overlay=format=auto,format=yuv420p" -c:a copy output2.mp4
  • T是填充度,表示填充的像素个数 t=fill表示填充
  • Drawbox中iw即为视频输入画面的宽度,所以中心位置应该为:
  • x=(iw-w)/2:y=(ih-h)/2:w=360:100(视频尺寸为1280*720)
  • 注意:单独使用drawtext时要记得在drawtext=后加上双引号“”,特别是要定义x和y的表达式时

4、方框扩张

关于方框的扩张,笔者尝试了好几种方案,也踩了好几种坑,现按照尝试顺序进行记录。

首先,我们如何做到方框扩张呢?最易理解的一种思路就是改变方框宽度及左顶点与时间的表达式。我们可以一方面控制方框的宽度w,令他随时间扩张,另一方面我们控制x参数,令x随时间向左移动,并使方框w扩张的速度为x向左移动速度的两倍。这样不就实现了吗?
因此咱们就按照这个思路去实现吧~go~

drawbox版本

首先说到方框扩张,第一时间想到了用drawbox滤镜去实现。然而查阅了很多资料发现,如果单独使用drawbox是无法实现的,因为它并不接受t参数(在drawbox滤镜中,t有特殊的含义,为thickness,指box的厚度)
因此以下代码并不能产生一个扩张的方框:

ffmpeg -i test.mp4 -filter_complex "drawbox=x=460+(8-t)*10:y=310:w=100+(t-8)*10*2:h=100:color=pink:t=fill:enable='between(t,8,15)',fade=t=in:start_time=8:d=1:alpha=1,fade=t=out:start_time=14:d=1:alpha=1[fg];[0][fg]overlay=format=auto,format=yuv420p" -c:a copy kuang.mp4

drawbox+scale版本

既然drawbox本身尺寸无法动态变化,那么用其他的filter可以做到吗?经过一番检索,查到了有scale这个滤镜,并开始了尝试:

ffmpeg -y -i test.mp4 -filter_complex "drawbox=iw/2:ih/2:20:20:blue@0.5:t=fill:enable='between(t,3,8)',scale=eval=frame:w=100+t*10:h=20[vb]; [0][vb]overlay=x=W/2:y=H/2" -t 16 a.mp4

而结果是令人失望的,由于这种写法相当于是绘图盒滤镜的输入所以这样覆盖层包含整个视频本身,所以无法显示独立的色块,显示的是源视频的缩影,因此并不符合动效要求。

color版本

那么如果不用drawbox,可以用其他的滤镜去代替drawbox么?当然有,这就是color!color是非常便捷的展示色块的滤镜,于是兴高采烈的写下了以下代码:

ffmpeg -y -i test.mp4 -filter_complex  "color=red@0.5:s=100*tx200[c];[0][c]overlay='if(lte(-1024+1500*t,0),-1024+1500*t,0)':100" -t 15 out.mp4

不过事实再一次令人绝望——color无法改变size!!不管你如何变化,它的size并不会跟着t改变。so sad。

color+scale版本

那么让我们试试color+scale吧
bingo!终于可以了!通过这俩结合的方式,我们实现了方框随时间扩张!

ffmpeg -y -i test.mp4 -filter_complex  "color=c=blue@0.5:size=500x300,scale=eval=frame:w=100+t*200:h=10[cl];[0][cl]overlay=x=W/2-100*t:y=H/2" -t 15 out.mp4

可是,你如果使用这段代码生产视频则会发现,color这个框从一开始就存在了。color模块无法控制出现的时间,始终有size
那么如何控制color出现呢?
答案就是:在overlay中增加控制时间的enable!

ffmpeg -y -i test.mp4 -filter_complex  "color=c=blue@0.5:size=10x10,scale=eval=frame:w='if(lte(t,3),0,if(lte(t,6),(t-3)*300,if(lte(t,10),(6-3)*300,if(lte(t,13),(6-3)*300-(t-10)*300,0))))':h=10,fade=t=in:start_time=2.5:d=0.5:alpha=1,fade=t=out:start_time=12.5:d=0.5:alpha=1[cl];[0][cl]overlay=x='if(lte(t,6),W/2-150*(t-3),if(gte(t,10),W/2-150*(6-3)+150*(t-10),W/2-150*(6-3)))':y=H/2:enable='between(t,3,13)'" -c:a copy -t 15 outting.mp4

注意:

  • 对W的限制一定要明确前后是0,不能超过enable的时间区间
  • Color最好有size参数,这样更稳定

5、方框扩张+文字

现在,我们整理以下刚刚的代码,将方框扩张和文字淡入淡出放在一起,就得到了以下一长串代码:

ffmpeg -y -i test.mp4 -filter_complex  "color=c=blue@0.5:size=10x10,scale=eval=frame:w='if(lte(t,3),0,if(lte(t,4),(t-3)*600,if(lte(t,12),(4-3)*600,if(lte(t,13),(4-3)*600-(t-12)*600,0))))':h=10,fade=t=in:start_time=3:d=0.5:alpha=1,fade=t=out:start_time=12.5:d=0.5:alpha=1[cl1];color=c=blue@0.5:size=10x10,scale=eval=frame:w='if(lte(t,3),0,if(lte(t,4),(t-3)*600,if(lte(t,12),(4-3)*600,if(lte(t,13),(4-3)*600-(t-12)*600,0))))':h=10,fade=t=in:start_time=3:d=0.5:alpha=1,fade=t=out:start_time=12.5:d=0.5:alpha=1[cl2];[0][cl1]overlay=x='if(lte(t,4),W/2-300*(t-3),if(gte(t,12),W/2-300*(4-3)+300*(t-12),W/2-300*(4-3)))':y=H/4:enable='between(t,3,13)'[bkg];[bkg][cl2]overlay=x='if(lte(t,4),W/2-300*(t-3),if(gte(t,12),W/2-300*(4-3)+300*(t-12),W/2-300*(4-3)))':y=3*H/4:enable='between(t,3,13)',drawtext=text='summer video':fontsize=50:x=(w-tw)/2:y='if(lte(t,4),(h-th)/2+(t-4)*30,if(gte(t,12),(h-th)/2+(t-12)*30,(h-th)/2))':enable='between(t,3,13)',fade=t=in:start_time=2.5:d=0.5:alpha=1,fade=t=out:start_time=12.5:d=0.5:alpha=1" -c:a copy -t 15 outting.mp4

此时,问题又出现了,我们发现当两者一起时,文字淡入淡出消失了,fade功能不见了。
因此我们换种思路,还有什么参数可以控制文字淡入淡出呢?
是的,我们可以通过动态调整alpha参数,来实现文字淡入淡出:

ffmpeg -y -i test.mp4 -filter_complex  "color=c=blue@0.5:size=10x10,scale=eval=frame:w='if(lte(t,3),0,if(lte(t,4),(t-3)*600,if(lte(t,12),(4-3)*600,if(lte(t,13),(4-3)*600-(t-12)*600,0))))':h=10,fade=t=in:start_time=3:d=0.5:alpha=1,fade=t=out:start_time=12.5:d=0.5:alpha=1[cl1];color=c=blue@0.5:size=10x10,scale=eval=frame:w='if(lte(t,3),0,if(lte(t,4),(t-3)*600,if(lte(t,12),(4-3)*600,if(lte(t,13),(4-3)*600-(t-12)*600,0))))':h=10,fade=t=in:start_time=3:d=0.5:alpha=1,fade=t=out:start_time=12.5:d=0.5:alpha=1[cl2];[0][cl1]overlay=x='if(lte(t,4),W/2-300*(t-3),if(gte(t,12),W/2-300*(4-3)+300*(t-12),W/2-300*(4-3)))':y=H/4:enable='between(t,3,13)'[bkg];[bkg][cl2]overlay=x='if(lte(t,4),W/2-300*(t-3),if(gte(t,12),W/2-300*(4-3)+300*(t-12),W/2-300*(4-3)))':y=3*H/4:enable='between(t,3,13)',drawtext=text='summer video':fontsize=50:x=(w-tw)/2:y='if(lte(t,4),(h-th)/2+(t-4)*30,if(gte(t,12),(h-th)/2+(t-12)*30,(h-th)/2))':enable='between(t,3,13)':alpha='if(lt(t,3),0,if(lt(t,4),(t-3)/1,if(lt(t,12),1,if(lt(t,13),(1-(t-12))/1,0))))'" -c:a copy -t 15 outting.mp4

这样问题就被解决了。

6、添加多行文本(最终代码)

目前ffmpeg并没有直接添加多行文本的好命令,最多可以在命令行通过enter来实现文本换行,一般情况下,都是通过控制xy参数对齐,通过多个drawtext滤镜链实现多行文本。

实现办法:在Overlay后面可以直接连接一个drawtext(最多一个),并以此为一幕[te1],然后再以[te1]开头写draw text,可以多个用逗号分隔。

具体代码如下:

ffmpeg -y -i test.mp4 -filter_complex  "color=c=LightSteelBlue@0.5:size=10x10,scale=eval=frame:w='if(lte(t,3),0,if(lte(t,4),(t-3)*600,if(lte(t,12),(4-3)*600,if(lte(t,13),(4-3)*600-(t-12)*600,0))))':h=10,fade=t=in:start_time=3:d=0.5:alpha=1,fade=t=out:start_time=12.5:d=0.5:alpha=1[cl1];color=c=MediumSlateBlue@0.5:size=10x10,scale=eval=frame:w='if(lte(t,3),0,if(lte(t,4),(t-3)*600,if(lte(t,12),(4-3)*600,if(lte(t,13),(4-3)*600-(t-12)*600,0))))':h=10,fade=t=in:start_time=3:d=0.5:alpha=1,fade=t=out:start_time=12.5:d=0.5:alpha=1[cl2];[0][cl1]overlay=x='if(lte(t,4),W/2-300*(t-3),if(gte(t,12),W/2-300*(4-3)+300*(t-12),W/2-300*(4-3)))':y=H/4:enable='between(t,3,13)'[bkg];[bkg][cl2]overlay=x='if(lte(t,4),W/2-300*(t-3),if(gte(t,12),W/2-300*(4-3)+300*(t-12),W/2-300*(4-3)))':y=3*H/4:enable='between(t,3,13)'[at];[at]drawtext=text='summer video':fontsize=50:x=(w-tw)/2:y='if(lte(t,4),(h-th)/2+(t-4)*30,if(gte(t,12),(h-th)/2+(t-12)*30,(h-th)/2))':enable='between(t,3,13)':alpha='if(lt(t,3),0,if(lt(t,4),(t-3)/1,if(lt(t,12),1,if(lt(t,13),(1-(t-12))/1,0))))',drawtext=text='夏日视频':fontsize=50:fontcolor=Brown:x=(w-tw)/2:y='if(lte(t,4),(h-th)/2-100+(t-4)*30,if(gte(t,12),(h-th)/2-100+(t-12)*30,(h-th)/2-100))':enable='between(t,3,13)':alpha='if(lt(t,3),0,if(lt(t,4),(t-3)/1,if(lt(t,12),1,if(lt(t,13),(1-(t-12))/1,0))))',drawtext=text='really nice':fontsize=50:fontcolor=Brown:x=(w-tw)/2:y='if(lte(t,4),(h-th)/2+100+(t-4)*30,if(gte(t,12),(h-th)/2+100+(t-12)*30,(h-th)/2+100))':enable='between(t,3,13)':alpha='if(lt(t,3),0,if(lt(t,4),(t-3)/1,if(lt(t,12),1,if(lt(t,13),(1-(t-12))/1,0))))'" -c:a copy -t 15 output.mp4

而这段代码则是实现开头所展示的动效的最终代码了。

而实现这一个动效,用了多少代码呢?

下面这张图给大家感受一下:

没错,看到这一段的时候,我当时的内心也是崩溃的。。

7、矩形框张缩+多行文本淡入淡出动效代码解读




8、总结

从以上艰难的实现历程和反复的踩坑上其实多多少少也能看出来,ffmpeg并不适合制作动效。

不仅这方面应用的资料难查,代码繁琐,而且实现成本也很高。

其实仔细看ffmpeg通过参数计算实现的动效也会发现,扩张的方框也存在着一定程度的抖动,其抖动原因,我猜想主要是因为方框左端在变化,右端也在变化,两边同时变化,而ffmpeg其内在的计算单元的精度可能无法保证两边变化的速度一定一致,因此出现抖动。

总之,ffmpeg是一个音视频好工具,但是是否适合制作动效,我本人的意见是否定的。不过以上工作总结也希望能给相关从业者提供一点参考和帮助。

当然我也期待日后会有大神开发出更多制作动效的filter,以便大家使用~期待~

FFmpeg动效实践与探索(文字方框的同步展开及收缩)相关推荐

  1. APP动效之美需内外兼修(转载自伯乐在线)

    APP动效之美需内外兼修 2014/08/06 | 分类: 设计 | 0 条评论 | 标签: 交换设计 分享到: 12 原文出处: 百度MUX   欢迎分享原创到伯乐头条 移动互联网时代已经到来,AP ...

  2. QQ音乐的动效歌词是如何实践的?

    2019独角兽企业重金招聘Python工程师标准>>> 本文由云+社区发表 作者:QQ音乐技术团队 一. 背景 1. 现状 歌词浏览已经成为音乐app的标配,展示和动画效果也基本上大 ...

  3. QQ音乐的动效歌词是如何实践的? 1

    本文由云+社区发表 作者:QQ音乐技术团队 一. 背景 1. 现状 歌词浏览已经成为音乐app的标配,展示和动画效果也基本上大同小异,主要是单行的逐字染色的卡拉OK效果和多行的滚动效果.当然,我们也不 ...

  4. WPF-3D动效-文字球形环绕

    原文:WPF-3D动效-文字球形环绕 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u013224722/article/details/81784 ...

  5. canvas 文字颜色_canvas 中普通动效与粒子动效的实现

    (给前端大全加星标,提升前端技能) 作者:薄荷前端 https://github.com/BooheeFE/weekly/issues/26 canvas 用于在网页上绘制图像.动画,可以将其理解为画 ...

  6. 站酷用HTML5播放视频,站酷:动效展示实践的问题及解决

    前两天设计一款主页,想给它加上一些操作演示,于是便自己琢磨如何实现.先上效果图: 首先,是界面设计的部分: 需求是针对现有的网站做移动端的展示.针对门户网站的性质,以及对象的行业特性,将首页直接体现的 ...

  7. 知识图谱可视化技术在美团的实践与探索

    省时查报告-专业.及时.全面的行研报告库 省时查方案-专业.及时.全面的营销策划方案库 [免费下载]2022年3月份热门报告盘点 某短视频APP推荐算法及策略最详细拆解 大萧条来临前的几大征兆 机器学 ...

  8. 内容理解、内容生成、内容推荐分发,在广告场景下的实践和探索(京东张政)

    内容理解.内容生成.内容推荐分发,在广告场景下的实践和探索(京东张政) 提示:广告也好,商品也罢,内容们,需要精准地推荐给用户,使其点击观看或者够买啥的,都需要走通一个重要流程:内容理解与推荐分发,更 ...

  9. ae 创建图像等高线 蒙版_如何用AE创建简单的UI动效

    工具 After Effects CS6 or CC Photoshop CS6 or CC 设计流程 After Effects 在一个合成中创建转场效果 另外一个合成中创建展示效果 导出 Phot ...

最新文章

  1. C语言考研复试知识点整理
  2. android webview 填充,从Android使用WebView自动填充表格
  3. python硬件编程智能家居_利用 Python 的力量,实现 Tableau 与智能家居系统集成
  4. RabbitMQ 的安装----windows环境
  5. JavaScript入门(part8)--数组
  6. 写出高效优美的C语言代码(单片机)
  7. 吃的苦中苦,方为人上人!
  8. QT中QWidget、QDialog及QMainWindow的区别
  9. openstack镜像制作详解
  10. php m.baidu.com,http://m.baidu.com/baidu.php?u
  11. mysql maratadb_Mysql/Mairadb主从复制
  12. python的paramiko模块
  13. 学习记录:由技术而产品,由产品而商务
  14. 阿里云推出全球云网络人才赋能计划,打造云网络认证体系
  15. 【元胞自动机】基于元胞自动机模拟单车道交通流含Matlab源码
  16. 句子迷 有哪些你第一眼就爱上的电影台词
  17. 获得旅行青蛙无限三叶草方法及apk
  18. Go webrtc项目pion创始人专访 | Gopher Daily (2021.04.07) ʕ◔ϖ◔ʔ
  19. 计算机底层01-计算机发展史
  20. win7 关机速度比较快

热门文章

  1. 预警神器来了,天翼大喇叭发出河道防汛强音
  2. Android开发:按一定频率同时获取多个传感器数据
  3. Set 中 toArray()
  4. 认识(大端--小端)端模式
  5. 国内代码托管平台gitee的使用
  6. IDEA使用手记——IDEA主菜单被隐藏了!!
  7. warning no match for this type name:xxx.xxx.xxx [Xlint:invalidAbsoluteTypeName]
  8. 可达编程 单源最短路
  9. Win11麦克风测试在哪里?Win11测试麦克风的方法
  10. 适用于大规模数据排序(归并排序、快速排序)