記 一次幫朋友下載視頻的經歷

記 一次幫朋友下載視頻的經歷

​ 事情的通過是這樣的,晚間有個朋友讓我幫她下載兩個公衆號文章裏的視頻,我想這so easy,經過Chrome打開該文章,經過安裝的瀏覽器插件(貓抓)很快搞定的第一個視頻。java

1581603417(1).jpg

打開第二個視頻後,我發現事情變得有趣起來了。編程

1581604651(1).jpg

視頻還沒加載完,就抓到481個資源,每一個資源都是幾百kb大小的短視頻,一想到下載完還需再想法辦把這幾百個切片視頻整合成一個視頻就頭大,因此想看看還有沒有其餘法子,嘗試了以前成功過的其餘幾個瀏覽器,此次都很差使。。。瀏覽器

​ 沒辦法,先所有下載下來再說。學習

1581604801(1).jpg

全部的ts( Transport Stream)格式的文件加起來一共744個,還有一個是m3u8格式的文件,這個文件就像一個播放列表,應該是記錄每一個文件的播放順序。spa

1581688129(1).jpg

合併文件插件

如今的任務是如何把這些分割的視頻文件合併成一整個視頻文件。code

優先想到Windows的批處理命令,視頻

copy  /b  *.ts  new_fileName.ts

這個命令好像能夠,但前提是這些文件的名稱必需要按照播放的前後順序來命名,否則合併出來的視頻先後內容不連貫,如今須要解決的是如何批量修改文件名稱,blog

1581689047(1).jpg

能夠看出這些文件的命名都是有規律的,第二個下劃線後邊的數字應該就是對應的播放順序,打開文件驗證無誤後,考慮如何批量修改文件名,最後打算本身寫Java代碼經過IO流的方式來修改,代碼以下:資源

public static void rename(){
        String path = "E://a";
        File file = new File(path);
        File[] files = file.listFiles();
        for (File f : files) {
            String old_name = f.getName();
            String[] s = old_name.split("_");
            f.renameTo(new File(path + "/" + s[2]));
        }
    }

執行完畢後,名稱已經被修改過來了。

1581689311(1).jpg

終於要搞定了,執行copy 命令。

結果我仍是高興的太早了,視頻時長正確,可是內容仍是存在不連續的問題,畫面播放一會忽然就跳到另一段內容了。

想看下問題在哪,遂複製了20個視頻,又執行了一遍,過程和結果以下圖:

1581688673(1).jpg

看到右邊的的複製順序就明白了,copy命令應該是將文件名看成字符串了,沒有看成數字,所以會先合併0開頭的文件,再合併1開頭的文件,依次類推,既然找到問題所在,那隻要在執行copy命令時帶上相關參數就能夠了。

1581688489(1).jpg

查看以後發現並無指定相關參數。。。這個方法以失敗了結。

也懶得去網上搜軟件了,因而打算繼續寫Java代碼來搞。本質上就是讀取每一個文件的字節而後寫在一個文件中。

public static void merge() throws IOException {
        String path = "E://a";
        File file = new File(path);
        File[] files = file.listFiles();
        FileOutputStream fileOutputStream = new FileOutputStream("E://b/a.mp4");
        int len;
        byte[] bytes = new byte[4096];
        int index = files.length - 1;
        for (int i = 0; i <= index; i++) {
            File tmpFile = new File("E://a/" + i + ".ts");
            if (tmpFile.exists()) {
                FileInputStream fileInputStream = new FileInputStream(tmpFile);
                while (true) {
                    len = fileInputStream.read(bytes);
                    if (len == -1) break;
                    fileOutputStream.write(bytes, 0, len);
                }
            }
        }
        fileOutputStream.close();
        fileOutputStream.close();
    }

執行代碼後,沒有報錯,查看合成後的文件,沒問題,終於搞定了!

雖然花了2個小時,可是內心仍是挺有知足感的。

以前覺得學習編程就是爲了工做,是一份職業,如今可能又有了新的見解,也是仍是一種生活方式吧。hhh

相關文章
相關標籤/搜索