功能实现-java下使用ffmpeg合成回忆录

2,120 阅读3分钟

1.背景信息

         这是一个我们云班产品的运营活动,主要为了营造开学季氛围提出来的,就是需要给已经上传过照片的班级相册里面提取出学生的人脸照片,然后将这些图片和音频合成为一个回忆录视频,然后推送给家长/老师等,有人会问,为啥不用h5的制作工具? 这里有个非常坑人的约束条件,这个视频要能在我们的设备上播放,恰巧我们的设备不支持前端框架,这就只能靠后台去合成这个视频了。看来没其他途径了,撸吧。

先上个最终实现的效果图,由于涉及到隐私,我就拿测试的模特图片来做展示,应该没问题。

2.技术选型

        这里针对ffmpeg和opencv做了选型,主要针对使用方式去做的。最终选定了ffmpeg,比较适合做这种图像视频音频类的加工处理,而且使用了看着比较靠谱的cmd模式,方便快速开发。

3.主要实现部分

3.1 主要业务流程

        从时序图中可以看到,整个流程包括了 1.需要识别到挑选的图片中含有人脸元素,因为很多老师会把学生的作业或者奖状发布到平台上去,所以需要人脸识别算法将带有人脸的照片挑选出来形成资源池;2.使用ffmpeg把识别好的图片列表和音频文件一起合成到视频中; 3.最后将视频上传到存储云中,并发出通知消息。别看只有简单的3步,里面踩了很多的坑。这里主要讲和ffmpeg库类有关的东西。

3.2 使用的ffmpeg命令

        ffmpeg是一个非常强大的图像视频音频处理库,里面能用到的东西非常多,但是基于这个需求,我们只用到了几个主要的命令。

其中将图片列表合成视频的命令如下所示:

ffmpeg -i img/frames_%05d.jpg -i sound/sound.mp3 -r 10 -t 20 --vcodec mpeg4 -y test.avi命令参数解析:
-i : 输入源,符合frames_1.jpg、frames_2.jpg这样的命名格式的图片文件或者音频文件
-r : 帧速
-t : 视频时长
--vcodec : 视频编码格式
-y : 输出视频

3.3 主要功能代码

        ffmpeg使用起来会比较复杂,主要是因为它的输入参数太多了,这里使用建造者模式将整个命令组装过程给封装起来,方便使用者快速明白参数含义。

这里使用了jdk中Runtime类,里面可以使用Process新建进程来执行ffmpeg命令,其中需要读取执行命令的输出流与错误流。特别注意:我们在这里踩到了进程间通信和不同进程在容器实例的内存分配问题两个大坑。

4.总结

        这是一个非常仓促的需求,从提出来到上线总共也就用了一周的时间,里面还包括测试的耗时,而且对于一个零图像视频技术储备的团队来说,只能加班去怼了。当然结局是很美好的,原定是1000个老师参加,最终有1800个老师参与了,还是达成目标了! 后续的运营采访中,用户对这个活动评价非常高。主要介绍了怎么使用ffmpeg来进行图像列表与音频合成视频,还有对ffmpeg执行进行的简单封装。这里还有一个关于java cmd执行在进程间通信导致死锁的问题,这个问题比较有趣,到时我会梳理些内容出来。