zoukankan      html  css  js  c++  java
  • 一个在linux环境执行io操作的bug

    今天项目有了一个奇葩的要求。。。是什么呢

    后台上传了视频后,解析其中的时长,和预览图,并拼接在一起,然而,之东西并不是太麻烦,很快写好了,在本地测试后也没有问题,嗯,发布到测试环境后,一个jar包报错,看到这想想今天要加班了/../

    出现的错误是javacv解析视频后,一个jni错误/home/travis/build/javacpp-presets/opencv/cppbuild/linux-x86_64/opencv-3.4.2/modules/videostab/src/frame_source.cpp:71: error: (0:No Error) can't open file:

    在git的lssues提交了一个问题后,很快有大佬跟我交流了,也就是基本说说,你怎么使用的,并没有解决我的问题

    总不能晾着啊,所以苦逼的我,到ffmpeg官网下载了他们的源码,在linux编译了有半小时,总算完成了,在我 的window上同样装了一个环境,

    下面是我的一个错误代码,在linux上获取一个视频的时长,嗯没问题,放到环境后,打印日志后什么都没有发生。。。。。。。。。。。

       public static  int getliunxFileLenth(String fileName) throws  InterruptedException {
            String command = "ffmpeg -i "+fileName+" 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//";
            Runtime rt = Runtime.getRuntime();
            InputStream inputStream = null;
            Process proc = null;
            String line = null;
            BufferedReader reader=null;
            try {
                proc = rt.exec(command);
    
               inputStream = proc.getInputStream();
               reader = new BufferedReader(new InputStreamReader(inputStream));
               
    
                while ((line = reader.readLine()) != null){
                    line = line;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    inputStream.close();
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            return DateUtil.getSecond(line);
        }

    先说下出现这种问题的原因是什么把,第一,ffmpeg使用异步io处理文件的,所以,

      proc = rt.exec(command);这种方式只是给系统一个通知,,
    第二,window与liunx不同的地方是,处处是阻塞,linux之所以能很好的完成大并发,靠的就是异步io,
    而window之所以图形界面做的好,是因为,系统之间的阻塞通知,可以让系统运行在一个流程中。

    解决的办法就是让通知阻塞我们的程序,

     public static  int getliunxFileLenth(String fileName) throws  InterruptedException {
            List<String> commands = new ArrayList<>();
            commands.add("ffmpeg");
            commands.add("-i");
            commands.add(fileName);
            try {
                ProcessBuilder builder = new ProcessBuilder();
                int time = 0;
                builder.command(commands);
                Process p = builder.start();
                
                //从输入流中读取视频信息
                BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
                StringBuilder stringBuilder = new StringBuilder();
                String line = "";
                while ((line = br.readLine()) != null) {
                    stringBuilder.append(line);
                }
                p.waitFor();//阻塞
                br.close();
    
                //从视频信息中解析时长
                String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\d*) kb\/s";
    
    。。。。。。。。。。。。
    .waitFor();//阻塞
     
  • 相关阅读:
    php文件下载方法收藏(附js下载技巧)
    微信自定义菜单类简单开发样例
    支付宝即时到账以及扫码支付相关注意事项
    ob系列函数归纳
    去除博客园底部图片广告的CSS代码
    TortoiseGit自动记住用户名密码的方法
    推荐分享一个牛X的自定义PHP加密解密类
    自动判断PC端、手机端跳往不同的域名JS实现代码
    unity 中 Tilemap的使用 笔记
    unity 判断平台(安卓,iOS还是编辑器)
  • 原文地址:https://www.cnblogs.com/dmeck/p/9457120.html
Copyright © 2011-2022 走看看