javacv截取视频截图-1.5.7版本精简包
1.需求背景:
相机上传的视频,没有上传封面,需要后台对云存储上的视频,添加封面后,保存封面和视频地址在数据库中。
2. JavaCV 简介
JavaCV是对各种常用计算机视觉库的封装后的一组jar包,其中封装了FFmpeg、OpenCV等计算机视觉编程人员常用库的接口,可以通过其中的Utility类方便的在包括Android在内的Java平台上调用这些接口。其中使用最多的应该就是FFmpeg了。
最开始Javacv是googlecode下面的一个项目,后来迁移到了github,因此JavaCV相关的包名也由com.googlecode.javacv
改为org.bytedeco.javacv。
项目地址:https://github.com/bytedeco/javacv
3. JavaCV 基本使用指南
从github项目中下载打包好的jar包,其中javacpp.jar 和 javacv.jar是必须的两个包,然后需要什么功能就添加额外的包。例如我需要用到ffmpeg进行视频录制,则需要添加ffmpeg.jar和ffmpeg-android-arm.jar(打包的arm平台so库)。这里很方便的地方是,so库文件都放在了jar文件里面,在集成的时候很简洁明了。
4.javacv的使用
1.4.x、1.3.x版本的精简jar:
<!--javacv 截取视频封面包--><dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>1.4.3</version><exclusions><exclusion><groupId>org.bytedeco.javacpp-presets</groupId><artifactId>*</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.bytedeco.javacpp-presets</groupId><artifactId>opencv</artifactId><version>3.4.2-1.4.2</version></dependency><dependency><groupId>org.bytedeco.javacpp-presets</groupId><artifactId>opencv</artifactId><version>3.4.2-1.4.2</version><classifier>windows-x86_64</classifier>
<!-- <classifier>linux-x86_64</classifier>--></dependency><!-- https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/ffmpeg --><dependency><groupId>org.bytedeco.javacpp-presets</groupId><artifactId>ffmpeg</artifactId><version>4.0.1-1.4.2</version></dependency><dependency><groupId>org.bytedeco.javacpp-presets</groupId><artifactId>ffmpeg</artifactId><version>4.0.1-1.4.2</version><classifier>windows-x86_64</classifier>
<!-- <classifier>linux-x86_64</classifier>--></dependency><!---->
1.5.x版本后的精简包:
<!--javacv 截取视频封面包--><dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>1.5.7</version><exclusions><exclusion><groupId>org.bytedeco</groupId><artifactId>*</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>ffmpeg</artifactId><version>5.0-1.5.7</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>ffmpeg</artifactId><version>5.0-1.5.7</version>
<!-- <classifier>windows-x86_64</classifier>--><classifier>linux-x86_64</classifier></dependency><!---->
2.实现:
package com.camojojo.device.common.utils;import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import com.camojojo.common.core.utils.AwsFileUtil;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;/*** @author:yuchen* @createTime:2022/7/11 16:07*/@Slf4j
public class VideoUtil {private static final String PATH="/ossRoot/";public static void main(String[] args) {getVideoPic();}public static String getVideoPic() {String url = "https://xxx/xxxx.mp4";String value = "1111123";String dir = value +"/";String fileName = FileUtil.getName(url);// 100.mp4String targetFileName = "thumb_"+fileName.substring(0, fileName.lastIndexOf("."))+".jpg";File filePath = new File(PATH+dir);if (!filePath.exists()) {boolean mkdirs = filePath.mkdirs();if(mkdirs){log.info("文件夹创建成功:{}",filePath.getAbsolutePath());}}String outPath = PATH+dir+targetFileName;File outFile = getScreenshot(url, outPath);if(outFile != null){String fileName1 = AwsFileUtil.uploadS3Us(outFile, imei, targetFileName);System.out.println(fileName1);boolean delete = outFile.delete();if(delete){log.info("删除本地临时文件成功");}return fileName1;}return "";}/*** 获取视频封面图* @param filePath 视频地址* @return map*/private static File getScreenshot(String filePath, String imagePath) {log.info("截取视频截图开始:Video={}",filePath);filePath = filePath.replaceAll("\\\\","/");File output = null;FFmpegFrameGrabber grabber = null;try{grabber = FFmpegFrameGrabber.createDefault(filePath);grabber.start();//设置视频截取帧(建议从5帧开始,防止全是黑屏)Frame frame = null;for (int j = 0; j < 5; j++) {frame = grabber.grabImage();}//视频旋转度String rotate = grabber.getVideoMetadata("rotate");Java2DFrameConverter converter = new Java2DFrameConverter();//绘制图片BufferedImage bi = converter.getBufferedImage(frame);if (rotate != null) {// 旋转图片bi = rotate(bi, Integer.parseInt(rotate));}//创建文件output = new File(imagePath);ImgUtil.write(bi, output);log.info("截取视频截图成功");}catch (Exception e){log.error("获取视频封面图,Error:",e);}finally {if(grabber!=null){try { grabber.stop(); } catch (Exception ignored) { }}}return output;}/*** @Description 根据视频旋转度来调整图片* @param src ""* @param angel 视频旋转度* @return BufferedImage*/private static BufferedImage rotate(BufferedImage src, int angel) {int src_width = src.getWidth(null);int src_height = src.getHeight(null);int type = src.getColorModel().getTransparency();Rectangle rect_des = calcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);BufferedImage bi = new BufferedImage(rect_des.width, rect_des.height, type);Graphics2D g2 = bi.createGraphics();g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2);g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);g2.drawImage(src, 0, 0, null);g2.dispose();return bi;}/*** @Description: 计算图片旋转大小* @param src ""* @param angel ""* @return Rectangle*/private static Rectangle calcRotatedSize(Rectangle src, int angel) {if (angel >= 90) {if (angel / 90 % 2 == 1) {int temp = src.height;src.height = src.width;src.width = temp;}angel = angel % 90;}double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;double angel_dalta_width = Math.atan((double) src.height / src.width);double angel_dalta_height = Math.atan((double) src.width / src.height);int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width));int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));int des_width = src.width + len_dalta_width * 2;int des_height = src.height + len_dalta_height * 2;return new java.awt.Rectangle(new Dimension(des_width, des_height));}}
5.使用Docker部署后,截屏异常
在另一个Docker部署的服务中使用该方法,发现一调用,服务就挂。
最后发现原因是由于那个Docker容器使用的是阉割版的JDK镜像:openjdk:8-jre-alpine ,虽然该镜像能使打包的体积更小,但是容易出现此类的问题,需要换成更完整的JDK镜像。
后面换成: openjdk:8-jre ,就没问题了。
javacv版本1.4.x ,会出现物理内存溢出溢出,网上说是旧版本源码bug,升级到1.5.x版本就修复了,今天升级了,运行一段时间再看。
特此记录。
javacv截取视频截图-1.5.7版本精简包相关推荐
- 基于javacv的视频截图、转码、提取音频
目录 目标 全量依赖 最小依赖 截图配置类 转码配置类 提取音频配置类 源视频处理结果类 核心类 怎么使用 目标 将所有格式的视频转码为H5能播放的mp4格式,也可以截取任意一帧图片 全量依赖 < ...
- javacv音视频截图,音频抽取汇总
概述: java 使用 javacv 视频截帧, 跳到指定帧截图, 从视频中抽取音频, 音频分割为多段 1 依赖: <dependency><groupId>org.byted ...
- java截取视频片段_使用javacv 截取视频指定帧节
个人博客 地址:https://www.wenhaofan.com/article/20190407105818 引入依赖 org.bytedeco javacv 1.4.3 org.bytedeco ...
- 利用 javacv 截取视频帧制作封面及获取视频播放时长
一.Maven依赖 <dependency><groupId>org.bytedeco</groupId><artifactId>javacv</ ...
- 视频截图方法 javacv
第一步 导入依赖 <dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platf ...
- php ffmpeg截图,php ffmpeg截取视频第一帧保存为图片的方法
php ffmpeg截取视频第一帧保存为图片的方法 $xiangmupath = $this->getxiangmupath(); $filename = 'chengshi'; $cmd = ...
- java如何截取视频文件_Java获取视频时长及截取帧截图详解
前言 只是最近碰到有这方面的项目需求,所以简单 Mark 下本文.下面的示例是参考过他人分享的文章,之后本人再自行实践.调整和测试过的,希望对有这方面需求的人有所帮助. 示例 添加依赖 org.byt ...
- java使用ffmpeg截取视频某个时间点的截图
1.软件安装 mac brew install ffmpeg 安装后路径:"/usr/local/Cellar/ffmpeg/4.0.1/bin ffmpeg –version 查看版本 l ...
- php截取视频第一帧为图片,把视频变成一帧一帧的图片(ae怎么把视频变成单帧) 视频截图视频画面每帧图片截取...
AE怎么把视频变成单帧?这是小编今天要与大家讨论及解决的一个问题.在视频后期处理中,有时为实现某个场景效果,需要把视频中的某帧变成静态帧图片:或者需要视频截图视频画面每帧图片截取出来,把视频变成一帧一 ...
- java结合ffmpeg实现多个视频截图,按时长平均分割截取固定数量
java结合ffmpeg实现多个视频截图,按时长平均分割截取固定数量 本工具简单介绍 使用方式 效果展示 工具源码 本工具简单介绍 先强调下,本工具可以直接上手使用. 本来ffmpeg就可以支持很多功 ...
最新文章
- Java 中文转拼音
- ORACLE纯SQL实现多行合并一行
- CSDN Github Markdown编辑常用功能符号补充
- hdu 2059(dp)
- JQ获取CKeditor的值
- AliOS Things网络适配框架 - SAL
- gms签名不一致_第三方稳定不掉ios软件企业签名怎么买
- Vmware虚拟机不能使用键盘的解决方法
- 距离一个优秀程序员,你还差多少?
- (16)机器学习_ROC曲线绘制
- linux环境安装ffmepg,Linux centOS下安装FFmpeg
- 2019eclipse 中文汉化包 安装教程
- [AngularJS面面观] 15. 依赖注入 --- 初识注入器(Injector)
- python获取股票分时数据_AkShare-股票数据-分时数据
- 这些免费、可商用的图片素材网站,绝对不能错过
- aspose合并单元格
- nintendo掌机
- 山东省非计算机专业,山东省高校非计算机专业教学考试(选择、判断含答案)2...
- vue 使用swper组件
- 毕业设计之基于Qt数字音频处理软件设计