一個在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();//阻塞
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章