其實上面網站要支援 H.264 根本就不是難事,去年 (2007) 底 Adobe 釋出了 Flash Player 9.0.115.0 修正版本,這個版本就導入了 H.264 支援。換言之關鍵的是你瀏覽器上面的 Flash 元件,所以才聽說有人在ニコニコ動画 SP1 看 H.264 影片需要更新吧?(我個人是去年看到有網站在討論重大安全性更新就手動更新了) 實際試驗手上能用的 Mediaplayer.swf 看看,這個 SWF 檔使用了媒體播放元件,可以線上播放 FLV 檔案,塞給它 MP4 檔吃,一樣可行,證實了我的想法。於是需要調整適應的地方不算很多,可以快速享受 H.264 的高畫質,只不過電腦配備 (CPU、GPU) 不夠好的朋友們可得注意了。
所以要玩的話就得要靠一些工具幫助我們編碼,以前的 FLV1 可以用懶人工具 Riva FLV Encoder 快速編碼,FLV4 時代也有攜帶動畫變換君這種 N 合一的東西可以幫助我們,H.264 雖然也有一些工具 (轉給 PSP 或 iPod 看的),不過我比較喜歡自己找工具來搭配,網路上看到有人用 AviUtil 在轉 (Ref: x264(mp4) encode教學 (採用ニコニコ動画及AviUtl為例)),各位不妨做個參考。
我選擇土砲法,才能充分理解壓縮步驟,準備以下工具:
以上就是主要的程式,流程為:
來源檔案 → Lanczos4Resize (AviSynth) → H.264/AVC (x264) *視訊
└→ WAV (FFmpeg) → AAC (Nero AAC Codec) *音訊
最後再 H.264/AVC + AAC → MP4 (MP4Box),大功告成,其實也不難嘛。
自己為了方便,寫了一個批次檔來負責這一大堆動作,全面自動化。隨著不斷的測試和調整,批次檔的也改的越來越人性化,可以直接拖檔案給它處理,只不過又使用了其他東西 (比如說 Horst Schaeffer 的 Wfolder,選取目標資料夾用輔助程式) 和多了一些判斷,諸位可以無視,畢竟那不是重點。
@ECHO OFF
SETLOCAL
SET BASEPATH=%~dp0
SET VBITRATE=500
REM SET VRES=512, 288
SET VRES=512, 384
SET /a ABITRATE=64 * 1000
SET ACOMPRESSION=-he
SET VCOMPRESSION=qualityEX
REM fast, quality, qualityEX
REM Set destination directory
"%BASEPATH%Wfolder2" "SET DESTDIR=" . "Choose a destination directory" /noquote /backslash > "%TEMP%\result_destfile.bat"
CALL "%TEMP%\result_destfile"
IF NOT %ERRORLEVEL% == 0 GOTO :EOF
ECHO Creating avs script...
IF /I %~x1 == .AVI GOTO TYPE_AVI
IF /I %~x1 == .DIVX GOTO TYPE_AVI
GOTO TYPE_OTHER
:TYPE_AVI
ECHO AviSource("%~1", false).Lanczos4Resize(%VRES%) > "%TEMP%\result_frame.avs"
GOTO IF2
:TYPE_OTHER
ECHO DirectShowSource("%~1", convertfps=true, audio=false).Lanczos4Resize(%VRES%) > "%TEMP%\result_frame.avs"
:IF2
ECHO Encoding video...
IF NOT %VCOMPRESSION% == fast GOTO quality
REM Fast Compression
ECHO Preset: Fast
"%BASEPATH%x264" --threads 2 --progress --pass 1 --bitrate %VBITRATE% --stats "%TEMP%\result_x264.stats" --subme 6 --ref 5 --filter 0:0 --keyint 250 --min-keyint 25 --direct temporal --sar 1:1 --bframes 2 --b-pyramid --weightb --8x8dct --ipratio 1.40 --pbratio 1.30 --qcomp 0.8 --analyse p8x8,i4x4 -o NUL "%TEMP%\result_frame.avs"
"%BASEPATH%x264" --threads 2 --progress --pass 2 --bitrate %VBITRATE% --stats "%TEMP%\result_x264.stats" --subme 6 --ref 5 --filter 0:0 --keyint 250 --min-keyint 25 --direct temporal --sar 1:1 --bframes 2 --b-pyramid --weightb --8x8dct --ipratio 1.40 --pbratio 1.30 --qcomp 0.8 --analyse b8x8,p8x8,p4x4,i4x4 -o "%TEMP%\result_video.mp4" "%TEMP%\result_frame.avs"
GOTO encodeaudio
:quality
IF %VCOMPRESSION% == quality ECHO Preset: Quality
IF %VCOMPRESSION% == qualityEX ECHO Preset: Quality Extreme
REM Quality Compression
"%BASEPATH%x264" --bframes 16 --ref 5 --keyint 250 --min-keyint 25 --b-pyramid --qcomp 1.0 --subme 7 --analyse all --weightb --8x8dct --trellis 2 --me umh --mixed-refs --direct auto --threads 2 --thread-input --no-psnr --no-ssim --no-fast-pskip --no-dct-decimate --progress --pass 1 --bitrate %VBITRATE% --stats "%TEMP%\result_x264.stats" --sar 1:1 --ipratio 1.40 --pbratio 1.30 -o NUL "%TEMP%\result_frame.avs"
IF NOT %VCOMPRESSION% == qualityEX GOTO finalpass
REM Quality Extreme Compression
"%BASEPATH%x264" --bframes 16 --ref 5 --keyint 250 --min-keyint 25 --b-pyramid --qcomp 1.0 --subme 7 --analyse all --weightb --8x8dct --trellis 2 --me umh --mixed-refs --direct auto --threads 2 --thread-input --no-psnr --no-ssim --no-fast-pskip --no-dct-decimate --progress --pass 3 --bitrate %VBITRATE% --stats "%TEMP%\result_x264.stats" --sar 1:1 --ipratio 1.40 --pbratio 1.30 -o NUL "%TEMP%\result_frame.avs"
:finalpass
"%BASEPATH%x264" --bframes 16 --ref 5 --keyint 250 --min-keyint 25 --b-pyramid --qcomp 1.0 --subme 7 --analyse all --weightb --8x8dct --trellis 2 --me umh --mixed-refs --direct auto --threads 2 --thread-input --no-psnr --no-ssim --no-fast-pskip --no-dct-decimate --progress --pass 2 --bitrate %VBITRATE% --stats "%TEMP%\result_x264.stats" --sar 1:1 --ipratio 1.40 --pbratio 1.30 -o "%TEMP%\result_video.mp4" "%TEMP%\result_frame.avs"
:encodeaudio
ECHO Encoding audio...
"%BASEPATH%ffmpeg" -y -i %1 -ar 48000 -ac 2 "%TEMP%\result_audio.wav"
"%BASEPATH%neroAacEnc" -br %ABITRATE% %ACOMPRESSION% -2pass -if "%TEMP%\result_audio.wav" -of "%TEMP%\result_audio.m4a"
ECHO Merging mp4...
"%BASEPATH%MP4Box" -add "%TEMP%\result_video.mp4#video" -add "%TEMP%\result_audio.m4a#audio" -new "%DESTDIR%merged.mp4"
ECHO Job finished.
PAUSE
del "%TEMP%\result_*.*" /Q
我想批次檔用了許多技巧,看不懂也是有可能的,不過還是抓幾個重點來介紹。首先是使用 AviSynth 這一部分,我使用 ECHO 動態了生成 avs 檔案,裡面指定了 Lanczos4Resize 來作畫面縮小的動作。
再來是重頭戲 x264,可以看到指令列跟了長長一串,這就是可以學習到的地方。我不敢保證上面列的參數是最完美的,但我也參考了很多地方如漫遊酷論壇、Doom9等地方的許多討論串,得出每個參數的大致功用,依照推薦所設定的。關鍵還是在「--bitrate %VBITRATE%」這邊,指定視訊流量。另外「--pass」是開啟 Multipass 的選項 (二次編碼),聽說 3pass 還是有一點用,所以我也用上了。
接著是音訊部分,使用 FFmpeg 將來源檔 (注意我沒用 AviSynth 處理)的音訊解成 WAV 後,再給 neroAacEnc 吃。
最後就使用 MP4Box 加入兩個檔案的視訊跟音訊,建立新檔案 merged.mp4,這個檔案就是辛苦的結晶啦,用 VLC、Media Player Classic 或是 KMPlayer 都可以看吧,如果有安裝 ffdshow, MP4Splitter.ax, CoreAVC 等想必會更好,觀看部分我就不特別著墨,反正大家都會裝整合包所以應該都可以看吧。
---
2008/12/12 修改: 更新 Nero AAC Codec 下載位置跟 x264 參數,新版取消 --bime 跟 --b-rdo
在 http://oss.netfarm.it/mplayer-win32.php 下載的ffmpeg好像沒這個問題呢…
回覆刪除補充一下,現在的 x264 Encoder 已經取消 --b-rdo 和 --bime 這兩個參數了。
回覆刪除Nero AAC Encoder 也已經沒有SSE特別編譯版。