下面專門總結一下技術上的經驗和收穫,主要是關於自己使用FFmpeg遇到的實際問題和解決方案,同時會推薦相關網上的資料。
一、ffmpeg支援格式問題
ffmpeg.exe能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等),對ffmpeg.exe無法解析的檔案格式(wmv9,rm,rmvb等),可採用Mencoder來轉換。
二、ffmpeg參數問題
例子:ffmpeg -y -i "1.avi" -title "Test" -vcodec xvid -s 368x208 -r 29.97 -b 1500 -acodec aac -ac 2 -ar 24000 -ab 128 -vol 200 -f psp -muxvb 768 "1.***"
解釋:以上命令可以在Dos命令列中輸入,也可以建立到批次檔中運行。不過,前提是:要在ffmpeg所在的目錄中執行(轉換君所在目錄下面的cores子目錄)。
參數:
-y(覆蓋輸出檔案,即如果1.***檔案已經存在的話,不經提示就覆蓋掉了)
-i "1.avi"(輸入檔案是和ffmpeg在同一目錄下的1.avi檔案,可以自己加路徑,改名字)
-title "Test"(在PSP中顯示的影片的標題)
-vcodec xvid(使用XVID編碼壓縮視頻,不能改的)
-s 368x208(輸出的解析度為368x208,注意片源一定要是16:9的不然會變形)
-r 29.97(幀數,一般就用這個吧)
-b 1500(視頻資料流量,用-b xxxx的指令則使用固定碼率,數字隨便改,1500以上沒效果;還可以用動態碼率如:-qscale 4和-qscale 6,4的品質比6高)
-acodec aac(音頻編碼用AAC)
-ac 2(聲道數1或2)
-ar 24000(聲音的採樣頻率,好像PSP只能支援24000Hz)
-ab 128(音頻資料流量,一般選擇32、64、96、128)
-vol 200(200%的音量,自己改)
-f psp(輸出psp專用格式)
-muxvb 768(好像是給PSP機器識別的碼率,一般選擇384、512和768,我改成1500,PSP就說檔案損壞了)
"1.***"(輸出檔案名,也可以加路徑改檔案名稱)
轉載自:http://g006.javaeye.com/blog/347152
三、ffmpeg擷取輸出資訊 (問題解決:http://www.ffmpeg.com.cn/index.php/.NET_2.0(C )
轉載: .NET 2.0 調用FFMPEG,並非同步讀取輸出資訊的代碼...
public void ConvertVideo() { Process p = new Process();//建立外部調用線程 p.StartInfo.FileName = @"c:\ffmpeg.exe";//要調用外部程式的絕對路徑 p.StartInfo.Arguments = "-i XXXXXXXXXXXXXX";//參數(這裡就是FFMPEG的參數了) p.StartInfo.UseShellExecute = false;//不使用作業系統外殼程式啟動線程(一定為FALSE,詳細的請看MSDN) p.StartInfo.RedirectStandardError = true;//把外部程式錯誤輸出寫到StandardError流中(這個一定要注意,FFMPEG的所有輸出資訊,都為錯誤輸出資料流,
用StandardOutput是捕獲不到任何訊息的...這是我耗費了2個多月得出來的經驗...mencoder就是用standardOutput來捕獲的)
p.StartInfo.CreateNoWindow = false;//不建立進程視窗 p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程式(這裡是FFMPEG)輸出資料流時候產生的事件,這裡是把流的處理過程轉移到下面的方法中,詳細請查閱MSDN p.Start();//啟動線程 p.BeginErrorReadLine();//開始非同步讀取 p.WaitForExit();//阻塞等待進程結束 p.Close();//關閉進程 p.Dispose();//釋放資源 } private void Output(object sendProcess, DataReceivedEventArgs output) { if (!String.IsNullOrEmpty(output.Data)) { //處理方法... } }
BeginErrorReadLine 可同步或非同步讀取 StandardError 流。Read、ReadLine 和 ReadToEnd 等方法對進程的錯誤輸出資料流執行同步讀取操作。
這些同步讀取操作只有在關聯的 Process寫入其 StandardError 流或關閉該流後才能完成。相反,BeginErrorReadLine
在 StandardError 流上開始非同步讀取操作。此方法會為流輸出啟用指定的事件處理常式並立即返回到調用方,這樣當流輸出
被定向到該事件處理常式時,調用方還可以執行其他動作。 按照這些步驟對 Process 的 StandardError 執行非同步讀取操作:
- 將 UseShellExecute 設定為 false。
- 將 RedirectStandardError 設定為 true。
- 向 ErrorDataReceived 事件添加事件處理常式。事件處理常式必須與 System.Diagnostics.DataReceivedEventHandler 委託簽名相匹配。
- 啟動 Process。
- 調用 Process 的 BeginErrorReadLine。此調用將啟動 StandardError 上的非同步讀取操作。
- 啟動非同步讀取操作時,關聯的 Process 每向其 StandardError 流寫入一行文本時,都將調用該事件處理常式。
- 可通過調用 CancelErrorRead取消非同步讀取操作。可通過調用方或事件處理常式取消讀取操作。取消之後,可以再次調用 BeginErrorReadLine 繼續進行非同步讀取操作。
ErrorDataReceived 事件指示關聯的進程已寫入其重新導向 StandardError 流中。該事件僅在對 StandardError 進行非同步讀取操作期間發生。
若要啟動非同步讀取操作,必須重新導向 Process 的 StandardError 流,向 ErrorDataReceived 事件添加事件處理常式,
並調用 BeginErrorReadLine。之後,每當該進程向重新導向 StandardError 流中寫入一行時,ErrorDataReceived 事件
都會發出訊號,直到該進程退出或調用 CancelErrorRead為止。
四、推薦網址
JAVA執行個體:http://www.w3china.org/blog/more.asp?name=lhwork&id=22488
ffmpeg中國:http://www.ffmpeg.com.cn/
ffmpeg:http://ffmpeg.org/
官方文檔:http://ffmpeg.org/ffmpeg-doc.html
參數說明:http://www.cnblogs.com/94cool/archive/2009/08/28/1555830.html
http://www.chinaz.com/Design/Video/0223CG32009.html