使用Java和FFempeg批量转码B站缓存下来的列表视频,成MP4格式
文章目錄
- 一、需求
- 二、現有辦法
- 三、困惑
- 四、思路
- 五、動手
- 附:源代碼
一、需求
??用手機從B站上緩存了一個列表的視頻,但是它的音視頻文件是分開的,而且只能用B站APP打開。想轉成mp4格式在電腦上播放。
二、現有辦法
??單個視頻倒也好辦,到該目錄下cmd運行下面這行代碼:
ffmpeg -i video.m4s -i audio.m4s -codec copy output.mp4??馬上就可以完事。
三、困惑
??但問題在于,一個列表的視頻有二十多個,一個一個打開似乎太啰嗦,而且小破站放緩存文件的方式很陰間:
??點進一個視頻的目錄后,還要再進一個叫80的子目錄才能看到源文件。點來點去實在麻煩,而且點開六七個后退出來找下一個,面對這一大堆以九位數字命名的目錄,很可能找不到自己上一個是點了哪個文件夾。
四、思路
??于是我想,能不能用Java的File IO流來幫我們做點事。把這個過程自動化一下。
??我們已經知道如何手動處理單個音視頻合并。如果我們用Java運行bat文件,bat文件的命令包括移動到指定目錄和執行ffmpeg(上面那行代碼),這不就是相當于上面手動運行cmd的效果了嗎?
??那么如何擴展到多文件呢?只要我們能得到其他源文件的路徑,就能如法炮制,得到mp4文件。如果能把該路徑自動化寫出來,那這整個過程不就自動化了嗎?
??我們觀察到所有源文件的路徑中只有c_341981036這一部分是不同的,那我們就重點解決它。
??正好Java File類提供給了我們一個方法file.list(),可以得到當前目錄下的子文件和子文件夾,這正是我們需要的:
??然后遍歷該數組,數組元素和兩頭兩尾固定的路徑拼接一下,就得到了一個完整的路徑。至此核心問題已經解決。
五、動手
編寫相關代碼跑一個看看:
??這樣做之后,已得到了所有視頻的mp4文件,隨便打開一個文件夾看一下:
??確實已經生成了mp4文件。不過生成的mp4文件分散在各個子目錄里面,如果要去手動復制出來了話依然很繁瑣。我們不妨在生成bat文件的時候就指定一個固定的輸出目錄:
"ffmpeg -i video.m4s -i audio.m4s -codec copy D:\\Videos\\createdMp4\\output" + i +".mp4"??這樣我們就得到了一打開就是mp4文件的文件夾。理想很美好,實際上我這么做,只得到兩個mp4文件代碼就不干活了,也不報錯,就在那卡著,狀態還是運行狀態。不管他,就讓它分散在自己的子目錄里,我們換個辦法,用IO流把文件復制一份到指定目錄:
public static void copy(int i) throws IOException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream(mp4Path + "\\output.mp4"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\Videos\\createdMp4\\output" + i + ".mp4"));byte[] bytes = new byte[1024];int num = 0;while ((num = bis.read(bytes)) != -1){bos.write(bytes,0,num);}bos.close();bis.close();}
??至此,需求得到解決。
附:源代碼
package com.serein.freedom;import java.io.*;/*** 需求:批量合并m4s音視頻。每個視頻的路徑:d:\\a\\c_xxxxx(隨機數)\\80\\video.m4s d:\\a\\c_xxxxx(隨機數)\\80\\audio.m4s* 思路:1.讀取到某一條視頻的信息* 2.運行命令行工具:ffmpeg -i video.m4s -i audio.m4s -codec copy output.mp4* 3.放到循環執行,遍歷所有文件。(功能已經做完了)(做到這一步相當于是半自動洗衣機)* 4.優雅的把mp4文件取出來,放到一個文件夾中,最好文件名是有順序的。(全自動洗衣機)*/ public class Test1 {static String batPath = "";static String mp4Path = "";static String headPath = "D:\\Videos\\545686540\\";public static void main(String[] args) throws Exception {//得到緩存列表視頻直接父目錄 下所有的子目錄File file = new File(headPath);String[] list = file.list();for (int i = 0; i < list.length; i++) {batPath = headPath + list[i] + "\\80\\test.bat";mp4Path = headPath + list[i] + "\\80"; // 黑窗口最多同時打開15個 // 當視頻不長“嗖”一下就搞定時沒關系,當任務量大單個視頻長的時候,用此方法可以當甩手掌柜,自己完全不用管事。if (i % 15 == 0){Thread.sleep(2000);}createBat();run_cmd("cmd /c" + batPath);copy(i);System.out.println("正在處理第 " + i + "個視頻");}}/*** 復制文件集中到指定目錄*/public static void copy(int i) throws IOException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream(mp4Path + "\\output.mp4"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\Videos\\createdMp4\\output" + i + ".mp4"));byte[] bytes = new byte[1024];int num = 0;while ((num = bis.read(bytes)) != -1){bos.write(bytes,0,num);}bos.close();bis.close();}/*** 創建bat文件*/public static void createBat() throws IOException{//在當前目錄創建bat文件BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(batPath));//把命令寫入bat文件bufferedWriter.write("cd " + mp4Path);bufferedWriter.newLine();bufferedWriter.write("ffmpeg -i video.m4s -i audio.m4s -codec copy output.mp4");bufferedWriter.newLine();//執行完后退出黑窗口bufferedWriter.write("exit");bufferedWriter.close();}/*** 運行bat文件* 感謝_Line_老哥,提供了Java打開批處理文件的辦法。*/public static void run_cmd(String strcmd) throws IOException, InterruptedException {Runtime rt = Runtime.getRuntime();Process ps = null;//該對象的exec()方法指示Java虛擬機創建一個子進程執行指定的可執行程序// 并返回與該子進程對應的Process對象實例。ps = rt.exec(strcmd);//等待子進程完成再往下執行。ps.waitFor();//銷毀子進程ps.destroy();} }總結
以上是生活随笔為你收集整理的使用Java和FFempeg批量转码B站缓存下来的列表视频,成MP4格式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 二进制文件流转图片
- 下一篇: 装修新房该不该换电线