Webrtc的ios架構編譯,Webrtcios架構編譯
1.WebRTC的iOS架構的選擇
目前兩個比較活躍的開源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 webrtcwuqiong:webrtc_build apple$ cd webrtc
在上面的檢查工作沒錯之後,我們就需要開始把WebRTC項目的代碼倉庫下載一份到本地來.由於其倉庫之大,大約一共需要下載6G+的東西.所以這一步非常需要有耐心.而且需要有穩定無障礙的互連網. 執行如下命令然後吧:
wuqiong:webrtc apple$ gclient config --name src http://webrtc.googlecode.com/svn/trunkwuqiong:webrtc apple$ echo "target_os = ['ios']" >> .gclientwuqiong: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.shwuqiong: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 --force135 pushd src136 svn info | grep Revision > ../svn_rev.txt137 popd138 }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 srcwuqiong: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問題,會直接導致程式崩潰,如需瞭解詳情並擷取補丁,請聯絡戴維營教育。
本文檔由長沙戴維營教育整理。