侧边栏壁纸
  • 累计撰写 416 篇文章
  • 累计创建 65 个标签
  • 累计收到 151 条评论

目 录CONTENT

文章目录

OpenCV Android 之 VideoWriter类

Z同学
2023-03-28 / 0 评论 / 3 点赞 / 1,667 阅读 / 1,616 字
温馨提示:
本文最后更新于 2023-03-30,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

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库才行吧。

默认支持的编解码比较少。

3

评论区