導讀 | ffmpeg 是音頻處理方面非常強大非常有名的開源項目了,然而如 雷神 所說,“FFMPEG 難度比較大,卻沒有一個循序漸進,由簡單到復雜的教程。現在網上的有關FFMPEG的教程多半難度比較大,不太適合剛接觸 FFMPEG 的人學習;而且很多的例子程序編譯通不過,極大地打消了學習的積極性”,對於平時只習慣在 Windows 下開發的初學者來說,從零開始了解相關依賴,搭建起項目並調試 ffmpeg 並不是件容易的事,好在另一個非官方的 開源項目,提供了一整套 Windows 下,用 VS 來調試 ffmpeg 的解決方案——Shift Media Project。 本文使用最新版本的 ShiftMediaProject 的代碼(20191015),展示在Windows10 下使用 VS2015 下載代碼並成功編譯的過程。在另一篇本文參考的 博文 中亦介紹了整個過程,不過由於是 20180307 寫的,有些新的內容沒有覆蓋到,這里可當做是對其進行補充和拓展。同時也作為個人筆記分享出來,希望能幫助到更多剛好有需求的人。 |
目錄 |
本文測試使用環境:
操作系統:Windows 10
編譯使用開發環境:Visual Studio 2015
下載源代碼工具:git 客戶端
(ffmpeg 的編譯要求編譯器對 C99 標准的支持。VS 中默認只有 VS2013 以及更新的版本對 C99 標准提供了支持,所以只能使用 VS2013 之后的版本,如果要使用更前版本,那么就得自己在 VS 先添加 C99 標准的支持)
項目地址:https://github.com/ShiftMediaProject/FFmpeg
需要注意的是,克隆到本地的目標項目目錄 至少需要有2層,因為期望的項目的結構是這樣子的:
- msvc (OutputDir) (該項目默認的 VS 編譯輸出的目錄) - source (這個是需要的上一級目錄,待會下載的依賴項目有很多,十幾二十來個依賴項目都會下載到這里) - FFmpeg (這個是 clone 到本地的項目目錄) - ..Any other libraries source code.. (其他的十幾二十個依賴的項目)
准備好文件夾后,比如這里上面的 "source" 文件夾,在這個文件夾下,克隆代碼下來
git clone https://github.com/ShiftMediaProject/FFmpeg.git
所有的 VS 項目相關的文件,都在 SMP 文件夾下,仔細查看該目錄下的 readme 文件內容,按里面的說明進行。

This is a small list of steps in order to build FFmpeg into a msvc DLL and lib file.
The projects contain Release and Debug builds for static lib files (Debug/Release)
as well as dynamic shared dll files (DebugDLL/ReleaseDLL).
Choose whichever project configuration meets your requirements.
Note: FFmpeg requires C99 support in order to compile. Only Visual Studio 2013 or newer supports required C99 functionality and so any
older version is not supported. Visual Studio 2013 or newer is required. If using an older unsupported version of Visual Studio the
Intel compiler can be used to add in the required C99 capability.
*** Using the Default Supplied Projects ***
The supplied project files are created using default configuration options as used by the ShiftMediaProject.
These projects use Visual Studio 2013/2015 and require certain additional dependencies to be built and available at compile time.
Required project dependencies include:
bzlib
iconv
zlib
lzma
libxml2
sdl2
libmp3lame
libvorbis
libspeex
libopus
libilbc
libtheora
libx264
libx265
libxvid
libvpx
libgme
libmodplug
libsoxr
libfreetype
fontconfig
libfribidi
libass
gnutls
libgcrypt
libssh
libcdio
libcdio_paranoia
libbluray
opengl
ffnvcodec
libmfx
Most of the above dependencies are supplied as part of the ShiftMediaProject repositories.
These repositories can be manually downloaded or automatically cloned using the supplied
project_get_dependencies.bat file. This file can also be used to check for and download
any dependency updates at any point after the first clone of the library.
Some of these dependency projects have additional requirements to those listed here. See the corresponding readme for each of the projects for further details.
Many of the possible FFmpeg dependencies (and there dependencies) are available in the ShiftMediaProject repositories.
However the following is a list of extra dependency options that require external downloads:
1) opengl (requires glext)
a) Download glext.h and wglext.h from opengl.org.
b) Save the header files into "OutputDir/include/gl/*".
c) Download khrplatform.h from khronos.org
d) Save the header file into "OutputDir/include/KHR/*".
2) ffnvcodec (requires nv-codec-headers)
a) Download the nv-codec-headers repository from https://github.com/FFmpeg/nv-codec-headers
b) Save the contents of the nv-codec-headers repositories "include" folder into "OutputDir/include/*".
3) AMF (requires Advanced Media Framework (AMF) SDK headers)
a) Download the AMF repository from https://github.com/GPUOpen-LibrariesAndSDKs/AMF
b) Save the contents of the AMF repositories "amf/public/include" into "OutputDir/include/AMF/*".
*OutputDir is the "Output Directory" specified in the project properties.
The default value of OutputDir is "..\..\msvc" relative to the FFmpeg source directory. An example of the expected
directory structure is:
- msvc (OutputDir)
-> source
- FFmpeg
- ..Any other libraries source code..
Any dependencies supplied by ShiftMediaProject should be downloaded next to the FFmpeg folder as they will use the same OutputDir
location. Projects to build each dependency can be found in the respective repository ./SMP directories or all together using
the all inclusive ffmpeg_deps.sln.
Only dependencies built from supplied ShiftMediaProject repositories are tested and supported. Using compiled dependencies from
other sources may result in version mismatch or other issues. Although these external sources generally work fine any problems associated
with them are not covered by ShiftMediaProject and so they should be used with discretion.
*** Building with ASM ***
In order to build FFmpeg using msvc you must first download and install NASM.
NASM is required to compile all assembly files.
1) Visual Studio NASM integration can be downloaded from https://github.com/ShiftMediaProject/VSNASM/releases/latest
2) Once downloaded simply follow the install instructions included in the download.
按照 readme 說明,接下來:
ShiftMediaProject 使用默認的配置生成了一些項目文件,這些文件可以使用 VS 打開,同時需要依賴特定的額外的項目,才能進一步編譯。
依賴的項目包括:
bzlib iconv zlib lzma libxml2 sdl2 libmp3lame libvorbis libspeex libopus
libilbc libtheora libx264 libx265 libxvid libvpx libgme libmodplug libsoxr libfreetype
fontconfig libfribidi libass gnutls libgcrypt libssh libcdio libcdio_paranoia
libbluray opengl ffnvcodec libmfx
上面大部分的依賴項目都被放在了 ShiftMediaProject 用戶的 git 倉庫 了,這些都可以手動下載,當然強烈建議還是使用 FFmpeg\SMP\project_get_dependencies.bat 批處理自動clone下載,這個腳本不僅僅可在第一次用於clone項目(及其本身依賴的其他git項目),還可以在后面任何時候執行,用來自動更新各自最新的版本
所以,雙擊執行 “project_get_dependencies.bat” 批處理,等待一段 較長的時間 的下載,即可完成大部分依賴庫的下載
大部分需要的依賴(及其自身的依賴)都可以在 ShiftMediaProject 下的倉庫找到,不過編譯還需要下載其他外部文件。
下面列出了需要額外下載的文件,以及對應需要下載到的目標目錄
1) opengl (requires glext)
a) Download glext.h and wglext.h from opengl.org.
b) Save the header files into "OutputDir/include/gl/*".
c) Download khrplatform.h from khronos.org
d) Save the header file into "OutputDir/include/KHR/*".
2) ffnvcodec (requires nv-codec-headers)
a) Download the nv-codec-headers repository from https://github.com/FFmpeg/nv-codec-headers
b) Save the contents of the nv-codec-headers repositories "include" folder into "OutputDir/include/*".
3) AMF (requires Advanced Media Framework (AMF) SDK headers)
a) Download the AMF repository from https://github.com/GPUOpen-LibrariesAndSDKs/AMF
b) Save the contents of the AMF repositories "amf/public/include" into "OutputDir/include/AMF/*".
1、下載 opengl 的 glext.h 和 wglext.h 到 " OutputDir/include/gl/* " (下載點 這里)
2、下載 opengl 的 khrplatform.h 到 " OutputDir/include/KHR/* " (下載點 這里)
3、下載 nv-codec-headers 項目的 "include" 文件夾下的內容到 " OutputDir/include/* " (git 項目點 這里)
4、下載 AMF 項目的 "amf/public/include" 文件夾下的內容到 " OutputDir/include/AMF/* " (git 項目點 這里)
OutputDir 是在項目屬性里指定了的 “輸出目錄 ”
默認的項目輸出目錄是相對於 FFmpeg 源代碼目錄的 “..\..\msvc”
一個預期的目錄結構如下,(這個也是前面 2、下載源代碼 步驟中提到的文件結構)
- msvc (OutputDir) (該項目默認的 VS 編譯輸出的目錄)
- source (這個是需要的上一級目錄,待會下載的依賴項目有很多,十幾二十來個依賴項目都會下載到這里) - FFmpeg (這個是 clone 到本地的項目目錄) - ..Any other libraries source code.. (其他的十幾二十個依賴的項目)
所以,如上創建 msvc 目錄,按步驟創建文件夾並下載對應文件(想偷懶的可以直接點擊我下載后打包的 msvc.zip )
下載完了項目依賴的其他 git 項目 和 頭文件之后,就可以使用 VS 打開 FFmpeg\SMP\ffmpeg_deps.sln 項目文件了
初次打開項目,如果缺少 Win10 SDK 相關組件,會有類似下圖提示
點擊 “安裝” ,關閉VS后,等待其安裝完畢。
實際上,如上 “安裝的缺少的功能” 后,重新用 VS 打開項目,還是會提示一些項目 (不可用) 或 (加載失敗),還是無法 “重新加載項目”
因為使用 msvc 來編譯 ffmpeg 還需要 安裝 NASM 才能編譯所有的匯編文件。ShiftMediaProject 為編譯 ffmpeg 提供的自定義構建項【nasm / yasm】默認 VS是沒有支持的,所以最后一步就是為 VS 添加自定構建項
ShiftMediaProject 提供了自動下載和安裝 NASM 的安裝腳本,下載地址為: https://github.com/ShiftMediaProject/VSNASM/releases/latest
下載完后,注意最好 不要 直接運行 install_script.bat
最好是先 以管理員身份,在預設好 VS 相關變量的腳本環境中 (開發者命令行 / dev command line),運行該 install_script.bat 腳本
若執行成功,沒有任何失敗提示,便算是安裝完成了
如果直接運行,由於執行腳本環境沒有先預設 VCINSTALLDIR 等變量,可能會出現如下錯誤(一開始我直接運行遇到的,后來經 BesLyric 項目 的一個合作開發的伙伴提醒才意識到先運行VS開發者命令行)。
這一步出現的2個錯誤是:
(1)無法下載 vswhere.exe 到當前目錄
(2) 在構建 .......\\VC\bin\amd64\vcvars64.bat 文件的路徑時, 構建出一個不存在的路徑,導致腳本嘗試執行 vcvars64.bat 時出錯
第一個錯誤還好解決,直接手動復制鏈接到瀏覽器下載 https://github.com/Microsoft/vswhere/releases/download/2.5.9/vswhere.exe ,然后放在 install_script.bat 同一目錄即可
第二個錯誤就需要手動改 install_script.bat 文件了
經過調試發現,在如下 批處理中:
REM Call the required vcvars file in order to setup up build locations if "%MSVC_VER%"=="16" ( set VCVARS=%VSINSTANCEDIR%\VC\Auxiliary\Build\vcvars%SYSARCH%.bat ) else if "%MSVC_VER%"=="15" ( set VCVARS=%VSINSTANCEDIR%\VC\Auxiliary\Build\vcvars%SYSARCH%.bat ) else if "%MSVC_VER%"=="14" ( set VCVARS=%VSINSTANCEDIR%\VC\bin%MSVCVARSDIR%\vcvars%SYSARCH%.bat ) else if "%MSVC_VER%"=="12" ( set VCVARS=%VSINSTANCEDIR%\VC\bin%MSVCVARSDIR%\vcvars%SYSARCH%.bat ) else ( echo Error: Invalid MSVC version! goto Terminate )
構建的變量 %VCVARS% 沒有達到預期值,通過打印相關變量(使用 echo 指令),打印出該變量的結果是:
而經過查找,我VS環境中的 vcvars64.bat 實際路徑為: "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat", 可能是之前安裝VS沒有按默認路徑安裝導致(?)
於是針對我個人的環境情況,根據自己的 vcvars64.bat 腳本的位置,根據我只需要成功為 VS2015 安裝這個自定義構建項的需要,我做了如下修改:
//由於VS2015會經過 "%MSVC_VER%"=="14" 的分支,所以我將原先構建的邏輯注釋掉(使用 REM),然后直接指定我VS2015 對應的 vcvars64.bat 文件的路徑
REM Call the required vcvars file in order to setup up build locations if "%MSVC_VER%"=="16" ( set VCVARS=%VSINSTANCEDIR%\VC\Auxiliary\Build\vcvars%SYSARCH%.bat ) else if "%MSVC_VER%"=="15" ( set VCVARS=%VSINSTANCEDIR%\VC\Auxiliary\Build\vcvars%SYSARCH%.bat ) else if "%MSVC_VER%"=="14" ( echo [%VSINSTANCEDIR%\VC\bin%MSVCVARSDIR%\vcvars%SYSARCH%.bat] REM set VCVARS=%VSINSTANCEDIR%\VC\bin%MSVCVARSDIR%\vcvars%SYSARCH%.bat set VCVARS="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat" ) else if "%MSVC_VER%"=="12" ( set VCVARS=%VSINSTANCEDIR%\VC\bin%MSVCVARSDIR%\vcvars%SYSARCH%.bat ) else ( echo Error: Invalid MSVC version! goto Terminate )
重新執行,腳本的執行便沒有其他錯誤了。
重新使用 VS 打開 ffmpeg_deps.sln ,還是提示報錯(部分項目未能正確加載),還是沒能 “ 重新加載項目 ”
經過一番探索,發現還需要 再安裝 另一個 自定義構建項 YASM,這一點是在 ShiftMediaProject 下其他 ffmpeg 的某些依賴項目下說明的,如 https://github.com/ShiftMediaProject/libvpx/tree/master/SMP 項目下的 readme 中:
*** Building with YASM *** In order to build libvpx using msvc you must first download and install YASM. YASM is required to compile all assembly files. 1) Visual Studio YASM integration can be downloaded from https://github.com/ShiftMediaProject/VSYASM/releases/latest 2) Once downloaded simply follow the install instructions included in the download.
關於為什么不將 自定義構建項 YASM 的下載說明放到 FFmpeg/SMP/readme.txt 下,項目維護者表示 ffmpeg 本身編譯直接依賴的項目只需要 NASM, 只是某些依賴本身編譯需要 YASM,想分開來在各自的依賴項目中說明
項目作者具體回復可查看:https://github.com/ShiftMediaProject/FFmpeg/pull/51
ShiftMediaProject 提供了自動下載和安裝 yasm 的安裝腳本,下載地址為: https://github.com/ShiftMediaProject/VSYASM/releases
安裝方法 以及 可能遇到的問題 同上一節 為 VS添加自定構建項 NASM 完全一致
這種情況為依賴項目的子項目沒有自動下載導致,這里截圖對應的項目為 gnutls 的 git子模塊 gnulib 沒有自動下載導致。
解決方案:手動下載 gnulib 到 gnutls/gnulib 文件夾下,這里可以使用 git submodule 指令同步下載如下,
如圖,如果沒有成功下載,可以嘗試手動下載,下載地址為 :
https://gitlab.com/libidn/gnulib-mirror.git
或者
git://git.sv.gnu.org/gnulib.git
可使用 git clone 下載代碼,然后放置到 gnutls/gnulib 文件夾下即可
可能原因:
解決方案下不同項目設置不一樣 (該問題由評論區網友 天空自由 遇到,其使用的的 VS 版本為 VS2019)
參考解決方案:
項目屬性 -> 配置屬性 -> C/C++ -> 代碼生成 -> 運行庫
都設置一樣就行了: 多線程調試(/MTd)
到此,編譯需要的所有事都完成了,重新打開VS,顯示(不可用)的項目是還沒重新加載, “ 重新加載項目 ”項目即可
接下來,指定一個啟動程序來調試,這里設置 ffmpeg.exe 為啟動項,“設為啟動項目” 后,開始構建編譯“生成”
編譯過程中,若提示如下,是正常的(可能是因為靜態編譯模式下 [使用的 lib文件] 在編譯生成lib文件后,VS沒有及時引用到臨時導致的?)
錯誤 LNK1181 無法打開輸入文件“libgmpd.lib” libnettle E:\openSourceGit\ffmpeg-vs\nettle\SMP\LINK 1
錯誤 LNK1181 無法打開輸入文件“libnettled.lib” libhogweed E:\openSourceGit\ffmpeg-vs\nettle\SMP\LINK 1
靜靜等待其編譯結束后,再點構建 “生成” 或是 “運行” 就沒報編譯上的錯誤了。
最后的最后,編譯完運行 “本地 Windows 調試器”,大概會彈出錯誤如下:
這是因為“調試”->“命令”使用的文件路徑,和 實際在“鏈接器”->“常規”中設置的“輸出文件”路徑不一致導致,將前者設置和后者一致即可。
好了,你可以用 vs 調試 ffmpeg 了 !