编译 WebRTC 库

引言

最近一段时间的主要工作内容是开发一个远程控制手机的功能,其中音视频传输的部分是采用WebRTC技术来进行的,而我们的手机都是通过与其直接连接的Agent服务器进行管理,Agent服务是Java写的,现在市面上又没有合适的Java版WebRTC库,所以我就基于Google开源代码,写了一个JNI调用WebRTC Native的库。这里先简单介绍一下在编译WebRTC的过程中遇到的一些坑,分享一下整个工作过程中的经验。其他 WebRTC 相关文章均收录于 <WebRTC系列文章>

现有的编译工具

在编译WebRTC Native Lib这部分,我使用过Github上的两个开源方案:libwebrtc, webrtc-builds

实现思路

简单的讲他们都是一系列脚本的集合,遵从Google提供的编译方案,自动地来帮您做以下工作:

  1. 下载编译WebRTC所需要的工具
  2. 下载代码
  3. 根据您的需要切换到对应的分支
  4. 根据您指定的脚本参数来设置WebRTC的编译参数
  5. 编译代码
  6. 打包目标文件
  7. 安装库文件

区别

  • libwebrtc: 使用Cmake模块封装各个子功能
  • webrtc-builds: 使用纯Shell脚本实现

我的选择

其中,我比较喜欢libwebrtc,一个原因是它的README介绍的比较详细,还有一个原因是其配合CMake使用超级方便,因为它帮你创建了一个Cmake Lib,这样您仅需要几行就能引入该库。

1
2
3
4
find_package(LibWebRTC REQUIRED)
include(${LIBWEBRTC_USE_FILE})

target_link_libraries(my-app ${LIBWEBRTC_LIBRARIES})

而且NodeJS WebRTC当时也是使用这个库来编译他们的WebRTC库的,不过后来他们转而从源码直接编译了,可能是因为这个库太久没更新吧^.^,毕竟这个库官方声称只支持到M60版本的WebRTC。
我这里由于业务的需要,要求WebRTC Lib的版本至少是M68,所以我当时对这个库进行了部分修改,使其能够编译M70版本的WebRTC,此外我还开了一些别的参数,从而达到一些业务目的。总之,如果您也和我一样,需要一些自定义设置的WebRTC Lib的话,我的建议是基于libwebrtc,按需进行少许修改,虽然这并不容易。反之,如果M60版本就能满足您的需求的话,我强烈推荐您直接使用libwebrtc

修改LibWebRTC

我的修改版:libwebrtc-m70

改动内容

  1. Commit1:
    • 因为WebRTC内部文件目录的改变,多了一级webrtc目录,所以我们抽取头文件时,也要将这一级目录结构带上,否则引用部分头文件会报错。
    • 删除install-sysroot.py的废弃参数(–running-as-hook)
    • 修改默认版本为M70
  2. Commit2
    • 添加缺少的头文件abseil-cpp
  3. Commit3
    • 这里我参考了webrtc-builds的方式,用sed命令修改了部分BUILD.gn文件,添加了_GLIBCXX_USE_CXX11_ABI=0,因为libwebrtc在linux编译出来的库也有这个参数,所以编译webrtc时如果没有这个参数会出现找不到符号的问题。
    • 之后的几次提交修正了脚本路径的问题Commit3.1,Commit3.2,Commit3.1
  4. Commit4
    • 随后我发现自己的修正BUILG.gn执行的顺序总是有问题,没法以参数的形式传递GN_EXTRA_ARGS参数,所以我就把业务需要的GN参数直接写到了Gn.cmake
    • proprietary_codecs=true use_openh264=true ffmpeg_branding=\“Chrome\“ 是开启H264编码支持
    • use_custom_libcxx=false use_custom_libcxx_for_host=false 是和上一步类似的编译参数

如果您也想使用M70版本的WebRTC Lib可以直接使用我的这个版本,需要注意的是您需要把GN_EXTRA_ARGS 直接写到Gn.cmake中,这一版在Mac,Ubuntu,CentOS上都可以正常编译使用。如果您需要更高版本的WebRTC Lib可以基于我的版本进行修改。

修改经验

  • 编译问题主要还是集中在Linux系统下,在使用的时候会提示XXX符号找不到,如果您遇到了类似情况我建议先根据错误提示,通过nm libwebrtc.a 看看编译出来的库中有没有类似的符号。如果libwebrtc.a中有类似符号,只是返回值或者参数描述有些出入,缺少的符号带’cxx’的话, 比如编译的时候提示缺少’cxx1112basic_stringXXX’,实际有的符号是’112basic_stringXXX’,那么很可能就是编译的时候没有适配上’_GLIBCXX_USE_CXX11_ABI=0’。这时候你就需要检查一下这个符号是在哪个模块里定义的,然后效仿Commit3,把参数添加到对应的BUILD.gn中。
  • ‘__1__cxx11’相关的符号问题,一般是是libc++和libstdc++的问题。
  • 如果提示缺少某些符号,而且libwebrtc.a中也没有,那很有可能就是打包的时候漏掉了,那么您需要修改打包模块把漏掉的部分补回来find . -name "*.o" -exec nm -A {} \; | grep "WelsQuant4x4Dc_sse2"。 头文件找不到也同理。
  • 调试Gn参数时,可以使用gn args out/Release --list来查看当前的编译参数,以及是哪个文件最终影响了该参数。

参考内容

[1] StackOverflow Question
[2] gn-build-configuration
[3] libwebrtc
[4] webrtc-builds

贝克街的流浪猫 wechat
您的打赏将鼓励我继续分享!
  • 本文作者: 贝克街的流浪猫
  • 本文链接: https://www.beikejiedeliulangmao.top/webrtc/build-webrtc-native-lib/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 创作声明: 本文基于上述所有参考内容进行创作,其中可能涉及复制、修改或者转换,图片均来自网络,如有侵权请联系我,我会第一时间进行删除。