小编最近3周在做流媒体相关业务,对于视频这块有了一些自己认识,分享一下。
一、业务场景
类似“汽车抵押贷款”等相关贷款业务这几年很常见,往往为了做风险控制,要求贷款人在我门店按照工作人员要求录制N段视频,上传到我系统,以备贷款资质审核而用。而我方网站是B/S模式,风控审核人员查看用户上传视频,只能通过web浏览器嵌入"video player"来看,这个时候,有部分“本地播放没问题”的视频在网页播不了,定位问题如上。
二、确定问题
1)当前情况如下:
1.小部分视频线上有声音但无画面
2.小部分视频线上不能播放
3.上述两类视频本地播放器均能正常播放
2)猜测问题
1.web播放器有问题(可能性很大)
2.视频格式有问题(不成立,upload过程已限制上传视频类型为.mp4)
3)问题确诊
有部分视频格式和播放器匹配失败
这里需要理解MP4真正的含义,可以参考这篇文章:“https://www.zhihu.com/question/20997688”,后续如果有精力,会写一写视频文件的格式,“.Mp4”可以从3个维度理解。总之,从编码压缩标准来讲,MP4又分为“1.MPEG4(DivX)”、“2.MPEG4(Xvid)”、“3.AVC(H264)”三种类型。
当我用本地的“格式工厂”将视频转换成第3种AVC模式之后,视频在web播放器上播放成功。
三、解决方向
1.更换web端视频播放器
2.不能播放的小部分视频进行视频转码
方案1调研之后,被pass,原因可参考:“http://www.php.cn/div-tutorial-362585.html”。几乎主流的H5视频播放器,都不兼容MPEG4(dIvX)以及MPEG4(Xvid)类型,只兼容AVC(H264)类型。如之前所述,upload时候,已经限制了上传的视频格式,只能为.mp4后缀类型。
So,只能通过视频转码来做。
至于视频转码,领导给出的要求如下:1.异步,2.准实时,3.不能再服务器上安装其他插件(我想可能是怕**软件带来漏洞),之后开始研究视频转码。
四、转码深入
1)我的尝试
1.ffmpeg
2.jave
3.jcodec
4.openCV
5.javaCV
6.javaCPP
简单介绍,上述几款三方工具/插件,我已经都被他们虐过了,其中jcodec适合做动态图,视频转码很慢;javacv调用ffmpeg封装的底层dll文件,需要掌握C语言,自己写一些动态链接库,奈何时间紧迫,没有时间学习C的写法,最终定位在了JAVE和FFMPEG上。
在和网友交流过程中,一些专业处理流媒体的朋友这样告诉我:
由此可以对其窥见一斑,java架构本身没有自己的流媒体框架,如果处理视频,只能通过ffmpeg来做,ffmpeg是永远都绕不过去的,包括最后我采用的Jave方式,看一下jave的源码,如下:
它下面也有两个ffmpeg的文件。
这个过程经历过:
1.从windows系统手写dos命令 类似: ffmpeg -i d:\special.mp4 -vcodec h264 d:\target.mp4
2.在java程序中将dos命令封装成接口
3.尝试jave来操作
这三大过程,其中,对我帮助特别大的是,在github上开源出来的一个命令行处理组件:https://github.com/eguid/FFmpegCommandHandler4java,受益匪浅。
对比性能:jave最高,其次ffmpeg的性能和格式工厂基本持平,8G内存,转码进程启动后,90%持续至转码结束。
jave的坑:Encode的过程,官网介绍可以Encode成H264格式,其实根本不能,其次最近的版本V1.0.2,在2009年已经停止维护。。。。。。
五、我的方案
标准:1.异步、2.准实时完成任务,我采用了MQ+jave+RPC的架构设计方式
架构图:
视频存储在Hbase服务器,我的转码业务主要是在MQ Server中执行,而fcarloan则是我们正常跑的业务项目,其中这样设计的考虑除了异步+准实时之外,还考虑如果做成同步,可能导致程序崩溃的情况,异步后,即使转码失败,fcarloan还会再刷定时任务处理转码失败的视频。
六、小结
1.这篇文章只是梳理了一下我对这个问题的处理过程,具体代码已上传Github:
https://github.com/zhangzhenhua92/VideoEncoder
2.整体思路
3.关于ffmpeg以及java处理视频的深入介绍,会尽快更新。