Webrtc的ios框架編譯

1.WebRTC的iOS框架的選擇

目前兩個比較活躍的開源WebRTC實現.

  • Google WebRTC:

項目地址是: https://code.google.com/p/webrtc/

  • Ericsson Research OpenWebRTC:

項目地址是: https://github.com/EricssonResearch/openwebrtc

我們戴維營教育爲了給學生實戰項目中運用WebRTC視頻通話技術,選擇Google的WebRTC項目來構建iOS App的開發框架,因爲目前Chrome瀏覽器和FireFox瀏覽器的WebRTC支持都是採用該項目.那麼問題就來了,既然瀏覽器裏都支持了WebRTC,那我們再去移植編譯它到iOS平臺幹嘛呢,直接用webview 不行? 對,還不行! Apple在這方面已經嚴重拖後腿了.不過他有他牛逼的Facetime技術,可以隨時隨地的視頻通話,但是他不開源,所以我們只能垂涎了. 故還是老老實實的移植WebRTC吧.非常幸運的是,Google 的Chromium項目開發者已經實現了其WebRTC的Objective-C的一套API了.

不過,醜話還是說在前頭好,要從零開始集成WebRTC到我們的App中中, 簡直就是噩夢;因爲WebRTC項目和Chromium項目有一定的關聯依賴關係,而且這些項目都是跨平臺的大項目,採用了Google自己的一套編譯系統,相對我們日常的IDE來說要複雜的多.如果我們需要得到一個WebRTC的庫或者框架,我們就需要忘記Xcode IDE和Interface Builder這些高科技,我們要切換到終端環境下用命令行下的黑科技來征服這一切.

2.開始WebRTC源碼下載

前提條件:

  • 我現在用的Macbook,8G內存,運行OS X 10.9.5.
  • 安裝最新的git和subversions並確保其可正常工作.
  • Xcode 6.1.1 和 Command Line Tools.
  • 中國大陸用戶額外要求,快速的VPN,或者快速的shadowsocks服務.(FQ和給git和svn以及curl設置代理等).

2.1 創建一個編譯目錄

我們創建一個目錄專門來存放項目編譯工具和項目代碼倉庫等.確保該目錄所在磁盤可用空間至少有8~10G.打開系統的終端工具進入到Shell:

wuqiong:~ apple$mkdir -p $HOME/opensource/webrtc_build/

2.2 下載Chromium的depot工具

在執行下面命令之前,請確保你已經連上快速VPN已經FQ了,或者你已經給git單獨配置了有效的socksFQ代理,如果你這些都不是問題,就當我沒說.

wuqiong:~ apple$cd $HOME/opensource/webrtc_build/
wuqiong:webrtc_build apple$git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

這是一套Google用來編譯Chromium或者WebRTC的構建工具,在我們後續的編譯過程中也將使用它.爲了命令行使用方便,我們把這些工具的路徑加入到系統環境變量PATH中去:

wuqiong:webrtc_build apple$echo "export PATH=$PWD/depot_tools:$PATH" > $HOME/.bash_profile

然後需要關閉當前終端重新開啓一個來上面設置的環境變量生效.或者在現在終端執行入門命令在當前終端里加載生效:

wuqiong:webrtc_build apple$source $HOME/.bash_profile

2.3 下載WebRTC的源碼

在我們的編譯工作目錄webrtc_build下創建一個webtrtc子目錄來存放代碼,請執行下面命令:

wuqiong:webrtc_build apple$ mkdir webrtc
wuqiong:webrtc_build apple$ cd webrtc 

在上面的檢查工作沒錯之後,我們就需要開始把WebRTC項目的代碼倉庫下載一份到本地來.由於其倉庫之大,大約一共需要下載6G+的東西.所以這一步非常需要有耐心.而且需要有穩定無障礙的互聯網. 執行如下命令然後吧:

wuqiong:webrtc apple$ gclient config --name src http://webrtc.googlecode.com/svn/trunk
wuqiong:webrtc apple$ echo "target_os = ['ios']" >> .gclient
wuqiong:webrtc apple$ gclient sync --force

FQ快的去喝咖啡,慢的去約妹子吧.辦完事情之後回來如果上面的命令都一切順利,我們就可以往下走去開始編譯了. (爲了方便大家,我已經把webrtc_build目錄打包備份,這樣大家可以省去大量的代碼下載時間.打包文件有5G,正在尋找網盤存放,隨後公佈.)

2.4 編譯WebRTC.framework

到了這一步,源碼應該已經下載好了.這些源碼可以編譯爲好幾個平臺,OS X, Linux, Windows, Android, iOS等.這裏我們只需要編譯iOS平臺的WebRTC,並製作成一個iOS的開發框架.這裏我們不能用Xcode工具,因爲這些項目壓根就不支持XCode.我們需要在終端命令行環境下去搞定這一切!

首先,爲了我們裝逼玩黑武器,我們需要在webrtc的項目代碼目錄下創建一個腳本, 這個腳本就是我爲了簡化命令的複雜度和提高使用的方便性專門編寫的一個一鍵框架編譯腳本,這個腳本就是今天的核心黑科技了.先創建一個空文件,然後賦予執行權限:

wuqiong:webrtc apple$ touch build_webrtc.sh
wuqiong:webrtc apple$ chmod +x build_webrtc.sh

然後用編輯器打開編輯剛剛創建的腳本文件,把如下腳本粘貼進去之後保存並關閉:

複製代碼
  1 #!/bin/bash
  2 # Script to build WebRTC.framework for iOS
  3 # Copyright (C) 2015 戴維營教育  - All Rights Reserved
  4 # Last revised 28/1/2015
  5 #
  6 
  7 function build_iossim_ia32() {
  8     echo "*** building WebRTC for the ia32 iOS simulator";
  9     export GYP_GENERATORS="ninja";
 10     export GYP_DEFINES="build_with_libjingle=1 build_with_chromium=0 libjingle_objc=1 OS=ios target_arch=ia32";
 11     export GYP_GENERATOR_FLAGS="$GYP_GENERATOR_FLAGS output_dir=out_ios_ia32";
 12     export GYP_CROSSCOMPILE=1;
 13     pushd src;
 14     gclient runhooks;
 15     ninja -C out_ios_ia32/Release-iphonesimulator iossim AppRTCDemo;
 16 
 17     echo "*** creating iOS ia32 libraries";
 18     pushd out_ios_ia32/Release-iphonesimulator/;
 19     rm -f  libapprtc_signaling.a;
 20     popd;
 21     mkdir -p out_ios_ia32/libs;
 22     libtool -static -o out_ios_ia32/libs/libWebRTC-ia32.a out_ios_ia32/Release-iphonesimulator/lib*.a;
 23     strip -S -x -o out_ios_ia32/libs/libWebRTC.a -r out_ios_ia32/libs/libWebRTC-ia32.a;
 24     rm -f out_ios_ia32/libs/libWebRTC-ia32.a;
 25     echo "*** result: $PWD/out_ios_ia32/libs/libWebRTC.a";
 26 
 27     popd;
 28 }
 29 
 30 function build_iossim_x86_64() {
 31     echo "*** building WebRTC for the x86_64 iOS simulator";
 32     export GYP_GENERATORS="ninja";
 33     export GYP_DEFINES="build_with_libjingle=1 build_with_chromium=0 libjingle_objc=1 OS=ios target_arch=x64 target_subarch=arm64";
 34     export GYP_GENERATOR_FLAGS="$GYP_GENERATOR_FLAGS output_dir=out_ios_x86_64";
 35     export GYP_CROSSCOMPILE=1;
 36     pushd src;
 37     gclient runhooks;
 38     ninja -C out_ios_x86_64/Release-iphonesimulator iossim AppRTCDemo;
 39 
 40     echo "*** creating iOS x86_64 libraries";
 41     pushd out_ios_x86_64/Release-iphonesimulator/;
 42     rm -f  libapprtc_signaling.a;
 43     popd;
 44     mkdir -p out_ios_x86_64/libs;
 45     libtool -static -o out_ios_x86_64/libs/libWebRTC-x86_64.a out_ios_x86_64/Release-iphonesimulator/lib*.a;
 46     strip -S -x -o out_ios_x86_64/libs/libWebRTC.a -r out_ios_x86_64/libs/libWebRTC-x86_64.a;
 47     echo "*** result: $PWD/out_ios_x86_64/libs/libWebRTC.a";
 48 
 49     popd;
 50 }
 51 
 52 function build_iosdevice_armv7() {
 53     echo "*** building WebRTC for armv7 iOS devices";
 54     export GYP_GENERATORS="ninja";
 55     export GYP_DEFINES="build_with_libjingle=1 build_with_chromium=0 libjingle_objc=1 OS=ios target_arch=armv7";
 56     export GYP_GENERATOR_FLAGS="$GYP_GENERATOR_FLAGS output_dir=out_ios_armv7";
 57     export GYP_CROSSCOMPILE=1;
 58     pushd src;
 59     gclient runhooks;
 60     ninja -C out_ios_armv7/Release-iphoneos AppRTCDemo;
 61 
 62     echo "*** creating iOS armv7 libraries";
 63     pushd out_ios_armv7/Release-iphoneos/;
 64     rm -f  libapprtc_signaling.a;
 65     popd;
 66     mkdir -p out_ios_armv7/libs;
 67     libtool -static -o out_ios_armv7/libs/libWebRTC-armv7.a out_ios_armv7/Release-iphoneos/lib*.a;
 68     strip -S -x -o out_ios_armv7/libs/libWebRTC.a -r out_ios_armv7/libs/libWebRTC-armv7.a;
 69     echo "*** result: $PWD/out_ios_armv7/libs/libWebRTC.a";
 70 
 71     popd;
 72 }
 73 
 74 function build_iosdevice_arm64() {
 75     echo "*** building WebRTC for arm64 iOS devices";
 76     export GYP_GENERATORS="ninja";
 77     export GYP_DEFINES="build_with_libjingle=1 build_with_chromium=0 libjingle_objc=1 OS=ios target_arch=arm64 target_subarch=arm64";
 78     export GYP_GENERATOR_FLAGS="$GYP_GENERATOR_FLAGS output_dir=out_ios_arm64";
 79     export GYP_CROSSCOMPILE=1;
 80     pushd src;
 81     gclient runhooks;
 82     ninja -C out_ios_arm64/Release-iphoneos AppRTCDemo;
 83 
 84     echo "*** creating iOS arm64 libraries";
 85     pushd out_ios_arm64/Release-iphoneos/;
 86     rm -f  libapprtc_signaling.a;
 87     popd;
 88     mkdir -p out_ios_arm64/libs;
 89     libtool -static -o out_ios_arm64/libs/libWebRTC-arm64.a out_ios_arm64/Release-iphoneos/lib*.a;
 90     strip -S -x -o out_ios_arm64/libs/libWebRTC.a -r out_ios_arm64/libs/libWebRTC-arm64.a;
 91     echo "*** result: $PWD/out_ios_arm64/libs/libWebRTC.a";
 92 
 93     popd;
 94 }
 95 
 96 function combine_libs() 
 97 {
 98     echo "*** combining libraries";
 99     lipo  -create   src/out_ios_ia32/libs/libWebRTC.a \
100             src/out_ios_x86_64/libs/libWebRTC.a \
101             src/out_ios_armv7/libs/libWebRTC.a \
102             src/out_ios_arm64/libs/libWebRTC.a \
103             -output libWebRTC.a;
104     echo "The public headers are located in $PWD/src/talk/app/webrtc/objc/public/*.h";
105 }
106 
107 function create_framework() {
108     echo "*** creating WebRTC.framework";
109     rm -rf WebRTC.framework;
110     mkdir -p WebRTC.framework/Versions/A/Headers;
111     cp ./src/talk/app/webrtc/objc/public/*.h WebRTC.framework/Versions/A/Headers;
112     cp libWebRTC.a WebRTC.framework/Versions/A/WebRTC;
113 
114     pushd WebRTC.framework/Versions;
115     ln -sfh A Current;
116     popd;
117     pushd WebRTC.framework;
118     ln -sfh Versions/Current/Headers Headers;
119     ln -sfh Versions/Current/WebRTC WebRTC;
120     popd;
121 }
122 
123 function clean() 
124 {
125     echo "*** cleaning";
126     pushd src;
127     rm -rf out_ios_arm64 out_ios_armv7 out_ios_ia32 out_ios_x86_64;
128     popd;
129     echo "*** all cleaned";
130 }
131 
132 function update()
133 {
134     gclient sync --force
135     pushd src
136     svn info | grep Revision > ../svn_rev.txt
137     popd
138 }
139 
140 function build_all() {
141     build_iossim_ia32 && build_iossim_x86_64 && \
142     build_iosdevice_armv7 && build_iosdevice_arm64 && \
143     combine_libs && create_framework;
144 }
145 
146 function run_simulator_ia32() {
147     echo "*** running webrtc appdemo on ia32 iOS simulator";
148     src/out_ios_ia32/Release-iphonesimulator/iossim src/out_ios_ia32/Release-iphonesimulator/AppRTCDemo.app;
149 }
150 
151 function run_simulator_x86_64() {
152     echo "*** running webrtc appdemo on x86_64 iOS simulator";
153     src/out_ios_x86_64/Release-iphonesimulator/iossim -d 'iPhone 6' -s '8.1'  src/out_ios_x86_64/Release-iphonesimulator/AppRTCDemo.app;
154 }
155 
156 function run_on_device_armv7() {
157     echo "*** launching on armv7 iOS device";
158     ideviceinstaller -i src/out_ios_armv7/Release-iphoneos/AppRTCDemo.app;
159     echo "*** launch complete";
160 }
161 
162 function run_on_device_arm64() {
163     echo "*** launching on arm64 iOS device";
164     ideviceinstaller -i src/out_ios_arm64/Release-iphoneos/AppRTCDemo.app;
165     echo "*** launch complete";
166 }
167 
168 #運行命令行參數中第一個參數所指定的Shell函數
169 $@
複製代碼

這個編譯腳本除了可以編譯WebRTC項目自帶的AppRTCDemo應用外,還可以編譯出WebRTC.framework.

執行如下命令來編譯我們所需要的全部:

wuqiong:webrtc apple$ ./build_webrtc.sh build_all

等上面命令完成之後,我們所需要的WebRTC框架就在當前目錄下了.可以用ls命令查看之:

wuqiong:webrtc apple$ ls 
WebRTC.framework build_webrtc.sh  libWebRTC.a      src
wuqiong:webrtc apple$ 

第一個WebRTC.framework就是我們需要的框架了! 到此,我們的編譯任務就完成了! 不是吧..就這麼簡單?不是說起來超級麻煩嗎?呵呵,裝逼結束. 繁瑣的部分已經封裝到了shell腳本里頭去了.如果有興趣可以去研究一下這個腳本.

2.5 WebRTC.framework的依賴.

如果項目使用了該框架,那麼編譯的時候需要在項目的Build Phases中添加如下庫和框架:

  • libstdc++.6.dylib
  • libsqlite3.dylib
  • libc++.dylib
  • libicucore.dylib
  • Security.framework
  • CFNetwork.framework
  • GLKit.framework
  • AudioToolbox.framework
  • AVFoundation.framework
  • CoreAudio.framework
  • CoreMedia.framework
  • CoreVideo.framework
  • CoreGraphics.framework
  • OpenGLES.framework
  • QuartzCore.framework

重要提示

目前Google官方代碼中在ARMv7平臺有VP8視頻編碼的stackoverflow問題,會直接導致程序崩潰,如需瞭解詳情並獲取補丁,請聯繫戴維營教育

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章