Java 调用ffmpeg 实现视频编辑

1. 前言

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。

2.1 实现格式转换功能

该方法就设置了一个入参,即文件路径。参数ffmpegPath是@value引入的yml配置,如下图
在这里插入图片描述
指向的路径下放入FFmpeg的.exe文件即可。
在这里插入图片描述

    @Value("${ffmpeg.path}")
    String ffmpegPath;

public  String transCoding(String path) throws IOException {
        String ffmpegExePath = new ClassPathResource(ffmpegPath+"/ffmpeg.exe").getAbsolutePath();
        ArrayList<String> command = 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 = "E:\\data\\split\\" + IdUtil.simpleUUID() + ".mp4";
        command.add(s);
        // 执行操作
        ProcessBuilder builder = new ProcessBuilder();
        builder.command(command);
        builder.redirectErrorStream(true);
        Process process = builder.start();
        return s;
    }

2.2 实现视频剪辑

 public String videoSpit(String path, String startTime, String duration) throws IOException {
        int i = Integer.parseInt(startTime) / 1000;
        int i1 = Integer.parseInt(duration) / 1000;
        String ffmpegExePath = new ClassPathResource(ffmpegPath +"/ffmpeg.exe").getAbsolutePath();
        List<String> command = 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 "文件不存在,请检查!!";
        }
        command.add(path);
        command.add("-codec");
        command.add("copy");
        command.add("-avoid_negative_ts");
        command.add("1");
        String s = IdUtil.simpleUUID();
        //本地开发写死路径
        String substring = path.substring(path.lastIndexOf("."));
        String e1 = "E:\\data\\split\\" + s + path.substring(path.lastIndexOf("."));
        StringBuilder stringBuffer = new StringBuilder();
        //业务需求,判断是否为mp4,如不需要可以去掉
        if (!"mp4".equals(substring)) {
            String s1 = transCoding(e1);
            command.add(s1);
            stringBuffer.append(s1);
        }else {
            command.add(e1);
            stringBuffer.append(e1);
        }
        try {
            System.out.println(command);
            ProcessBuilder builder = new ProcessBuilder();

            builder.command(command);
            //正常信息和错误信息合并输出

            builder.redirectErrorStream(true);

            //开始执行命令

            Process process = builder.start();
            //如果你想获取到执行完后的信息,那么下面的代码也是需要的

            StringBuilder sbf = new StringBuilder();

            String line;

            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));

            while ((line = br.readLine()) != null) {

                sbf.append(line);

                sbf.append(" ");

            }

            String resultInfo = sbf.toString();

            System.out.println(resultInfo);
            System.out.println(stringBuffer);
            return stringBuffer.toString();
        } catch (IOException e) {
            e.printStackTrace();

        }
        return "操作失败";
    }

path 是文件路径,startTime是开始时间,duration是持续时间,我这里传入的时间是ms,所以先转换成s。方便FFmpeg处理

2.3 实现对指定区域的裁剪并切割

public void spit(String filePath, Integer startTime, String location, String continuous, Integer number) throws IOException {
        ArrayList<String> command = new ArrayList<>();
        DecimalFormat df = new DecimalFormat("0.00");
        StringBuilder stringBuffer = new StringBuilder();
        for (int i = 0; i < number; i++) {
            command.add("E:\\data\\ffmpeg.exe");
            command.add("-ss");
            String format = df.format((float) i / number + startTime);
            System.out.println("开始时间" + format);
            command.add(String.valueOf(format));
            command.add("-i");
            command.add(filePath);
            command.add("-strict");
            command.add("-2");
            command.add("-vf");
            command.add(location);
            command.add("-t");
            command.add(continuous);
            String s = "E:\\data\\spit-test\\2s\\" + format + ".mp4";
            System.out.println(s);
            command.add(s);
            ProcessBuilder builder = new ProcessBuilder();
            builder.command(command);
            System.out.println(command);
            builder.redirectErrorStream(true);
            Process process = builder.start();
            command.removeAll(command);
            StringBuilder sbf = new StringBuilder();

            String line;

            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));

            while ((line = br.readLine()) != null) {

                sbf.append(line);

                sbf.append(" ");

            }

            String resultInfo = sbf.toString();

            System.out.println(resultInfo);
            System.out.println(stringBuffer);
        }
    }

filePath 文件路径
startTime 开始时间(单位/s)
location 裁剪的位置,格式如:crop=w=100:h=100:x=12:y=34 ,其中w和h指的是裁剪完的帧宽度和帧高度,x和y指裁剪的坐标点,裁剪时会按照该点坐标往右下裁剪。
continuous 持续时间
number 颗粒度 该参数是业务为需求定制,因为我需要按照业务会把视频以0.1s、0.01s切片,则此参数影响for循环次数,根据具体业务修改

截取前:
在这里插入图片描述

截取后:
在这里插入图片描述

  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值