星球專享 | 播放器 FFmpeg 依賴庫的配置

語言: CN / TW / HK

上回書說道: 星球專享 | 關於播放器的一次專案實踐~~

目前已經完成了專案的建立,是怎樣一個專案呢?

首先是播放器 SDK ,也是專案最核心的模組,然後是對 SDK 進行單元測試的模組,最後是使用 SDK 做播放器的視覺化專案模組。

專案工程的每個目錄介紹已經在上篇文章中講過了,這裡會說一下如何開啟專案。

如圖所示,1 和 2 代表兩個 CMakeLists.txt 檔案,其中 1 代表的是 SDK 工程 CMake 配置檔案,2 代表的是播放器工程 CMake 配置檔案。

圖示 3 作為新增的庫檔案目錄,後面會介紹。

專案根目錄是作為 SDK 的目錄,而 demo 是在根目錄下的子目錄中,同時 demo 依賴根目錄 SDK 的編譯結果,這種專案配置在一些開源專案中還是很常見的。

當用 CLion 開啟工程時如果選擇了根目錄下的 CMakeLists.txt 就是 SDK 工程了,選擇了 demo 目錄下的就是播放器專案了,差別就是在 CLion 中能否有 PlanetPlayerDemo 這個構建,如下圖所示:

選擇 SDK 工程開啟方式時就只有 2 和 3 的選項了,其中 2 是 SDK 的構建,3 是單測的構建,而 1 是播放器開啟方式才有的,前期很多時候都只要 SDK 開啟方式就行了。

開啟工程之後,接下來就要新增 FFmpeg 的依賴了。

這裡並不打算講要如何編譯 FFmpeg ,因為一開始就被編譯困住了,很難接下來的學習,反而有一種簡單的方式直接拿編譯好的庫就行了。

如果是 Mac 電腦的話,使用 brew 安裝 ffmepg ,電腦上就已經有編譯好的庫了,而且還很全面。

brew install ffmpeg

眾所周知,FFmpeg 是有很多編譯選項和依賴選項的,那麼上面的命令到底指定了哪些依賴呢?

如上圖,:white_check_mark: 和 :negative_squared_cross_mark: 表示的意思很明確了。

另外箭頭所指的 url 地址其實就是 brew 安裝 ffmpeg 的編譯指令碼了,裡面指定了哪些依賴內容,比如涉及的 x264、x265 就包含在內了。

我們的播放器專案就是在 Mac 上執行的,所以完全可以直接用 brew 安裝好的 ffmpeg 庫。

如上命令,在 finder 中開啟 ffmpeg 的安裝目錄。

其中 include 目錄就是標頭檔案目錄,lib 目錄裡面放著 ffmpeg 的動態庫和靜態庫。

我們要的就是這兩個目錄裡的東西,直接拷出來用,為此我建立了一個倉庫,單獨存放這些編譯好的庫檔案(只用靜態庫就行)。

https://github.com/glumes/lib

這個倉庫正好對應之前提的圖示 3 的目錄。

溫馨提示:由於我在家用的 M1 Pro 對應 arm64 架構,所以拿出來的庫也是 arm64 架構的,如果你用的非 M1 對應的就是 x86_64 架構,這塊等我回公司了補上,也可以自己補上。

接下來就是要在工程中連結 FFmpeg 庫了。

首先新建了一個 vendor.cmake 作輔助,判斷當前系統是什麼平臺和架構的:

if (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
set(arch arm64)
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(arch x64)
endif ()

if (WIN32)
set(platform win)
elseif (APPLE)
set(platform mac)
else ()
message(FATAL_ERROR "not support current platform")
endif ()

然後新增連結 FFmpeg 庫的方法:

可以看到連結庫時用到了上面指定的平臺和架構資訊,這和我們的目錄結構是相互依賴的。

有了這兩個方法,在 SDK 工程和播放器工程都可以複用了。

接下來在 SDK 工程中的配置就和平常配置一樣了,依賴好 ffmpeg 的庫。

set(path ${CMAKE_CURRENT_SOURCE_DIR})

# SDK 的標頭檔案
set(PLANET_INCLUDES ./ include src)

include(${CMAKE_CURRENT_SOURCE_DIR}/vendor.cmake)

# 模擬第三方庫依賴
add_subdirectory(3rdparty/test1)
list(APPEND PLANET_INCLUDES 3rdparty/test1/src)

add_subdirectory(3rdparty/test2)
list(APPEND PLANET_INCLUDES 3rdparty/test2/src)

# 新增 FFmpeg 標頭檔案的依賴
list(APPEND PLANET_INCLUDES ${path}/lib/ffmpeg/${platform}/${arch}/include)
# 自定義方法 連結 ffmpeg 庫目錄
link_ffmpeg_directory(${path})

# SDK 的原始檔
file(GLOB_RECURSE PLANET_FILES
src/*.*)

# 編譯 SDK 的靜態庫
add_library(PlanetPlayer STATIC ${PLANET_FILES})

# 包含標頭檔案內容
target_include_directories(PlanetPlayer PUBLIC ${PLANET_INCLUDES})

# 連結三方庫
target_link_libraries(PlanetPlayer gtest TEST1 TEST2)

# 自定義方法 連結 ffmpeg
link_ffmpeg_library(PlanetPlayer ${path})

同樣在播放器專案中也要做配置,依賴 SDK 以及 ffmpeg 的庫。

# 設定 SDK 的根目錄
set(ProjectPath ${CMAKE_CURRENT_SOURCE_DIR}/../../PlanetPlayer)

# 自定義方法 連結 ffmpeg 庫目錄
link_ffmpeg_directory(${path})

# 播放器專案的標頭檔案
set(DEMO_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/src)

# SDK 提供的標頭檔案
list(APPEND DEMO_INCLUDES ${ProjectPath}/include)

# 播放器專案的原始檔
file(GLOB_RECURSE DEMO_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.*)

# 新增 SDK 的目錄
add_subdirectory(${ProjectPath}/ PlanetPlayer)

# 播放器專案
add_executable(PlanetPlayerDemo ${DEMO_SOURCE_FILES})

# 包含標頭檔案內容
target_include_directories(PlanetPlayerDemo PUBLIC ${DEMO_INCLUDES})

# 連結三方庫
target_link_libraries(PlanetPlayerDemo PlanetPlayer)

# 自定義方法 連結 ffmpeg
link_ffmpeg_library(PlanetPlayerDemo ${path})

這裡有個問題,就是既然 SDK 依賴了 ffmepg ,播放器依賴了 SDK ,為什麼播放器還有依賴 ffmpeg ?

這是因為編譯的 SDK 是個靜態庫,但是並沒有把 ffmpeg 的靜態庫合併進來,導致播放器僅連結了 SDK 的庫會找不到 ffmpeg 函式的符號表,後續再把這個功能補上。

另外也說明了,音視訊做工程搭建也是有很多學問的。

以上就是本篇文章的內容了,搞定了庫依賴就可以開始擼程式碼啦!!!

關於播放器實踐的專欄,後續大部分進展都會放在知識星球裡面了,尤其是原始碼會在星球內同步更新,當然也會挑一些乾貨在公眾號同步。

目前 音視訊開發進階知識星球 還在讓利中, 非常低的價格就可以獲得業內一線開發人員的答疑解惑

與其在 群裡面提問石沉大海,不如來星球有問必答 ,而且這個價格還是管一年的哦,一年的時間可以說是相當划算了。

同時星球內非常歡迎大家提問,尤其是我不會的問題,我會去找業內好朋友請教,既回答了你的問題又幫助了我提高。

想要加入的可以通過掃如下二維碼進星球哦,iPhone 使用者如果不能訪問小程式的話,也可以加我微信 ezglumes 拉你進星球。

一個音視訊領域專業問答的小圈子!

推薦閱讀:

音視訊開發工作經驗分享 || 視訊版

OpenGL ES 學習資源分享

開通專輯 | 細數那些年寫過的技術文章專輯

Android NDK 免費視訊線上學習!!!

你想要的音視訊開發資料庫來了

推薦幾個堪稱教科書級別的 Android 音視訊入門專案

覺得不錯,點個在看唄~