javaCV

  最近有视频处理的需求,自己调研javaCV。

  官网没有详细的API,各种轮子翻遍了也没找到几个有用的,以下是自己整理一些视频处理功能:截取视频指定帧生成gif,将图片旋转指定度,截取视频指定帧保存为指定格式的图片(图片保存在视频同文件夹下),调整视频清晰度(只能降低),视频转音频

  先上代码。

1package com.richinfo.media.utils;import com.madgag.gif.fmsware.AnimatedGifEncoder;import org.bytedeco.javacv.FFmpegFrameGrabber;import org.bytedeco.javacv.Frame;import org.bytedeco.javacv.Java2DFrameConverter;import javax.imageio.ImageIO;import java.awt.*;import java.awt.image.BufferedImage;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;/** * @author */public class VideoUtils { /** * 截取视频指定帧生成gif * * @param videofile 视频文件 * @param startFrame 开始帧 * @param frameCount 截取帧数 * @param frameRate 帧频率(默认:3) * @param margin 每截取一次跳过多少帧(默认:3) * @throws java.io.IOException 截取的长度超过视频长度 */ public static void buildGif(String videofile, int startFrame, int frameCount, Integer frameRate, Integer margin) throws IOException { if (margin == null) { margin = 3; } if (frameRate == null) { frameRate = 3; } FileOutputStream targetFile = new FileOutputStream(videofile.substring(0, videofile.lastIndexOf(".")) + ".gif"); FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile); Java2DFrameConverter converter = new Java2DFrameConverter(); ff.start(); try { if (startFrame > ff.getLengthInFrames() & (startFrame + frameCount) > ff.getLengthInFrames()) { throw new RuntimeException("视频太短了"); } ff.setFrameNumber(startFrame); AnimatedGifEncoder en = new AnimatedGifEncoder(); en.setFrameRate(frameRate); en.start(targetFile); for (int i = 0; i < frameCount; i++) { en.addFrame(converter.convert(ff.grabImage())); ff.setFrameNumber(ff.getFrameNumber() + margin); } en.finish(); } finally { ff.stop(); ff.close(); } } /** * 将图片旋转指定度 * * @param bufferedimage 图片 * @param degree 旋转角度 * @return */ public static BufferedImage rotateImage(BufferedImage bufferedimage, int degree) { // 得到图片宽度。 int w = bufferedimage.getWidth(); // 得到图片高度。 int h = bufferedimage.getHeight(); // 得到图片透明度。 int type = bufferedimage.getColorModel().getTransparency(); // 空的图片。 BufferedImage img; // 空的画笔。 Graphics2D graphics2d; (graphics2d = (img = new BufferedImage(w, h, type)) .createGraphics()).setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); // 旋转,degree是整型,度数,比如垂直90度。 graphics2d.rotate(Math.toRadians(degree), w / 2, h / 2); // 从bufferedimagecopy图片至img,0,0是img的坐标。 graphics2d.drawImage(bufferedimage, 0, 0, null); graphics2d.dispose(); // 返回复制好的图片,原图片依然没有变,没有旋转,下次还可以使用。 return img; } /** * 截取视频指定帧保存为指定格式的图片(图片保存在视频同文件夹下) * * @param videofile 视频地址 * @param imgSuffix 图片格式 * @param indexFrame 第几帧(默认:5) * @throws Exception */ public static void fetchFrame(String videofile, String imgSuffix, Integer indexFrame) throws Exception { if (indexFrame == null) { indexFrame = 5; } Integer suffixIndex = videofile.lastIndexOf("."); File targetFile = new File((suffixIndex != -1 ? videofile.substring(0, suffixIndex) : videofile) + imgSuffix); try (FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile); OutputStream outputStream = new FileOutputStream(targetFile)) { ff.start(); ff.setFrameNumber(indexFrame); Frame f = ff.grabImage(); Java2DFrameConverter converter = new Java2DFrameConverter(); BufferedImage fecthedImage = converter.getBufferedImage(f); ImageIO.write(fecthedImage, "jpg", outputStream); } } public static void main(String[] args) { try { fetchFrame("C:\\Users\\Desktop\\b9aef3a28becab2e9e3c544caf70bfde.mp4", ".jpg", 100); buildGif("C:\\Users\\Desktop\\b9aef3a28becab2e9e3c544caf70bfde.mp4", 50, 10, 3, 50); } catch (Exception e) { e.printStackTrace(); } }} 2 3package com.richinfo.media.utils;import lombok.SneakyThrows;import org.apache.commons.io.IOUtils;import org.bytedeco.javacpp.avcodec;import org.bytedeco.javacv.CanvasFrame;import org.bytedeco.javacv.FFmpegFrameGrabber;import org.bytedeco.javacv.FFmpegFrameRecorder;import org.bytedeco.javacv.Frame;import javax.swing.*;/** * @author * @create */public class Test { private static boolean isStart = true; @SneakyThrows public static void main(String[] args) { frameRecord("C:\\Users\\Desktop\\b9aef3a28becab2e9e3c544caf70bfde.mp4", "C:\\Users\\Desktop\\b9aef3a28becab2e9e3c544caf70bf602.mp4"); } public static void frameRecord(String inputFile, String outputFile) throws Exception, org.bytedeco.javacv.FrameRecorder.Exception { // 获取视频源 FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile); grabber.setOption("rtsp_transport", "tcp");// //速度// grabber.setFrameRate(30);// //码率// grabber.setVideoBitrate(3000000); // 流媒体输出地址,分辨率(长,高),是否录制音频(0:不录制/1:录制) FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile, 2);// recorder.setFrameRate(30); recorder.setVideoBitrate(720 * 576); //编码格式 recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); //avcodec.AV_CODEC_ID_H264 //AV_CODEC_ID_MPEG4 recordByFrame(grabber, recorder); } private static void recordByFrame(FFmpegFrameGrabber grabber, FFmpegFrameRecorder recorder) throws Exception, org.bytedeco.javacv.FrameRecorder.Exception { try {// 建议在线程中使用该方法 grabber.start();// CanvasFrame canvas = new CanvasFrame("摄像头");//新建一个窗口// canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// canvas.setAlwaysOnTop(true); recorder.setImageHeight(grabber.getImageHeight()); recorder.setImageWidth(grabber.getImageWidth()); recorder.start(); long t1 = System.currentTimeMillis(); Frame frame = null; while (isStart && (frame = grabber.grabFrame()) != null) { long t2 = System.currentTimeMillis(); if (t2 - t1 > 2 * 60 * 60 * 1000) { break; } else {//视频转音频 grabber.grabSamples(); recorder.record(frame); //TODO your work } //canvas.showImage(grabber.grab());//获取摄像头图像并放到窗口上显示, 这里的Frame frame=grabber.grab(); frame是一帧视频图像 } recorder.stop(); grabber.stop(); } finally { IOUtils.closeQuietly(recorder); IOUtils.closeQuietly(grabber); } }}相关依赖:<!-- 视频截图 --><dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv-platform</artifactId> <version>1.4.4</version></dependency><!-- gif --><dependency> <groupId>com.madgag</groupId> <artifactId>animated-gif-lib</artifactId> <version>1.4</version></dependency><!--lombok --><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.8</version></dependency> 4 5<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version></dependency>
点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Topaz Video AI for mac(视频增强和修复工具)

TopazVideoAIforMac是一款视频增强和修复工具,采用了人工智能技术,可以提高视频的清晰度、降噪、去抖动和插帧等。这款软件支持多种视频格式,包括MP4、MOV、AVI等。使用TopazVideoAIforMac,用户只需将需要处理的视频导入到软

javacv开发详解之1:调用本机摄像头视频

前言:javacv开发包是用于支持java多媒体开发的一套开发包,可以适用于本地多媒体(音视频)调用以及音视频,图片等文件后期操作(图片修改,音视频解码剪辑等等功能),这里只使用最简单的本地摄像头调用来演示一下javacv的基础功能重要:建议使用最新javaCV1.3版本,该版本已解决更早版本中已发现的大部分bugjavacv系

Topaz Video AI for mac(视频增强和修复工具)

TopazVideoAI是一款使用人工智能技术对视频进行增强和修复的软件。它可以自动降噪、去除锐化、减少压缩失真、提高清晰度等等。TopazVideoAI可以处理各种类型的视频,包括低分辨率视频、老旧影片、手机录制的视频等等。除了增强和修复视频效果,Top

moviepy简介及安装

一、概述MoviePy是一个用于视频编辑的Python模块,可用于进行视频的基本操作(如剪切、连接、标题插入)、视频合成(也称非线性编辑)、视频处理或创建高级效果。它可以读写最常见的视频格式,包括GIF。MoviePy能处理的视频是ffmpeg格式的,老猿理解支持的文件类型至少包括:\.mp4\.wmv\.rm\.avi\.flv\.webm\.

03.视频播放器Api说明

03.视频播放器Api说明目录介绍01.最简单的播放02.如何切换视频内核03.切换视频模式04.切换视频清晰度05.视频播放监听06.列表中播放处理07.悬浮窗口播放08.其他重要功能Api09.播放多个视频10.