1. 介绍
在上篇内容中,介绍过VideoCapture
类,用来解析视频,并获取视频帧。而VideoWriter
类就是用来将Mat
文件,存储为视频文件的工具类。
先说自己使用后的经验。
使用VideoWriter
类,我将一组图片转成了视频文件。但是这个视频文件,使用 Android 原生播放器却无法播放,使用ExoPlayer
播放器也无法播放。
改ijkplayer
进行播放发现提示 error 错误。代码为-10000,说明编码格式不支持。
因为我编译的视频格式为:MJPG格式。尝试过其他编码格式都提示失败。只有MJPG格式才能将Mat存储为视频。
可能还需要更多的第三方依赖才能实现不同的编码格式视频的生成。openCV SDK默认支持的编码格式应该是比较少的。
这篇内容,可能无法解决相关问题。因为很多地方我也没有得到解答。
2. VideoWriter
VideoWriter
是视频编写工具。提供了用于编写视频文件或图像序列的 C++ API。
示例,创建VideoWriter
对象:
VideoWriter videoWriter = new VideoWriter(); //可以直接创建
boolean isWriter = videoWriter.open(fileUrl + ".avi",VideoWriter.fourcc('M', 'J', 'P', 'G'), 30,
new Size(1920, 1080),true);
open()
方法中的传参,其实也可以直接在构造方法中初始化。先简单介绍一下这些传参的意义:
- String filename: 视频文件的存储路径+名称+后缀组合的文件地址。示例:/storage/emulated/0/Android/data/com.zinyan.demo/files/CacheVideo/50.avi。
VideoWriter
会自动在该路径下创建该视频文件。 - int fourcc:视频编码。也就是决定了后续给视频文件中添加帧的时候的编码方式。需要通过VideoWriter.fourcc()方式来创建。下面有介绍fourcc的相关知识。
- double fps:创建的视频流的帧速率。通常有:25,30 等值。
- Size frameSize:视频文件的每一帧的尺寸。
- boolean isColor:是否有色彩。当isColor值为false时,生成的视频是一个灰色的,该值不传时默认为灰色。
- MatOfInt params:这个变量是用来扩展传参的,例如视频编解码支持更多的参数设置,不止fps,宽高等信息。那么我们就可以使用这个参数去传更多的变量。但通常情况下,这个很少使用了。我们如果有要进行配置的变量,也可以使用set方法进行修改。(默认可不传)
在上面的这些配置方法中,都是初始化的时候导入就可以了。
后面循环调用:
videoWriter.write(Mat mat);
就可以将大量的Mat数据写入到视频文件中了。全部写入完毕后,执行:
videoWriter.release(); //释放资源
释放资源。
PS:如果你针对Videoio中各种enum枚举对象,或者int标注的值不太了解他们的作用,同时java代码上又没有注释说明。
我们可以去C代码中查找,在C代码中会有更详细的注释说明。
文件路径为:opencv/native/jni/include/opencv2/videoio/legacy/constants_c.h 和
opencv/native/jni/include/opencv2/videoio.hpp 两个文件中查询
到这里,我们的VideoWriter
的传参和使用就差不多了。
还没有介绍的set和get方法其实和VideoCapture
差不多。具体的可以参考文章:https://zinyan.com/?p=497
2.1 Android端存储
上面也有介绍过,如果想存储视频到Android本地,我们可以选择的编码器只有:VideoWriter.fourcc('M', 'J', 'P', 'G')
才行。同时文件名称的后缀必须是:.avi
。只有这样我们调用open方法得到的返回值才是true。其他的编码格式都会是false。
网上很多示例中,在windows环境下可以编译更多的编码类型。应该是系统环境和依赖库有比较大的区别吧。
如果不想自己编译so库,添加依赖。而直接使用OpenCV提供的Android SDK。受到的限制比较多,有很多编码都是不支持的。
2.2 fourcc 参数
在上面的传参中,比较不好理解的可能就是fourcc值了。这个值和定义不是openCV中专有的。
它的全名叫做:Four-Character Codes 是一种独立标示视频数据流格式的四字符代码。
也就是表明该视频的编码方式。
常见的编码格式有:
VideoWriter.fourcc('P','I','M','1'); //mpeg-1编码
VideoWriter.fourcc('M', 'J', 'P', 'G'); //mjpge编码
VideoWriter.fourcc('F', 'F', 'V', '1'); // FFmpge的 无损编码格式
VideoWriter.fourcc('H', 'F', 'Y', 'U'); //Huffman 的无损编码格式
VideoWriter.fourcc('L', 'A', 'G', 'S'); //Lagarith 的无损编码格式
VideoWriter.fourcc('M', 'P', '4', '2'); // MPEG-4.2 编码
VideoWriter.fourcc('D', 'I', 'V', '3'); // MPEG-4.3 编码
VideoWriter.fourcc('D', 'I', 'V', 'X'); // MPEG-4 编码
VideoWriter.fourcc('U', '2', '6', '3'); // H263 编码
VideoWriter.fourcc('I', '2', '6', '3'); //H263I 编码
VideoWriter.fourcc('F', 'L', 'V', '1'); //FLV1 编码
VideoWriter.fourcc('I', '4', '2', '0'); //YUV编码,视频格式为.avi
VideoWriter.fourcc('A', 'V', 'C', '1'); //H264编码
如果想弄明白更多的传参可以通过网站:http://mp4ra.org/#/codecs 这个网站查询。
openCV还推荐了个网站:http://www.fourcc.org/codecs.php。但是在国内访问这个网站容易被重定向到一个非法网站。
3. 小结
openCV SDK中针对视频的编解码等操作,支持的比较少。我们如果想在Android上发挥更多的视频编解码等操作。可能需要自己编译FFmpeg库才行吧。
默认支持的编解码比较少。
评论区