首页 > 系统相关 >java 调用 ffmpeg 指令获取视频的第 n 帧图片-兼容【linux 和 win】

java 调用 ffmpeg 指令获取视频的第 n 帧图片-兼容【linux 和 win】

时间:2022-12-02 10:44:13浏览次数:59  
标签:java ffmpeg process win pb msg null append String

1.调用

 if (StringUtil.equals(HotCacheData.os, "linux")) {
                msg = processVideo(filePath, n, targetUrl);
 } else {
                if (StringUtil.isEmpty(HotCacheData.ffmpegUrl)) {
                    throw new CustomResultException(ResultEn.FILE_LOADUP_ERROR.getCode(), "win系统ffmpeg的执行文件未找到");
                }
                msg = processVideo(HotCacheData.ffmpegUrl, filePath, n, targetUrl);
}

2.封装的方法

 private static String processVideo(String filePath, int n, String targetUrl) {
        String msg = "";
        StringBuilder commend = new StringBuilder();
        commend.append("ffmpeg ")
                .append(" -i ")
                .append(filePath)
                .append(" -ss ")
                .append(" ").append(n).append(" ")
                .append(" -f ")
                .append(" image2 ")
                .append(targetUrl);
        Process process = null;
        try {
            ProcessBuilder pb = new ProcessBuilder();
            //因为process执行命令并不是像窗口中执行shell一样,所以需要添加参数,用于执行脚本
            pb.command("sh", "-c", commend.toString());
            //processBuilder支持将inputStream与ErrorStream合并为一个Stream,即所有的输出信息都合并到inputStream中,这样做可以减少一个线程
            pb.redirectErrorStream(true);
            process = pb.start();
            //由于process机制原因会导致死锁,所以需要在waitfor方法之前,创建线程用于处理inputstream中缓冲区的数据,这也是为什么要合并inputstream和errorstream的原因,在这里可以少创建一个线程
            readInputStream(process.getInputStream());
            //返回0则表示输出正常
            int resultCode = process.waitFor();
        } catch (Exception e) {
            msg = ExcBox.getExcMsg(e);
            log.info("\n视频解析帧画面异常:");
            log.info(msg);
        } finally {
            try {
                if (null != process) {
                    process.getErrorStream().close();
                    process.getInputStream().close();
                    process.getOutputStream().close();
                }
            } catch (Exception ignored) {
            }
        }
        return msg;
    }
linux
private static String processVideo(String ffmpegPath, String filePath, int n, String targetUrl) {
        String msg = "";
        Process process = null;
        try {
            ProcessBuilder pb = new ProcessBuilder();
            //因为process执行命令并不是像窗口中执行shell一样,所以需要添加参数,用于执行脚本
            pb.command(ffmpegPath, "-y", "-i", filePath, "-ss", n + "", "-f", "image2", targetUrl);
            //processBuilder支持将inputStream与ErrorStream合并为一个Stream,即所有的输出信息都合并到inputStream中,这样做可以减少一个线程
            pb.redirectErrorStream(true);
            process = pb.start();
            //由于process机制原因会导致死锁,所以需要在waitfor方法之前,创建线程用于处理inputstream中缓冲区的数据,这也是为什么要合并inputstream和errorstream的原因,在这里可以少创建一个线程
            readInputStream(process.getInputStream());
            //返回0则表示输出正常
            int resultCode = process.waitFor();
        } catch (Exception e) {
            msg = ExcBox.getExcMsg(e);
            log.info("\n视频解析帧画面异常:");
            log.info(msg);
        } finally {
            try {
                if (null != process) {
                    process.getErrorStream().close();
                    process.getInputStream().close();
                    process.getOutputStream().close();
                }
            } catch (Exception ignored) {
            }
        }
        return msg;
    }
win
 //创建线程处理输出流
    private static void readInputStream(InputStream in) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                InputStreamReader reader = null;
                try {
                    reader = new InputStreamReader(in);
                    LineNumberReader line = new LineNumberReader(reader);
                    String str = null;
                    while ((str = line.readLine()) != null) {
                        System.out.println(str);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (reader != null) {
                            reader.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
共通部分

 

标签:java,ffmpeg,process,win,pb,msg,null,append,String
From: https://www.cnblogs.com/c2g5201314/p/16943695.html

相关文章

  • javascript中generator快速小结
    1基本例子  function*generatorFunc(){console.log("任务一");yield1;console.log("任务二");yield*generatorSubFunc();console.log("任务三");return......
  • java中求两个日期之间的天数
    收藏一个常用的代码段,那就是java中求两个日期间的天数,常见于日历中的两个日期(yyyy-mm-dd)格式,要求它们之间的相差的天数,例子如下:CalendarstartC......
  • (收藏)window.location.hash属性介绍
    ​​http://www.html-js.com/article/JavaScript-focus-and-keyboard​​​location是javascript里边管理地址栏的内置对象,比如location.href就管理......
  • Java学习-笔记本电脑常用快捷键
    #笔记本电脑常用快捷键笔记本快捷键大全图解-百度经验          ......
  • java往oracle存储过程中传递数组方法小结
    java往oracle存储过程中传递数组方法小结,下面是一个例子,比如存储过程中要接受一个数组,并且输出一个数组,则先注意数组在oracle中的定义方法如下:CRE......
  • JAVA字符串处理工具类集合
    //Java拼接字符串时,去掉最后一个多余的逗号Stringstr[]={"hello","beijing","world","shenzhen"};StringBufferbuf=newStringBuffer();for(inti=0;i......
  • JavaScript入门③-函数(2)原理{深入}执行上下文
    00、头痛的JS闭包、词法作用域?被JavaScript的闭包、上下文、嵌套函数、this搞得很头痛,这语言设计的,感觉比较混乱,先勉强理解总结一下......
  • Windows 服务移植到Mono
    系统:CentOS7.0移植过程中遇到的问题执行servicemyserverstart的时候提示“没有权限”处理方式:chmoda+wrx/etc/init.d/myserver执行“ln–s/etc/rc.d/init.d/sjhServe......
  • Win10 Bash初体验
    在今年的Windows开发者大会上微软频频向开发者示好,对我来说大概有以下三个方面的利好消息:Win10支持Bash了!mono团队加入微软,这将有助于微软在.netcore再跨平台上做出突......
  • win10下面部署Mysql数据库
    5.6.24下载地址:​​​http://down10.zol.com.cn/biancgj/mysql_5.6.24_winx64.zip​​下载完成以后解压,在安装目录下面新增my.ini,内容如下:[mysql]#设置mysql客户端默认......