javaCV

Wesley13
• 阅读 921

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

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

  先上代码。

package 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(); } }}

package 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>

<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version></dependency>
点赞
收藏
评论区
推荐文章
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Karen110 Karen110
3年前
moviepy简介及安装
一、概述MoviePy是一个用于视频编辑的Python模块,可用于进行视频的基本操作(如剪切、连接、标题插入)、视频合成(也称非线性编辑)、视频处理或创建高级效果。它可以读写最常见的视频格式,包括GIF。MoviePy能处理的视频是ffmpeg格式的,老猿理解支持的文件类型至少包括:\.mp4\.wmv\.rm\.avi\.flv\.webm\.
春风化雨 春风化雨
1年前
Topaz Video AI for mac(视频增强和修复工具)
TopazVideoAIforMac是一款视频增强和修复工具,采用了人工智能技术,可以提高视频的清晰度、降噪、去抖动和插帧等。这款软件支持多种视频格式,包括MP4、MOV、AVI等。使用TopazVideoAIforMac,用户只需将需要处理的视频导入到软
Wesley13 Wesley13
3年前
javacv开发详解之1:调用本机摄像头视频
前言:javacv开发包是用于支持java多媒体开发的一套开发包,可以适用于本地多媒体(音视频)调用以及音视频,图片等文件后期操作(图片修改,音视频解码剪辑等等功能),这里只使用最简单的本地摄像头调用来演示一下javacv的基础功能重要:建议使用最新javaCV1.3版本,该版本已解决更早版本中已发现的大部分bugjavacv系
仲远 仲远
1年前
Topaz Video AI for mac(视频增强和修复工具)
TopazVideoAI是一款使用人工智能技术对视频进行增强和修复的软件。它可以自动降噪、去除锐化、减少压缩失真、提高清晰度等等。TopazVideoAI可以处理各种类型的视频,包括低分辨率视频、老旧影片、手机录制的视频等等。除了增强和修复视频效果,Top
Wesley13 Wesley13
3年前
03.视频播放器Api说明
03.视频播放器Api说明目录介绍01.最简单的播放02.如何切换视频内核03.切换视频模式04.切换视频清晰度05.视频播放监听06.列表中播放处理07.悬浮窗口播放08.其他重要功能Api09.播放多个视频10.
Stella981 Stella981
3年前
Serverless 实现视频压缩与格式转换
在Serverless架构的应用案例中,有这样一个非常实在的应用:视频的处理。腾讯云的函数计算平台对这个领域的描述:视频应用、社交应用等场景下,用户上传的图片、音视频的总量大、频率高,对处理系统的实时性和并发能力都有较高的要求。例如:对于用户上传的视频短片,我们可以使用多个云函数对其分别处理,对应不同的清晰度(1080p、720p等),以满足
流浪剑客 流浪剑客
1年前
「最新」Premiere Pro 2024 for Mac中文版
是一款功能强大的视频编辑软件,它为专业剪辑师和视频爱好者提供了无限创意的可能。以下是PremierePro2024的中文介绍:PremierePro2024是一款专业的非线性视频编辑软件,它可以帮助您轻松地完成视频剪辑、特效处理、音频调整和字幕设计等工作。
铁扇公主 铁扇公主
1年前
mac电脑视频管理软件:Topaz Video AI 激活最新版
TopazVideoAI是一款视频处理软件,利用人工智能技术对视频进行多种增强和修复操作,提高视频的质量和清晰度。以下是TopazVideoAI软件的主要功能:视频增强:该软件可以自动增强视频的细节和清晰度,修复模糊、噪点和压缩失真等问题,提高视频的观看体
流浪剑客 流浪剑客
1年前
Dynamic Wallpaper 16.7中文破解下载「最新」
是一款Mac平台上的动态壁纸应用程序,它让用户可以使用动态壁纸来为自己的桌面增添一些活力。这个软件可以使用几乎任何类型的动态视频或者图片,包括GIF、MOV、MP4等等,并且支持高清晰度的视频和超过24小时的时间长度。DynamicWallpaper的用户