作者:手机用户2502914287 | 来源:互联网 | 2023-07-21 08:50
1.前言FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决
1. 前言
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
2.1 实现格式转换功能
该方法就设置了一个入参,即文件路径。参数ffmpegPath是@value引入的yml配置,如下图
指向的路径下放入FFmpeg的.exe文件即可。
&#64;Value("${ffmpeg.path}")String ffmpegPath;public String transCoding(String path) throws IOException {String ffmpegExePath &#61; new ClassPathResource(ffmpegPath&#43;"/ffmpeg.exe").getAbsolutePath();ArrayList command &#61; new ArrayList<>();command.add(ffmpegExePath);command.add("-i");command.add(path);command.add("-vcodec");command.add("copy");command.add("-f");command.add("mpegts");String s &#61; "E:\\data\\split\\" &#43; IdUtil.simpleUUID() &#43; ".mp4";command.add(s);// 执行操作ProcessBuilder builder &#61; new ProcessBuilder();builder.command(command);builder.redirectErrorStream(true);Process process &#61; builder.start();return s;}
2.2 实现视频剪辑
public String videoSpit(String path, String startTime, String duration) throws IOException {int i &#61; Integer.parseInt(startTime) / 1000;int i1 &#61; Integer.parseInt(duration) / 1000;String ffmpegExePath &#61; new ClassPathResource(ffmpegPath &#43;"/ffmpeg.exe").getAbsolutePath();List command &#61; new ArrayList<>();command.add(ffmpegExePath);command.add("-ss");command.add(String.valueOf(i));command.add("-t");command.add(String.valueOf(i1));command.add("-accurate_seek");command.add("-i");if (!FileUtil.file(path).isFile()) {return "文件不存在&#xff0c;请检查&#xff01;&#xff01;";}command.add(path);command.add("-codec");command.add("copy");command.add("-avoid_negative_ts");command.add("1");String s &#61; IdUtil.simpleUUID();//本地开发写死路径String substring &#61; path.substring(path.lastIndexOf("."));String e1 &#61; "E:\\data\\split\\" &#43; s &#43; path.substring(path.lastIndexOf("."));StringBuilder stringBuffer &#61; new StringBuilder();//业务需求&#xff0c;判断是否为mp4&#xff0c;如不需要可以去掉if (!"mp4".equals(substring)) {String s1 &#61; transCoding(e1);command.add(s1);stringBuffer.append(s1);}else {command.add(e1);stringBuffer.append(e1);}try {System.out.println(command);ProcessBuilder builder &#61; new ProcessBuilder();builder.command(command);//正常信息和错误信息合并输出builder.redirectErrorStream(true);//开始执行命令Process process &#61; builder.start();//如果你想获取到执行完后的信息&#xff0c;那么下面的代码也是需要的StringBuilder sbf &#61; new StringBuilder();String line;BufferedReader br &#61; new BufferedReader(new InputStreamReader(process.getInputStream()));while ((line &#61; br.readLine()) !&#61; null) {sbf.append(line);sbf.append(" ");}String resultInfo &#61; sbf.toString();System.out.println(resultInfo);System.out.println(stringBuffer);return stringBuffer.toString();} catch (IOException e) {e.printStackTrace();}return "操作失败";}
path 是文件路径&#xff0c;startTime是开始时间&#xff0c;duration是持续时间&#xff0c;我这里传入的时间是ms&#xff0c;所以先转换成s。方便FFmpeg处理
2.3 实现对指定区域的裁剪并切割
public void spit(String filePath, Integer startTime, String location, String continuous, Integer number) throws IOException {ArrayList command &#61; new ArrayList<>();DecimalFormat df &#61; new DecimalFormat("0.00");StringBuilder stringBuffer &#61; new StringBuilder();for (int i &#61; 0; i
filePath 文件路径
startTime 开始时间&#xff08;单位/s&#xff09;
location 裁剪的位置&#xff0c;格式如&#xff1a;crop&#61;w&#61;100:h&#61;100:x&#61;12:y&#61;34 &#xff0c;其中w和h指的是裁剪完的帧宽度和帧高度&#xff0c;x和y指裁剪的坐标点&#xff0c;裁剪时会按照该点坐标往右下裁剪。
continuous 持续时间
number 颗粒度 该参数是业务为需求定制&#xff0c;因为我需要按照业务会把视频以0.1s、0.01s切片&#xff0c;则此参数影响for循环次数&#xff0c;根据具体业务修改
截取前&#xff1a;
截取后&#xff1a;