最近打算把我電腦上的一些視頻文件轉換成x264格式的mp4,從而實現和平板&電腦間的共享。由於WinMEncoder對高清視頻有些力不從心,便用MeGui實現視頻轉換。MeGui本身還算比較容易上手,但是它有一個問題,那就是無法像WinMencoder那樣根據設置的規則實現批量轉換,需要對每一個文件進行設置,如果文件較多便會覺得很累,容易出錯。
MeGui本身就是一個Gui,具體轉換的工作還是靠外部程序實現的,它主要是生成外部命令行所需要的參數。而其中參數主要有兩種——avs腳本和命令行參數。對於那些轉換視頻的老手來說,自然可以手動編寫avs腳本,並手動配置相應命令行參數,寫一個批處理文件即可實現批量轉換,但對於我這種門外漢來說幾乎是不可能任務。我的實現方案是:
- 用MeGui轉換一個視頻文件,截取其生成的avs腳本和命令行參數,並轉換為批處理文件,使之可以脫離MeGui批量執行。
- 修改其avs腳本和批處理文件中的輸入和輸出文件,使之可以批量應用於其它文件。
PS:本文只是給了一個通用的方案,使用該方案也需要較強的動手能力和一定的編程經驗。由於轉換任務配置有很大差異,我這里並沒有給出一個可以直接使用的傻瓜程序,請不要留言索求程序,具體根據自己的配置參數來實現。
由於視頻文件較大,這里我用網上下的一個flv短片演示這一過程。
轉換完后,可以通過Job項查看該轉換過程結果了哪幾步,
這里由於我是采用的二次編碼,因此有兩次視頻轉換,其總共分四步:
- 分離出音頻文件,輸出"3.m4a"
- 第一次視頻轉換
- 第二次視頻轉換,輸出視頻文件"3.264"
- 將視頻和音頻混合起來,輸出mp4文件"3-混合文件.mp4"
Job項寫得比較簡單,從中我們看不出具體的調用了那些外部程序,參數是啥,詳細信息需要進一步查看日志:
下面我們來一一分析這些過程,並將其轉換為命令行。
第一步:分離出音頻文件
其中高亮部分表示的是通過R:\1\MeGUI\tools\eac3to\neroAacEnc.exe -ignorelength -q 0.5 -if - -of "R:\2\3.m4a"命令,分離出"3.m4a"音頻文件。
NeroAAC的參數說明可以參考這個地址:http://wiki.hydrogenaudio.org/index.php?title=NeroAAC。 它的輸入參數是一個wav格式文件,當輸入為-的時候表示stdin中獲取。從這里的參數來看是通過stdin中獲取wav數據的。從日志中我們無法看出是如何將視頻格式轉換為wav並輸出到stdin中共neroaac調用的,但能發現圖中所示的一個腳本:
LoadPlugin("R:\1\MeGUI\tools\ffms\ffms2.dll")
FFAudioSource("R:\2\3.flv")
Normalize()
return last
這個腳本的功能就是將音頻信息轉換為wav格式,如何執行的這個腳本,在日志中並沒有找到相應的外掛命令行,可能是MeGUI自己的內部實現,不過可以通過dshow2wav.exe(在http://sourceforge.net/projects/direct264/下載)來實現,它的命令格式如下:dshow2wav.exe "audio.avs"(PS:不要單獨在控制台執行這個命令,大量非法輸出會把控制台掛死)其中它的輸入參數"audio.avs"就是我將前面的腳本保存成的avs文件。
綜上所述,最終的組合命令如下:
dshow2wav.exe "audio.avs" | R:\1\MeGUI\tools\eac3to\neroAacEnc.exe -ignorelength -q 0.5 -if - -of "R:\2\3.m4a"
執行完這個命令行,就可以獲取音頻文件"3.m4a"了。
注: 有時dshow2wav.exe無法正確解析出wav文件來,這時可以試一下wavi這個程序,不過它不支持輸出到stdout,需要中間有個臨時wav文件。不過這個程序是開源的,有空的話我改一下這個程序。
第二步:第一次視頻轉換
從它的日志類型-任務命令行(前面的那個轉換音頻的日志類型是CommandLine,表示是一個組合的命令行),這一步命令行化就比較簡單了,直接將它的命令行執行輸出即可:
"R:\1\MeGUI\tools\x264\avs4x264mod.exe" --tune animation --pass 1 --bitrate 1000 --stats "R:\2\3.stats" --keyint 150 --sar 1:1 --output NUL "R:\2\3.avs"
這里有一個avs腳本作為輸入參數,它是MeGUI自動生成的,內容如下:
DirectShowSource("R:\2\3.flv", fps=15.000, audio=false, convertfps=true).AssumeFPS(15.000)
#deinterlace
#crop
#resize
#denoise
ConvertToYV12()
第三步:第二次視頻轉換
這一步也是直接執行命令行:
"R:\1\MeGUI\tools\x264\avs4x264mod.exe" --tune animation --pass 2 --bitrate 1000 --stats "R:\2\3.stats" --keyint 150 --sar 1:1 --output "R:\2\3.264" "R:\2\3.avs"
這個里面的輸入腳本和前面一樣,就不多介紹了。執行完這一步后,就生成了視頻文件"3.avs"。
第四步:混流
這一步也是直接執行命令行:
"R:\1\MeGUI\tools\mp4box\mp4box.exe" -add "R:\2\3.264:fps=15" -add "R:\2\3.m4a#trackID=1" -tmp "R:\\2" -new "R:\2\3-混合文件.mp4"
執行這個命令行后,就生成了我們要的mp4文件了。
綜合:
最后把這四步綜合起來,形成一個批處理文件:
R:\1\direct264\dshow2wav.exe "audio.avs" | R:\1\MeGUI\tools\eac3to\neroAacEnc.exe -ignorelength -q 0.5 -if - -of "R:\2\3.m4a"
"R:\1\MeGUI\tools\x264\avs4x264mod.exe" --tune animation --pass 1 --bitrate 1000 --stats "R:\2\3.stats" --keyint 150 --sar 1:1 --output NUL "R:\2\3.avs"
"R:\1\MeGUI\tools\x264\avs4x264mod.exe" --tune animation --pass 2 --bitrate 1000 --stats "R:\2\3.stats" --keyint 150 --sar 1:1 --output "R:\2\3.264" "R:\2\3.avs"
"R:\1\MeGUI\tools\mp4box\mp4box.exe" -add "R:\2\3.264:fps=15" -add "R:\2\3.m4a#trackID=1" -tmp "R:\\2" -new "R:\2\3-混合文件.mp4"
del *.stats
del *.m4a
del *.ffindex
del *.264
del *.mbtree
PS: 由於刪除臨時文件的命令行在日志中找不到,這里是我根據我的命令的輸出加入的,根據命令不同,輸出的臨時文件也會有所不同。
其中用到了兩個輸入腳本audio.avs和3.avs,這些都是MeGui創建的:
Auido.avs
LoadPlugin("R:\1\MeGUI\tools\ffms\ffms2.dll")
FFAudioSource("R:\2\3.flv")
Normalize()
return last
3.avs
DirectShowSource("R:\2\3.flv", fps=15.000, audio=false, convertfps=true).AssumeFPS(15.000)
#deinterlace
#crop
#resize
#denoise
ConvertToYV12()
到了這一步后,我們已經成功實現純命令行轉換視頻了,直接執行這個批處理文件就可以獲取轉換后的mp4文件了。下一步就是把這些命令行應用到其它視頻文件中,以實現批量轉換的目的。
我的批量轉換方式實現比較簡單:寫了一個程序導入所有待轉換的文件,然后每次轉換前直接把輸入和輸出文件(上面腳本中標紅的部分)的命令行在bat和avs腳本中替換,調用bat文件獲取轉換輸出。
由於轉換任務配置有很大差異,所以我這里的分析過程還是手動完成的,因此並不能給出一個通用的批量轉換。實際上,如果能實現一個智能分析日志的的功能,把我這里的分析過程自動化,是可以實現直接根據MeGui日志自動批量轉換的。我最開始本打算實現一下的,后來發現如果要弄一個比較完善的版本還有些工作量,就沒弄了,等閑下來時再看看。