Linux 下開發基於 webrtc 的實時音視訊 SDK
在 Linux 平臺下開發實時通話 SDK 其實是主要應用於未來的 IOT 行業,先基於 Ubuntu 作為開發平臺,完成後再基於每個客戶提供的其交叉編譯工具鏈進行交叉編譯以供使用者使用。
1、基於 Ubuntu 下載 webrtc
1.1 自行下載編譯
如果是自己下載編譯的話,可以參考官方教程,或者參考本人之前的一篇部落格:https://www.jianshu.com/p/09f065f3feb0 ,其實 Ubuntu 下編譯 webrtc 是比較簡單的,只要可以翻牆,其它都只是時間問題了。
1.2 國內網路問題無法自行下載
那麼可以通過下載本人配置的一個 Docker 映象進行進行編譯:https://hub.docker.com/r/cgb0210/ubuntu_build ,由於 Docker 不適合作為開發環境,下載後,建議使用者將 develop 目錄下的檔案拷貝到自己的開發環境中,並參考https://www.jianshu.com/p/09f065f3feb0 配置相關環境變數,實現本地編譯,過程主要包含 3 步:
1.3 配置 depot_tools 環境變數
將export PATH=$PATH:/home/gobert/develop/depot_tools
新增到/etc/profile
檔案尾部;
1.4 安裝 GoLang 並配置環境
1.5 安裝 Linux 依賴包
執行 webrtc 目錄下的/build/install-build-deps.sh
指令碼命令,如:sudo sh build/install-build-deps.sh
;
2、編譯 webrtc
預設情況下,Linux 下基於 ninja 編譯的話,其編譯器使用的是 clang,且其依賴的 stdc 標準庫為其 ./buildtools/third_party/libc++ 內建的,所以如果外部想要基於 clang 編譯的 libwebrtc.a 進行開發的話,上層依然需要使用 clang 做為編譯器,且連結 webrtc 內部的 libc++ 標準庫,否則將會產生各種error: undefined reference to symbol ...
,無法解決,雖然 clang 比 g++ 要優秀很多,但本人目前還是習慣使用 g++ 進行開發,所以需要指定 g++ 編譯器,同時需要注意以下事項:
2.1 RTTI (Run-Time Type Identification 執行時型別識別)
webrtc 內部各模組配置了不同的 rtti 屬性,開、關各不相同,預設情況下,載入 libwebrtc.a 會產生undefined reference to
typeinfo for [classname]'錯誤,為此我們可以在連結 libwebrtc.a 的根編譯指令碼檔案中配置統一去除 rtti 屬性,以解決此類問題,開啟根目錄下的 BUILD.gn 檔案,在
rtc_static_library("webrtc")尾部新增
cflags_cc = [" -fno-rtti" ]` 即可,如下:
if (!build_with_chromium) { # Target to build all the WebRTC production code. rtc_static_library("webrtc") { ... cflags_cc = [" -fno-rtti" ] } }
這樣便可以解決所有 undefined reference totypeinfo for [classname]'
類的錯誤。
2.2 找不到 builtin_audio_decoder_factory 模組的所有符號
這應該是 webrtc branch:68 版本的 bug,在各平臺均會出現此類問題,原因在於其在編譯指令碼中漏寫了builtin_audio_decoder_factory
模組,加上即可,開啟audio/BUILD.gn
檔案,在"../api/audio_codecs:builtin_audio_encoder_factory",
下面新增一行"../api/audio_codecs:builtin_audio_decoder_factory",
即可。
2.3 編譯
編譯命令如下:
gn gen -C out/Linux/Release--args="is_debug=false target_cpu=\"x64\" rtc_include_tests=false rtc_use_h264=true rtc_initialize_ffmpeg=true ffmpeg_branding=\"Chrome\" is_component_build=false"
其中rtc_include_tests=false
為禁止編譯單元測試程式,可大大節省編譯時間;
rtc_use_h264=true rtc_initialize_ffmpeg=true ffmpeg_branding=\"Chrome\"
為啟用內部 H.264 編解碼器。
3、Demo 程式
3.1 編譯測試程式載入並呼叫 webrtc 介面。
#include <stdio.h> #include <string> #include "api/jsep.h" using namespace std; using namespace webrtc; int main(int argc, char const *argv[]) { SdpParseError error; auto ptr = CreateSessionDescription("offer", "sdp", &error); if (!ptr) { printf("CreateSessionDescription return null, error str:%s\n", error.description.c_str()); } else { printf("CreateSessionDescription success!\n"); } return 0; }
3.2 編寫 CMakeLists.txt 指令碼檔案
cmake_minimum_required(VERSION 3.5) project(demo) set(CMAKE_POSITION_INDEPENDENT_CODETRUE) set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS}") SET(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS} -fno-exceptions -fPIC") set(CMAKE_SHARED_LINKER_FLAGS"${CMAKE_SHARED_LINKER_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS"${CMAKE_EXE_LINKER_FLAGS}") set(ARCH_PATH linux) set(WEBRTC_PATH "/home/gobert/develop/webrtc/src") set(WEBRTC_LIBRARY_PATH "/home/gobert/develop/webrtc/src/out/Linux/Release/obj") add_definitions( "-DWEBRTC_POSIX" "-DWEBRTC_LINUX" "-DUSE_GLIB=1" ) if (Linux) set(ARCH_PATH linux) elseif (Arm) set(ARCH_PATH arm) endif () include_directories( ${WEBRTC_PATH} ) set(SOURCE_FILES main.cpp ) link_directories( ${link_directories} ${WEBRTC_PATH}/out/Linux/Release/obj /usr/lib/x86_64-linux-gnu/ ) link_libraries( "${WEBRTC_LIBRARY_PATH}/libwebrtc.a" ) add_executable(demo ${SOURCE_FILES}) TARGET_LINK_LIBRARIES(demo pthread stdc++) set_target_properties(demo PROPERTIES OUTPUT_NAME "demo")
3.3 編譯
cmake && make