springboot 通过 javaCV 实现视频裁剪

编程入门 行业动态 更新时间:2024-10-08 04:32:13

springboot 通过 javaCV 实现<a href=https://www.elefans.com/category/jswz/34/1771437.html style=视频裁剪"/>

springboot 通过 javaCV 实现视频裁剪

导入依赖

 	 <properties><java.version>1.8</java.version><ffmpeg.version>0.6.2</ffmpeg.version><javacv.version>1.5.8</javacv.version><javacpp.version>1.5.8</javacpp.version><bytedeco-ffmpeg.version>5.1.2-1.5.8</bytedeco-ffmpeg.version><opencv-platform-gpu.version>4.6.0-1.5.8</opencv-platform-gpu.version><javacpp.platform.dependencies>windows-x86_64</javacpp.platform.dependencies><javacpp.platform.linux-x86_64>linux-x86_64</javacpp.platform.linux-x86_64><!-- 跳过测试 --><skipTests>true</skipTests></properties><!-- maven依赖 --><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--  javacv -->
<!--        <dependency>-->
<!--            <groupId>org.bytedeco</groupId>-->
<!--            <artifactId>javacv-platform</artifactId>-->
<!--            <version>1.5.8</version>-->
<!--        </dependency>--><!-- Optional GPL builds with (almost) everything enabled --><!--        <dependency>--><!--            <groupId>org.bytedeco</groupId>--><!--            <artifactId>ffmpeg-platform-gpl</artifactId>--><!--            <version>5.1.2-1.5.8</version>--><!--        </dependency>--><!--  ========== 优化依赖 ffmpeg-platform-gpl javacv-platform 只导入windows liunx平台 ==============  --><dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>${javacv.version}</version><exclusions><exclusion><groupId>org.bytedeco</groupId><artifactId>javacpp</artifactId></exclusion></exclusions></dependency><!-- 获取视频中的图片 --><dependency><groupId>org.bytedeco</groupId><artifactId>javacpp</artifactId><version>${javacpp.version}</version><classifier>${javacpp.platform.dependencies}</classifier></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>javacpp</artifactId><version>${javacpp.version}</version><classifier>${javacpp.platform.linux-x86_64}</classifier></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>ffmpeg</artifactId><version>${bytedeco-ffmpeg.version}</version><classifier>linux-x86_64-gpl</classifier></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>ffmpeg</artifactId><version>${bytedeco-ffmpeg.version}</version><classifier>windows-x86_64-gpl</classifier></dependency><dependency><groupId>net.bramp.ffmpeg</groupId><artifactId>ffmpeg</artifactId><version>${ffmpeg.version}</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>opencv-platform-gpu</artifactId><version>${opencv-platform-gpu.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

核心方法

	/*** 视频转分辨率转视频编码** @param inputFile   源文件* @param outputPath  输出目录* @param filterContent  过滤器配置参数* @param width       需要转成的视频的宽度* @param height      需要转成的视频的高度* @param videoFormat 需要转换成的视频格式* @return 返回新文件名称,可以根据实际使用修改*/public static String videoConvert(String inputFile, String outputPath,String filterContent, Integer width, Integer height, String videoFormat) {List<String> paths = Splitter.on(".").splitToList(inputFile);String ext = paths.get(paths.size() - 1);if (StringUtils.isEmpty(videoFormat)) {videoFormat = ext;}String newFileName = UUID.randomUUID().toString().replaceAll("-","") + "." + videoFormat;String resultPath = Joiner.on(File.separator).join(Arrays.asList(outputPath, newFileName));Frame frame;FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile);FFmpegFrameRecorder recorder = null;double aspectRatio = 1.0;FFmpegFrameFilter filter =new FFmpegFrameFilter(filterContent,grabber.getImageWidth(),grabber.getImageHeight());try {// 初始化帧抓取器,例如数据结构(时间戳、编码器上下文、帧对象等),// 如果入参等于true,还会调用avformat_find_stream_info方法获取流的信息,放入AVFormatContext类型的成员变量oc中grabber.start(true);// grabber.start方法中,初始化的解码器信息存在放在grabber的成员变量oc中//过滤器启动filter.start();AVFormatContext avformatcontext = grabber.getFormatContext();// 文件内有几个媒体流(一般是视频流+音频流)int streamNum = avformatcontext.nb_streams();// 没有媒体流就不用继续了if (streamNum < 1) {log.info("视频文件格式不对");return "error";}// 取得视频的帧率int framerate = (int) grabber.getVideoFrameRate();log.info("视频帧率:{},视频时长:{}秒,媒体流数量:{}", framerate, avformatcontext.duration() / 1000000,streamNum);// 遍历每一个流,检查其类型for (int i = 0; i < streamNum; i++) {AVStream avstream = avformatcontext.streams(i);AVCodecParameters avcodecparameters = avstream.codecpar();log.info("流的索引:{},编码器类型:{},编码器ID:{}", i, avcodecparameters.codec_type(),avcodecparameters.codec_id());}// 源视频宽度int frameWidth = grabber.getImageWidth();// 源视频高度int frameHeight = grabber.getImageHeight();// 源音频通道数量int audioChannels = grabber.getAudioChannels();log.info("源视频宽度:{},源视频高度:{},音频通道数:{}", frameWidth, frameHeight, audioChannels);AVFormatContext ifmt_ctx = grabber.getFormatContext();AVStream inpVideoStream = null,inpAudioStream = null;if (ifmt_ctx != null) {//获取Video的AVStreaminpVideoStream = ifmt_ctx.streams(grabber.getVideoStream());//不能使用 inpVideoStream.sample_aspect_ratio()AVRational SAR = inpVideoStream.codecpar().sample_aspect_ratio();double a = (double) SAR.num() / (double) SAR.den();//默认情况为1:1aspectRatio = a == 0.0 ? 1.0 : a;int SARden = SAR.den();int SARnum = SAR.num();log.info("SARden[{}], SARnum[{}]", SARden, SARnum);}recorder = new FFmpegFrameRecorder(resultPath, width, height, audioChannels);// 设置H264编码
//            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);// 设置视频格式recorder.setFormat(videoFormat);// 使用原始视频的码率,若需要则自行修改码率recorder.setVideoBitrate(grabber.getVideoBitrate());// 一秒内的帧数,帧率recorder.setFrameRate(framerate);// 两个关键帧之间的帧数recorder.setGopSize(framerate);// 设置音频通道数,与视频源的通道数相等recorder.setAudioChannels(grabber.getAudioChannels());//给录制器设置SARrecorder.setAspectRatio(aspectRatio);recorder.start();int videoFrameNum = 0;int audioFrameNum = 0;int dataFrameNum = 0;// 持续从视频源取帧while (null != (frame = grabber.grab())) {// 有图像,就把视频帧加一if (null != frame.image) {videoFrameNum++;//把已经解码后的视频图像像素塞进过滤器filter.push(frame);//取出过滤器处理后的图像像素数据Frame filterFrame =filter.pullImage();// 取出的每一帧,都保存到视频recorder.record(filterFrame);}// 有声音,就把音频帧加一if (null != frame.samples) {audioFrameNum++;// 取出的每一帧recorder.record(frame);}// 有数据,就把数据帧加一if (null != frame.data) {dataFrameNum++;}}log.info("转码完成,视频帧:{},音频帧:{},数据帧:{}", videoFrameNum, audioFrameNum, dataFrameNum);} catch (Exception e) {log.error(e.getMessage());return "error";} finally {if (recorder != null) {try {recorder.close();} catch (Exception e) {log.info("recorder.close异常" + e);}}try {filter.close();} catch (FrameFilter.Exception e) {log.info("filter.close异常" + e);}try {grabber.close();} catch (FrameGrabber.Exception e) {log.info("frameGrabber.close异常" + e);}}return newFileName;}

测试方法调用

					//crop=width:height::x:yvideoConvert("D:\\testvedio\\1673244765519.mp4","D:\\testvedio\\",MessageFormat.format("crop={0}:{1}:{2}:{3}",String.valueOf(360),String.valueOf(360),String.valueOf(0),String.valueOf(0)),360,360,"mp4");

更多推荐

springboot 通过 javaCV 实现视频裁剪

本文发布于:2024-02-07 06:15:44,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1753847.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:视频   springboot   javaCV

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!