在Windows下編譯ffmpeg完全手冊
本文的內容幾乎全部來自于FFmpeg on Windows,但是由于國內的網絡封鎖,很難訪問這個域名下的內容,因此我一方面按照我自己的理解和實踐做了翻譯,另一方面也是為了能提供一個方便的參考方法。
注:
1. 對于compile和build這兩個詞,本文統一的使用編譯這個詞,根據上下文讀者應能區分語義上的差別。
本文的目的是提供一切與FFmpeg在Windows下的相關幫助。它最初是一個針對用MSys+MinGW系統編譯的手把手的教程,現在也增加了如何在你的項目中鏈接FFmpeg所產生的庫(C++,C#)。
我們不討論Cygwin,因為它的工作方式基本上與Unix系統相一致。 開始之前,首先要明確以下幾點:
1. 由于MSVC++并不嚴格的遵循C標準,因此FFmpeg不能使用MSVC++來編譯,而且將來也不會支持。所以整個編譯過程必須使用MSys+MinGW系統來完成。
2. 如果你選擇編譯動態鏈接庫(dll),這些庫將和其他的動態鏈接庫一樣在使用上沒什么差別。你可以使用MSVC++來鏈接這些庫進入到你的程序,只有這種情況下MSVC++是被支持的。
介紹本指南是十分冗長的。如果你已經以前曾有過編譯開源軟件的經驗,你可以嘗試讀一下這篇。它要簡短的多,只需要一些小的微調就能正常工作。
但是如果你遇到了任何問題,在你向ffmpeg的郵件列表報告錯誤時請先仔細的通讀本文,它是非常直觀的,不少地方的細節甚至可能過于詳細了。我們試圖涵蓋一切可能出錯的地方,如果你精確的遵照文中的方法,你不會在Windows環境下的FFmpeg上有任何問題。 盡你的努力去解決你所遇到的問題,絕大多數的FFmpeg開發人員不使用Windows,所以他們幫不了你什么。
預備這里的內容可能和本文沒有什么關系,但是我不想留下任何可能出錯的地方。對于絕大多數人來說,這一部分可以跳過。 你需要一個解壓的工具軟件支持“*.tar.gz”和“*.tar.bz2”文件。你將需要把這些壓縮包解壓縮到指定的目錄下。如果你已經有這樣的程序了,并且知道如何解壓到特定目錄下,請閱讀準備MSys+MinGW系統。 這里我將演示如何使用7-Zip或WinRAR來解壓縮。推薦使用7-Zip,因為它是開源且免費的。
準備MSys+MinGW系統獲取最新的MSys+MinGW系統。注意以下幾個包的版本要求:
- 不要使用2.0.4的bash,這個是有缺陷的,2.05b的bash用來編譯FFmpeg沒有問題,但是更推薦3.1版本。
- 使用msys-1.0.dll-SNAP-1.0.11-2006.04.23
- 不要使用binutils-2.15.91-20040904-1,它無法正確的鏈接。
如果你已經安裝配置完畢,那么請閱讀下一部分用SVN方式獲取FFmpeg(http://www.aurora-x.net/wiki/CompileFFmpegWindows),否則的話請依次執行下面的步驟。
用SVN方式獲取FFmpeg如果你已經知道如何獲取FFmpeg的源代碼,那么請閱讀下一部分編譯。 由于FFmpeg的源代碼存放在SVN倉庫里,你必須使用命令行程序或是圖形界面程序來訪問。我個人推薦TortoiseSVN,因為它和Windows資源管理器結合的非常棒,所以我只介紹使用TortoiseSVN的方法。 編譯
鏈接
編譯FFplay你必須事先安裝了SDL-devel。
1. 解壓該軟件包。
2. 將lib下的所有文件復制到C:/msys/mingw/lib。
3. 將include下的所有文件復制到C:/msys/mingw/include。
4. 將bin下的i386-mingw32msvc-sdl-config復制到C:/msys/mingw/bin,并重命名為sdl-config。
5. 將bin下的SDL.dll復制到C:/msys/mingw/bin。
CODE:
SDL.dll必須在ffplay.exe德PATH路徑中,程序才能啟動。在MSys環境下mingw/bin在PATH環境變量中,因此運行ffplay.exe不會有問題。但如果你想在MSys外部運行,則應SDL.dll復制到和ffplay.exe同一個目錄下。
現在你可以按照前面的方式靜態或動態重新編譯FFmpeg,在運行configure腳本后,它將正確的找到SDL和ffplay。
對第三方庫的支持
你必須完全的理解了編譯動態庫部分。
在向FFmpeg的二進制文件中添加其他的庫時,你必須首先考慮庫是以靜態還是動態的鏈接到FFmpeg中。不要把這個和FFmpeg本身是靜態/動態鏈接庫搞混,你可以把靜態的將第三方庫鏈接到FFmpeg中,但是FFmpeg的庫本身是動態加載的dll庫。
考慮這種情況:你想要更換xvidcore卻不希望重新編譯FFmpeg,那你就應該把xvidcore編譯成動態鏈接庫。
其次你要考慮的是這些第三方庫被安裝到MSys系統中的什么位置上。
對于絕大多數的是庫,如果你把它們安裝到缺省路徑,你就得向FFmpeg的configure腳本傳遞額外的參數,這樣才能在編譯的時候找到這些庫。
如果你把這些庫安裝到gcc的缺省include和lib路徑下,就不需要額外指定這些參數了。如果你希望把動態庫和靜態庫分開保存,那就不得不指定路徑。這樣的路徑被稱為你所安裝的庫的prefix。 如果你把庫安裝在了非gcc的缺省尋找路徑,你必須向FFmpeg的configure腳本傳遞這些路徑信息。
CODE:
--extra-ldflags=-L<prefix>/lib --extra-cflags=-I<prefix>/include
類似這樣:
CODE:
./configure --enable-memalign-hack --enable-mp3lame -–extra-ldflags=-L/usr/local/lib --extra-cflags=-I/usr/local/include
在MSys下gcc的缺省路徑是 /mingw另外,如果你把這些庫的dll安裝后,確保你的應用程序能在PATH環境變量中找到相應的dll。 我將展示下面這些庫的安裝:
引用原文:http://www.aurora-x.net/wiki/CompileFFmpegWindows
安裝MSys
下載如下的文件:
- MSYS-1.0.11-2004.04.30-1.exe
- msys-1.0.dll-SNAP-1.0.11-2006.04.23.tar.bz2
- bash-3.1-MSYS-1.0.11-snapshot.tar.bz2
接下來依次安裝這些文件:
MSYS-1.0.11-2004.04.30-1.exe
運行 MSYS-1.0.11-2004.04.30-1.exe.
點Yes
點Next >
如果你接受許可協議,點Yes
點Next >
選擇MSys安裝的路徑,推薦C:/msys。點Next >。
點Next >
選擇MSys在啟動菜單中位置,推薦MinGW,點Next >。
點Install。不久你將看到
輸入n后回車
再按一下回車。
把所有打勾的框去掉,然后點Finish
msys-1.0.dll-SNAP-1.0.11-2006.04.23.tar.bz2
- 將該壓縮包解壓到C:/msys/bin。
- 在Windows資源管理器中打開C:/msys/bin目錄。
- 刪除文件msys-1.0.dll(你剛才已經解壓了一個新的版本了,所以刪除舊的沒有問題)。
- 重命名new-msys-1.0.dll為msys-1.0.dll。
bash-3.1-MSYS-1.0.11-snapshot.tar.bz2
- 在本地目錄解壓該壓縮包。
- 產生一個名為bash-3.1的目錄。
- 在該目錄下有一個子目錄名為bin,其他的目錄并不關心。
- 復制bin目錄中的所有文件到C:/msys/bin。
- 提示是否要覆蓋sh.exe的時候,選擇確定。
修改 "msys.bat"
用文本編輯器打開C:/msys/msys.bat,譬如記事本等。如果你打算用MSVC++編譯你的程序(注意:是你的程序,不是FFmpeg),你需要有.lib文件才能鏈接到FFmpeg的庫。這些.lib文件可以使用微軟的工具鏈中lib命令產生。為此,你的機器上必須已經安裝了微軟的Visual Studio或是Visual C++。把下面這行加到msys.bat的最前面,把路徑替換成你機器上vcvars32.bat實際存在的路徑。
call "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/vc7/bin/vcvars32.bat"
如果你的操作系統是Windows x64,那你必須把下面的這些內容插入到:_WindowsNT標簽后面(行36):
rem Hopefully a temporary workaround for getting MSYS shell to run on x64
rem (WoW64 cmd prompt sets PROCESSOR_ARCHITECTURE to x86)
if not "x%PROCESSOR_ARCHITECTURE%" == "xAMD64" goto _NotX64
set COMSPEC=%WINDIR%/SysWOW64/cmd.exe
%COMSPEC% /c %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
goto EOF
:_NotX64
安裝MinGW
下載這些文件:
- binutils-2.17.50-20060824-1.tar.gz
- gcc-core-3.4.5-20060117-1.tar.gz
- gcc-g++-3.4.5-20060117-1.tar.gz
- mingw-runtime-3.10.tar.gz
- w32api-3.7.tar.gz (站點上找不到該文件,不過這個鏈接是有效的)
把它們全部解壓到C:/msys/mingw。
整合MinGW和MSys
復制C:/msys/etc/fstab.sample為C:/msys/etc/fstab。
用文本編輯器打開C:/msys/etc/fstab編輯。(注意:使用一個支持Unix換行風格的編輯器)
把下面這行
c:/mingw /mingw
改為
c:/msys/mingw /mingw
編譯靜態庫
如果你的系統已經按照所安裝配置,那么下面的動作將正常執行:
從啟動菜單出進入
開始->程序->MinGW->MSys->msys
一個米色背景的窗口會出現在你的眼前,這是一個運行著bash的rxvt程序
這是一個類Linux的shell并且在Windows上運行的就像是在使用一個真正的Linux shell。
- 目錄名使用正斜杠來分割,而不是Windows所使用的反斜杠(象"C:/ffmpeg"而不是"C:/ffmpeg")。
- 盤符(例如"C:/")可以從根目錄處訪問(像這樣"/C/")。
- 文件名或目錄名中的空格必須用雙引號括起(例如這樣"/C/Program Files (x86)",帶有雙引號)。
切換目錄到你之前存放FFmpeg源代碼的目錄,如果你嚴格的按照本文的示范,那么就應該輸入下面的命令來切換:
cd /C/ffmpeg
首先配置FFmpeg,選擇你所需要的部分,如果你還想安裝額外的庫(例如mp3lame,或xvid),參考后面的使用第三方庫部分。不過先確保完成了這一部分和下一部分動態庫編譯。
如果你不知道項包含什么,那么就輸入:
./configure --enable-memalign-hack
--enable-memalign-hack選項是在FFmpeg在Windows上編譯成功所必須指定的。
待配置完成后,將回到命令提示符,你應該看到如下的畫面:
如果沒有錯誤的話,你現在就可以"make" FFmpeg了,在提示符后輸入:
make
編譯的過程將持續很長時間。如果一切正常,結束后將返回提示符,并有如下的輸出畫面
程序已經編譯好了,你可以在ffmpeg的目錄下找到ffmpeg.exe這個文件。之后,你應該執行安裝步驟
make install
得到如下的輸出畫面:
這將會復制所有生成的重要文件到系統的"Program Files"目錄下。通常"Program Files"目錄是"C:/Program Files",但也有可能會不同。要了解確切的路徑,在提示符下輸入:
echo $PROGRAMFILES
然后將Windows風格的路徑名改為Linux風格的路徑名,進入該目錄,在該目錄下輸入
cd FFmpeg
很好,你現在可以方便的運行ffmpeg.exe,FFmpeg已經成功的編譯并靜態鏈接了。
當然你得知道正確的參數使用方法,要產生Windows兼容的文件請參考http://ffmpeg.mplayerhq.hu/faq.html以獲取更多的信息。
編譯動態庫
編譯動態庫和編譯靜態庫沒有什么明顯的差別,只不過你要明確地告訴configure腳本你現在將編譯動態庫。
如果還沒有MSys的話,那么現在啟動它:
開始->程序->MinGW->MSys->msys
切換到FFmpeg的源代碼目錄,在開始編譯前先清理上一次留下的中間文件是個好習慣:
make distclean
現在需要向configure腳本多傳遞兩個參數:
./configure --enable-shared --disable-static --enable-memalign-hack
后面的則不變:
make
make install
在Program Files下的FFmpeg目錄里,現在應該多了一些文件:
ffmpeg.exe
avcodec.dll
avcodec-51.dll
avcodec-51.11.0.dll
avutil.dll
avutil-49.dll
avutil-49.0.0.dll
avformat.dll
avformat-50.dll
avformat-50.5.0.dll
include/
lib/
你可能已經注意到了每個庫都有三個對應的dll,它們是同一份文件拷貝。
- SLIBNAME contains only the library name (avcodec.dll)
- SLIBNAME_WITH_MAJOR contains library name and major version number (avcodec-51.dll)
- SLIBNAME_WITH_VERSION contains library name and full version number (avcodec-51.11.0.dll)
因為MSys將ln(制作符號鏈接的程序)以cp(文件復制)來對待,所以就產生了這些相同的拷貝。
除了消耗點磁盤外不會有任何其他問題,不過對于所有使用這些庫的可執行文件來說只鏈接到SLIBNAME_WITH_MAJOR,因此你可以放心的刪除另外兩個。換句話說你只需留下avcodec-51.dll、avformat-50.dll 和 avutil-49.dll就行了。
include目錄包含了一個名為ffmpeg的子目錄,這個子目錄里存放了所有其他應用程序訪問FFmpeg庫時所需包含的頭文件。
lib目錄下有一個子目錄pkgconfig。如果你不知道它是干嗎的,那就忽略它吧。
用MSVC++鏈接DLL庫
這是絕大多數人發生誤解的地方:FFmpeg SVN本身不能用MSVC++編譯,但是如果它在MinGW下正確的被編譯,那么你可以把生成的dll用在任何支持dll的程序里。
注意你將用到的不是ffmpeg.exe,而是那些dll。
在開始往下閱讀之前,你應該確保你完成并理解了編譯靜態庫和編譯動態庫部分的內容。這不是推薦的,而是必須的。
在msys提示符下輸入:
lib
如果你看到如下的畫面,說明一切OK,注意有Microsoft (R) Library Manager字樣。
上面假定了你是在完成了編譯動態庫后在FFmpeg目錄下執行的,如果你還沒有編譯動態庫,那么依次執行如下:
cd /c/ffmpeg
make distclean
./configure --enable-shared --disable-static --enable-memalign-hack
make
make install
lib
在ffmpeg目錄下有三個子目錄名字分別為:libavutil、libavcodec 和 libavformat。在這三個目錄下都有一個SLIBNAME_WITH_MAJOR.lib這樣的文件,分別是avcodec-51.lib、avformat-50.lib 和avutil-49.lib。MSVC++從這些文件中才能知道dll的導出函數。把這三個文件拷貝到Program Files下的FFmpeg下的lib目錄。
現在通過包含include/ffmpeg下的頭文件,和使用剛才我們拷貝的那三個lib文件進行鏈接,就能夠編寫具備FFmpeg功能的應用程序了。
我提供了一個示例:用MSVC++創建output_example.exe
用MSvc++創建output_example.ex
這是絕大多數人發生誤解的地方:FFmpeg SVN本身不能用MSVC++編譯,但是如果它在MinGW下正確的被編譯,那么你可以把生成的dll用在任何支持dll的程序里。
注意你將用到的不是ffmpeg.exe,而是那些dll。
在開始往下閱讀之前,你應該確保你完成并理解了編譯靜態庫和編譯動態庫部分的內容。這不是推薦的,而是必須的。
在msys提示符下輸入:
lib
如果你看到如下的畫面,說明一切OK,注意有Microsoft (R) Library Manager字樣。
上面假定了你是在完成了編譯動態庫后在FFmpeg目錄下執行的,如果你還沒有編譯動態庫,那么依次執行如下:
cd /c/ffmpeg
make distclean
./configure --enable-shared --disable-static --enable-memalign-hack
make
make install
lib
在ffmpeg目錄下有三個子目錄名字分別為:libavutil、libavcodec 和 libavformat。在這三個目錄下都有一個SLIBNAME_WITH_MAJOR.lib這樣的文件,分別是avcodec-51.lib、avformat-50.lib 和avutil-49.lib。MSVC++從這些文件中才能知道dll的導出函數。把這三個文件拷貝到Program Files下的FFmpeg下的lib目錄。
現在通過包含include/ffmpeg下的頭文件,和使用剛才我們拷貝的那三個lib文件進行鏈接,就能夠編寫具備FFmpeg功能的應用程序了。
我提供了一個示例:用MSVC++創建output_example.exe
用MSvc++創建output_example.exe
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成