Java调用ffmpeg进行视频转码

2021-09-17  本文已影响0人  爱恨_交加

使用java调用ffmpeg进行视频转码,适合windows和linux环境

测试结论

可以使用多线程调用ffmpeg命令执行转码,但不推荐。因为使用多线程并不能提高视频转码效率,相反,它会导致单个的视频转码效率成比例的降低,虽然总体耗时差不多。 综述,推荐使用有且只有一个线程用于调用ffmpeg命令执行视频转码。详情见 https://gitee.com/springboot_learning/springboot-ffmpeg/blob/master/HELP.md 的"性能消耗情况如何?"一节

关键代码块

    @Async("ffmpegExecutor")
    @Override
    public void execVideoTranscode(File ffmpegCmd, boolean isWindows, String sourceFile, String targetFile) {
        Runtime runtime = null;
        try {
            log.info("<<开始视频转码>> 文件名:{}", sourceFile);
            runtime = Runtime.getRuntime();
            long startTime = System.currentTimeMillis();
            String cmd = ffmpegCmd.getAbsolutePath() + " -y -i " + sourceFile + " -vcodec libx264 -vf scale=\"iw/1:ih/1\" " + targetFile;
            log.info("<<命令>> {}", cmd);
            Process process = null;
            if(isWindows){
                process = runtime.exec(cmd);
            }else{
                process = runtime.exec(new String[]{"sh", "-c", cmd});
            }
            // 通过读取进程的流信息,可以看到视频转码的相关执行信息,并且使得下面的视频转码时间贴近实际的情况
            BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String line = null;
            while((line = br.readLine()) != null){
                log.debug("<<视频执行信息>> {}", line);
            }
            br.close();
            log.info("<<开始关闭进程相关流>>");
            process.getOutputStream().close();
            process.getInputStream().close();
            process.getErrorStream().close();
            long endTime = System.currentTimeMillis();
            log.info("<<视频转码完成>> 耗时 {}ms", (endTime - startTime));
        } catch (IOException e) {
            log.error("<<视频转码失败,原因:发生IO异常>>");
        } finally {
            if(Objects.nonNull(runtime)){
                runtime.freeMemory();
            }
        }
    }

完整代码

https://gitee.com/springboot_learning/springboot-ffmpeg.git

tip: 请先阅读项目中根目录下的HELP.md文件

上一篇 下一篇

猜你喜欢

热点阅读