ffmpeg按像素倍数缩放,并截取前5分钟视频(Java)

package com.crayon2f.ffmpeg;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * @author zc
 * @date 2023/8/23
 * @apiNote
 */
public class VideoUtils {

    static String command = "$0 -ss $1 -t $2 -i $3 -vcodec copy -acodec copy $4";


    public static void main(String[] args) {
        //缩放倍数
        int zoom = 5;
        //视频截取时间
        int minute = 5;
        //ffmepg工具地址
        String ffmpegPath = "D:/视频压缩/ffmpeg-git-full_v5.1.2/ffmpeg/bin/ffmpeg.exe";
        //输出存放基础地址
        String outputPath = "D:/视频压缩/待压缩视频";
        //原文件所在文件夹
        List<String> fileList = getFileList(outputPath);

        for (int i = 0; i < fileList.size(); i++) {
            createSubVideo(ffmpegPath, fileList.get(i).replaceAll("\\\\", "/"), outputPath, zoom, minute);

        }

    }

    public static void createSubVideo(String ffmpegPath, String inputPath, String outputPath, int zoom, int minute) {

        boolean result = VideoUtils.convertVideoResolution(inputPath, outputPath + zoom + "倍缩放/", ffmpegPath, zoom);
        if (result) {
            String[] inputPathArray = inputPath.split("/", -1);

            // 剪辑后的视频文件路径
            String videoTargetFilePath = outputPath.split("\\)", -1)[0] + "前" + minute + "分钟";
            outputPath = outputPath + zoom + "倍缩放/" + inputPathArray[inputPathArray.length - 1].split("\\.")[0] + "(" + zoom + "倍缩放).mp4";
            // 剪辑前的视频源文件路径
            String videoResourceFilePath = outputPath;

            // 剪辑开始时间点
            String startTime = "00:00:00";
            // 剪辑视频总时长
            String durationTime = "00:0" + minute + ":00";

            //调用方法
            createSubVideo(ffmpegPath, videoResourceFilePath, videoTargetFilePath, startTime, durationTime);

        }
    }


    /**
     * 视频分辨率按倍数缩放
     *
     * @param inputPath  输入视频路径
     * @param ffmpegPath ffmpeg地址
     * @param Zoom       缩放倍数
     * @return
     */
    public static boolean convertVideoResolution(String inputPath, String outputPath, String ffmpegPath, int Zoom) {

        File file = new File(outputPath);

        if (!file.exists() && !file.isDirectory()) {
            file.mkdir();
        }


        //拼接cmd命令语句
        StringBuffer buffer = new StringBuffer();
        buffer.append(ffmpegPath);
        //注意要保留单词之间有空格
        buffer.append(" -i ");
        buffer.append(inputPath);
        //执行命令语句并返回执行结果
        String definition = null;
        try {
            Process process = Runtime.getRuntime().exec(buffer.toString());
            InputStream in = process.getErrorStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String line;
            while ((line = br.readLine()) != null) {
                if (line.trim().startsWith("Duration:")) {
                    //根据字符匹配进行切割
                    System.out.println("视频时间 = " + line.trim().substring(0, line.trim().indexOf(",")));
                }
                //一般包含fps的行就包含分辨率
                if (line.contains("fps")) {
                    //根据
                    definition = line.split(",")[2];
                    definition = definition.trim().split(" ")[0];
                    System.out.println("分辨率 = " + definition);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        if (definition == null) {
            throw new RuntimeException("视频分辨率获取失败!文件地址:" + inputPath);
        }
        if ("bt709".equals(definition)) {
            definition = "1920x1080";
        }

        String[] resolutions = definition.split("x");
        int width = Integer.parseInt(resolutions[0]) / Zoom;
        int height = Integer.parseInt(resolutions[1]) / Zoom;


        String resolution = width + "x" + height;

        String[] inputPathArray = inputPath.split("/", -1);
        outputPath = outputPath + inputPathArray[inputPathArray.length - 1].split("\\.")[0] + "(" + Zoom + "倍缩放).mp4";


        List<String> command = new ArrayList<>();
        command.add("ffmpeg");
        command.add("-i");
        command.add(inputPath);
        command.add("-vf");
        command.add("scale=" + resolution);
        command.add("-c:a");
        command.add("copy");
        command.add(outputPath);

        try {
            ProcessBuilder builder = new ProcessBuilder(command);
            Process process = builder.start();
            InputStream stderr = process.getErrorStream();
            InputStreamReader isr = new InputStreamReader(stderr);
            BufferedReader br = new BufferedReader(isr);
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println("缩放::" + outputPath + "::::::" + line);
            }
            int exitCode = process.waitFor();
            return exitCode == 0;
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 截取视频
     *
     * @param ffmpegPath            ffmpeg地址
     * @param videoResourceFilePath 源文件地址
     * @param videoTargetFilePath   目标文件地址
     * @param startTime             开始时间
     * @param endTime               结束时间
     * @return
     */
    public static String createSubVideo(String ffmpegPath, String videoResourceFilePath, String
            videoTargetFilePath, String startTime, String endTime) {

        File file = new File(videoTargetFilePath);
        if (!file.exists() && !file.isDirectory()) {
            file.mkdir();
        }

        videoTargetFilePath = videoTargetFilePath + "/" + videoResourceFilePath.split("/")[videoResourceFilePath.split("/").length - 1];

        String str = command.replace("$0", ffmpegPath).replace("$1", startTime).replace("$2", endTime)
                .replace("$3", videoResourceFilePath).replace("$4", videoTargetFilePath);


        Runtime runtime = Runtime.getRuntime();
        try {
            Process proce = runtime.exec(str);
            //处理结果信息Start
            BufferedReader br = new BufferedReader(new InputStreamReader(proce.getErrorStream()));
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println("截取::" + videoTargetFilePath + ":::::::::" + line);
            }
            //处理结果信息Start
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取视频文件列表
     *
     * @param dir
     * @return
     */
    public static List<String> getFileList(String dir) {

        List<String> listFile = new ArrayList<>();

        File dirFile = new File(dir);

        //如果不是目录文件,则直接返回
        if (dirFile.isDirectory()) {
            //获得文件夹下的文件列表,然后根据文件类型分别处理
            File[] files = dirFile.listFiles();
            if (null != files && files.length > 0) {
                //根据时间排序
                Arrays.sort(files, new Comparator<File>() {
                    public int compare(File f1, File f2) {
                        return (int) (f1.lastModified() - f2.lastModified());
                    }

                    public boolean equals(Object obj) {
                        return true;
                    }
                });
                for (File file : files) {
                    //如果不是目录,直接添加
                    if (!file.isDirectory()) {
                        listFile.add(file.getAbsolutePath());
                    } else {
                        listFile.addAll(getFileList(file.getAbsolutePath()));
                    }
                }
            }
        }
        return listFile;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值