> 文章列表 > 视频重置尺寸

视频重置尺寸

视频重置尺寸

两个方法实现视频重置,有兴趣的小伙伴可以看看两个有啥不一样

视频尺寸重置一

import cn.hutool.core.util.IdUtil;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import org.bytedeco.javacpp.Loader;import java.io.File;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;/*** @Description:* @Author:* @Date: 2023/4/6*/
public class ModifyVideoResolution {public static String modifyResolution(String imagePath, String outputDir, Integer width, Integer height, Integer bitRate) throws Exception {if (bitRate == null) {bitRate = 2000;}List<String> paths = Splitter.on(".").splitToList(imagePath);String ext = paths.get(paths.size() - 1);if (!Arrays.asList("mp4").contains(ext)) {throw new Exception("format error");}String resultPath = Joiner.on(File.separator).join(Arrays.asList(outputDir, IdUtil.simpleUUID() + "." + ext));String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);ProcessBuilder builder = new ProcessBuilder(ffmpeg, "-i", imagePath, "-s",MessageFormat.format("{0}*{1}", String.valueOf(width), String.valueOf(height)), "-b",MessageFormat.format("{0}k", String.valueOf(bitRate)), resultPath);builder.inheritIO().start().waitFor();return resultPath;}public static void main(String[] args) throws Exception {System.out.println(modifyResolution("/Users/apple/Desktop/d/2_2.mp4", "/Users/apple/Desktop", 480, 640, null));}}<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.15</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.0.1-jre</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.5</version></dependency>

视频重置方法二

import cn.hutool.core.util.IdUtil;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bytedeco.ffmpeg.avcodec.AVCodecParameters;
import org.bytedeco.ffmpeg.avformat.AVFormatContext;
import org.bytedeco.ffmpeg.avformat.AVStream;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.*;import java.io.File;
import java.util.Arrays;
import java.util.List;
/*** @author hy* @date 2022-06-13 上午 10:38*/
@Slf4j
public class VideoUtils {/*** 视频转分辨率转视频编码** @param inputFile   源文件* @param outputPath  输出目录* @param width       需要转成的视频的宽度* @param height      需要转成的视频的高度* @param videoFormat 需要转换成的视频格式* @return 返回新文件名称,可以根据实际使用修改*/public static String videoConvert(String inputFile, String outputPath, 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 = IdUtil.simpleUUID() + "." + videoFormat;String resultPath =Joiner.on(File.separator).join(Arrays.asList(outputPath, newFileName));FFmpegLogCallback.set();Frame frame;FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile);FFmpegFrameRecorder recorder = null;try {// 初始化帧抓取器,例如数据结构(时间戳、编码器上下文、帧对象等),// 如果入参等于true,还会调用avformat_find_stream_info方法获取流的信息,放入AVFormatContext类型的成员变量oc中grabber.start(true);// grabber.start方法中,初始化的解码器信息存在放在grabber的成员变量oc中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);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());recorder.start();int videoFrameNum = 0;int audioFrameNum = 0;int dataFrameNum = 0;// 持续从视频源取帧while (null != (frame = grabber.grab())) {// 有图像,就把视频帧加一if (null != frame.image) {videoFrameNum++;// 取出的每一帧,都保存到视频recorder.record(frame);}// 有声音,就把音频帧加一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 {grabber.close();} catch (FrameGrabber.Exception e) {log.info("frameGrabber.close异常" + e);}}return newFileName;}public static void main(String[] args) {videoConvert("/Users/apple/Desktop/d/2_2.mp4", "/Users/apple/Desktop", 480, 640, "");}<dependency><groupId>org.jboss.logging</groupId><artifactId>jboss-logging</artifactId><version>3.4.1.Final</version></dependency><!-- UUID --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.16</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.1-jre</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.7</version></dependency>