本文已参与「新人创作礼」活动,一起开启掘金创作之路。
项目需求需要将视频按帧进行拆分,并通过获取每帧的当前时间与视频文件名中的时间进行计算,最终结果命名为抽帧图片的文件名。案例中只有部分代码,不影响集成使用。
1、window10 系统 安装opencv 4.52版本
下载地址:Find out more about OpenCV | SourceForge.net
下载之后自定义安装目录,进行下一步安装操作即可。
2、将Opencv库添加到项目中
在IDEA 中的 Project Structure => Modules => Dependencies 中添加 opencv 安装目录下的的jar包 D:\opencv\build\java\opencv-452.jar
同时将D:\opencv\build\java\x64\opencv_java452.dll,添加为Native Libary
3、直接上代码实现视频图片拆帧
//加载本地的OpenCV库,这样就可以用它来调用Java API
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
视频拆帧代码:
// 创建VideoCapture对象
VideoCapture cap = new VideoCapture(videoPath);
//判断视频是否打开
if (cap.isOpened()) {
//总帧数
int frameCount = new Double(cap.get((Videoio.CAP_PROP_FRAME_COUNT))).intValue();
logger.info("{}视频一共{}帧", file_name, frameCount);
// 创建mat
Mat frame = new Mat();
for (int i = 0; i < frameCount; i++) {
// 读取下一帧的数据
if (cap.read(frame)) {
// 获取当前帧的时间戳
int video_mesc = new Double(cap.get(Videoio.CAP_PROP_POS_MSEC)).intValue();
// cap.set(Videoio.CAP_PROP_POS_MSEC,2 * 1000);
// file_date通过视频名字获取时间,然后根据帧的视频戳进行相加计算
String curTime = simpleDateFormat.format(new Date(file_date.getTime() + video_mesc));
String outFileName = out_directory + File.separator + file_name + "@" + curTime + ".jpg";
// 写出图片
Imgcodecs.imwrite(outFileName, frame);
}
}
4、集成过程中遇见的问题
1)VideoCapture的isOpened()方法一直返回false。
将opencv安装目录D:\opencv\build\x64\vc14\bin中的opencv_videoio_ffmpeg452_64.dll复制到生成 java的安装目录 C:\Program Files\Java\jdk1.8.0_191\bin 中去。
2) 读取帧 提示:[NULL @ 0000022362197940] non-existing PPS 0 referenced
当根据时间获取相应的帧数据时,会出现ffmpeg解析问题,不知道如何解决。暂时没用,给注掉了。
cap.set(Videoio.CAP_PROP_POS_MSEC,2 * 1000);