雨翔河
首页
列表
关于
使用 javacv 和 ffmpeg 获取视频信息进行视频剪切
2021-12-01 07:22
偶然工作中需要获取视频信息,java本身要获取视频信息比较麻烦,但是可以使用ffmpeg来做到,在机器上安装好ffmpeg,安装好后,输入 `ffmpeg -version` 可以查看自己安装的ffmpeg版本。 官网: http://www.ffmpeg.org/ ffmpeg非常强大,简单的获取一个视频信息就是 `ffmpeg -i 20211201.mp4` 也可以用ffmpeg自带的`ffprobe`命令来查看视频信息 ``` ffprobe -show_streams 20211201.mp4 ``` 看了下ffmpeg是使用c开发的一个多媒体处理工具(不仅仅可以处理视频,也可以处理音频),使用c++去调用和使用java调用的性能损耗应该是差不多的,所以为了简单点,可以直接使用java的cmd调用得到结果。 ``` import org.apache.commons.io.IOUtils; private static String ffprobeProcess(String filePath) { List<String> commend = new ArrayList<>(); commend.add("ffprobe"); commend.add("-show_streams"); commend.add(filePath); InputStream inputStream = null; try { ProcessBuilder builder = new ProcessBuilder(); builder.command(commend); builder.redirectErrorStream(true); Process process = builder.start(); inputStream = process.getInputStream(); List<String> list = IOUtils.readLines(inputStream, "utf-8"); process.waitFor();//这里线程阻塞,将等待外部转换进程运行成功运行结束后,再往下执行 StringBuilder stringBuilder = new StringBuilder(); for (String line : list) { stringBuilder.append("\n"); stringBuilder.append(line); } return stringBuilder.toString(); } catch (Exception e) { e.printStackTrace(); return null; } finally { IOUtils.closeQuietly(inputStream); } } ``` 还有一种更好的方式就是使用javacv来实现。 官网: https://github.com/bytedeco/javacv javacv封装了ffmpeg的一些接口,可以很方便的使用ffmpeg的功能,当然javacv不仅仅封装包含了ffmpeg,还有opencv等等一些组件的接口封装,适配了各个平台,所以在引入的包的时候最好不好一股脑的全部的依赖都引进来,我这里为了方便就直接全部引入了。 写个简单的功能:获取视频的长度和宽度,剪切视频只保留前六秒钟的视频且视频每一窗口帧都加入一张图片进去。 ``` import org.apache.commons.io.IOUtils; @Test public void test() { String inFile = "/tmp/test1.mp4"; //读取的视频 String outFile = "/tmp/out.mp4"; //将要生成的剪切视频 String insertImage = "/tmp/test2.jpg"; //视频中要放入的图片 FFmpegFrameGrabber grabber = null; FFmpegFrameRecorder fFmpegFrameRecorder = null; try { grabber = new FFmpegFrameGrabber(inFile); grabber.start(); int width = grabber.getImageWidth(); System.out.println("width: " + width); int height = grabber.getImageHeight(); System.out.println("height: " + height); System.out.println("---------------------------"); fFmpegFrameRecorder = new FFmpegFrameRecorder(outFile, width, height, 2); fFmpegFrameRecorder.start(); Frame inFrame; boolean audioCompleted = false; boolean videoCompleted = false; while (true) { inFrame = grabber.grab(); if (null == inFrame) { break; } if (inFrame.timestamp >= 5 * 1000 * 1000) { if (AVMEDIA_TYPE_VIDEO == inFrame.streamIndex) { videoCompleted = true; } else if (AVMEDIA_TYPE_AUDIO == inFrame.streamIndex) { audioCompleted = true; } if (audioCompleted && videoCompleted) { break; } } fFmpegFrameRecorder.record(inFrame); //放入图片 Java2DFrameConverter java2DFrameConverter = new Java2DFrameConverter(); File imageFile = new File(insertImage); BufferedImage read = ImageIO.read(imageFile); Frame imageFrame = java2DFrameConverter.getFrame(read); fFmpegFrameRecorder.record(imageFrame); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (null != grabber) { grabber.close(); } } catch (Exception e) { e.printStackTrace(); } try { if (null != fFmpegFrameRecorder) { fFmpegFrameRecorder.close(); } } catch (Exception e) { e.printStackTrace(); } } } ``` 这样就完成了一个简单的获取视频信息和视频剪切操作。
类型:工作
标签:ffmpeg,javacv
Copyright © 雨翔河
我与我周旋久
独孤影
开源实验室