WebRTC入门:iOS工程

刚进到新的项目组,就接到WebRTC相关的任务。我们的项目是需要基于WebRTC上做二次开发。而最新版本的WebRTC的工程是基于gn和ninja,每次修改完后,编译成lib或者framework才能进行调试。特别不方便。本文记录的就是分离WebRTC的OC工程的踩坑过程。

注:目前编译通过,但是还是存在内存问题。GN的编译条件还存在差别。暂时还没解决。

0x00 什么是WebRTC?

WebRTC,名称源自网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌2010年以6820万美元收购Global IP Solutions公司而获得的一项技术。2011年5月开放了工程的源代码,在行业内得到了广泛的支持和应用,成为下一代视频通话的标准。

官网介绍:https://webrtc.org

0x01 获取源码

第一步就是获取源码。由于不可抗力,需自行备梯。我们的目标是获取iOS版本的代码。原文档:https://webrtc.org/native-code/ios/

  1. 获取depot tools, 并且配置好环境。http://dev.chromium.org/developers/how-tos/install-depot-tools

  2. 获取WebRTC iOS版本代码。

    $ mkdir webrtc && cd webrtc
    # 下载源码库
    $ fetch --nohooks webrtc_ios
    # 同步第三方依赖库
    $ gclient sync
    

    接下来就是耐心的等待, 代码库大概是6G左右。我获取是1月3号的版本:d25f79e

坑:由于使用了代理。所以需要设置curl的代理配置。否则git无法正常工作。

$ export https_proxy=http://127.0.0.1:1235;export http_proxy=http://127.0.0.1:1235

0x02 编译库

WebRTC是使用GN来生成ninja工程文件的。所以需要了解GN和ninja的基本使用。中文资料很少,但是官网上的教程写得非常好,容易上手。当然你也可以不了解的情况下,直接用下面几个命令就可以编译出WebRTC.framework。

## 生成ninja工程文件
# debug build for 64-bit iOS
gn gen out/ios_64 --args='target_os="ios" target_cpu="arm64" is_component_build=false'

# debug build for simulator
gn gen out/ios_sim --args='target_os="ios" target_cpu="x64" is_component_build=false'

## 编译WebRTC.framework 文件
ninja -C out/ios rtc_sdk_framework_objc

上面的方法可以编译出某一cpu架构版本的库,但是实际开发时需要支持多个cpu架构。

在代码库中已经包含了编译脚本代码。查看/webrtc/build/ios/build_ios_libs.sh

➜  src git:(libwebrtc) ✗ ./webrtc/build/ios/build_ios_libs.sh -h
WebRTC iOS FAT libraries build script.
Each architecture is compiled separately before being merged together.
By default, the fat libraries will be created in out_ios_libs/.
The headers will be copied to out_ios_libs/include.
Usage: ./webrtc/build/ios/build_ios_libs.sh [-h] [-b build_type] [-c] [-o output_dir]
  -h Print this help.
  -b The build type. Can be framework, or static_only.
     Defaults to framework.
  -c Removes generated build output.
  -o Specifies a directory to output build artifacts to.
     If specified together with -c, deletes the dir.
  -r Specifies a revision number to embed if building the framework.
  -e Compile with bitcode.
➜  src git:(libwebrtc) ✗

官方已经准备好编译脚本,很方便的编译出静态库版本和Framework版本,另外也可以指定其他编译条件,如是否为debug版本,是否开启bitcode。也可以配置更多的其他gn配置参数。详情查看目录:/build, /build_overrides, /webrtc/build 三个目录下的.gni和BUILD.gn内的参数配置。

由于WebRTC项目既是Chrome的子项目又是可以作为独立项目。支持win,linux,android,chorome os,mac,ios。支持多种cpu架构。而且高度模块化,可定制化。所以配置参数特别多。

好消息是,大部分参数才是都已经为我们配置好了。我们无需修改或者修改很少的部分参数就可以使用了。

0x03 准备分离objc工程

小目标:WebRTC.framework的代码放到Xcode工程里面。而其余部分代码使用静态库的方式引用。这样我们只需关注objc部分的二次开发,而无需太多关注c++部分的其他代码。

生成libjingle_peerconnection_all

增加jingle_peerconnection_all目标. 修改/webrtc/BUILD.gn文件。增加以下代码

# 增加新的目标,编译webrtc的c++接口库。(iOS版本还包含了rtc_sdk_common_objc的代码)
rtc_static_library("jingle_peerconnection_all") {
  complete_static_lib = true
  deps = [
    "api:libjingle_peerconnection",
    
    # 需要增加下面2项,参考rtc_sdk_framework_objc配置。
    "//webrtc/system_wrappers:field_trial_default", 
    "//webrtc/system_wrappers:metrics_default",
  ]
}

修改/webrtc/build/ios/build_ios_libs.sh脚本。增加编译这个目标的选项-b static_only_cpp支持。具体见修改后的文件。

  # Generate static or dynamic.
  if [[ ${build_type} = "static_only" ]]; then
    GN_TARGET_NAME="rtc_sdk_objc"
  elif [[ ${build_type} == "static_only_cpp" ]]; then   ## 增加的条件参数选项
    GN_TARGET_NAME="jingle_peerconnection_all"          ## 指定我们上面新增的目标
    GN_ARGS="${GN_ARGS} enable_dsyms=true enable_stripping=true"
  elif [[ ${build_type} == "framework" ]]; then
    GN_TARGET_NAME="rtc_sdk_framework_objc"
    GN_ARGS="${GN_ARGS} enable_dsyms=true enable_stripping=true"
  fi

我们只需输入一下命令,就可以打包生成库了。

$ webrtc/build/ios/build_ios_libs.sh -o out/ios-libs -b static_only_cpp

增加WebRTC_OC工程

webrtc/sdk/objc目录增加一个空的iOS工程。对比webrtc/sdk/objc/BUILD.gn文件中的rtc_sdk_common_objcrtc_sdk_framework_objc目标的配置。选择性添加Framework文件夹的代码文件。

原工程使用gn文件进行配置。如前面所提的,大量配置变量分布在下面几个文件夹内。

  • /build
  • /build_overrides
  • /webrtc/build

以下是踩过的坑:

  1. 打包后libjingle_peerconnection_all包含了rtc_sdk_common_objc。所以不能添加rtc_sdk_common_objc的代码。注意导出的头文件,只有部分是公开头文件。
  2. 需要根据环境配置宏。指定各种编译配置和定义宏。
    1. 关闭bitcode。
      2)关闭rtti。
      3)增加-all_load
      4)增加WebRTC_OC/Info.plist
      5)指定module map: Framework/Modules/module.modulemap
    2. 设置search path: 具体看工程。代码使用相对路径,需要添加好搜索路径。
      7)增加prefix pch: $(SRCROOT)/WebRTC-Prefix.pch
    3. 指定C++库版本:libc++
    4. 添加宏 WEBRTC_POSIX, WEBRTC_IOS, TARGET_OS_IPHONE=1
    5. 添加 libjingle_peerconnection_all 库。

0x04 总结

接触WebRTC的代码,踩坑几天的感受。

  • 工程非常庞大。完整代码库达到惊人的6G大小。
  • 模块化程度高。分层,分模块。根据我们的需求,只需要关注API层就可以了。
  • 感受到gn进行工程配置的强大能力。gn进行多系统,多cpu,多目标,多配置条件。
  • ninja部分。模块化编译。增量编译,提高编译速度。

虽然已经分离出OC的工程,但现有工程对完整代码库的依赖:

  • 头文件引用。源码是用的是相对位置引用,如果要完全分离头文件,需要改动源码。这个问题不解决,就不能完全分离出库和头文件。
  • 头文件导出。需要修改头文件的对外部头文件引用方式。

现有的方式是不修改源码的方式,最小化修改,进行工程分离。
而完全分离,则需要对源码做大量的修改(头文件引用)。


延伸阅读:

What is GN?
GN Quick Start guide
GN Style Guide
The Ninja build system
Have a try on Ninja
WebRTC介绍

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容