Ubuntu18.04 從頭開始編譯 Android Native WebRTC

本文詳細記錄Mac下使用PD虛擬機安裝ubuntu18.4桌面版,編譯Android Native WebRTC的過程。

注意如果僅僅是使用WebRTC沒必要手動編譯源碼,直接用官方提供的預編譯包即可:

The easiest way to get started is using the official prebuilt libraries available at JCenter. These libraries are compiled from the tip-of-tree and are meant for development purposes only.On Android Studio 3 add to your dependencies:

<code>implementation 'org.webrtc:google-webrtc:1.0.+'
/<code>

On Android Studio 2 add to your dependencies:

<code>compile 'org.webrtc:google-webrtc:1.0.+'
/<code>

The version of the library is 1.0… The hash of the commit can be found in the .pom-file. The third party licenses can be found in the THIRD_PARTY_LICENSES.md file next to the .aar-file.

只有需要研究和修改源代碼時才有必要下載代碼並自己編譯。

按照官網的教程WebRTC源碼編譯看似簡單,但坑很多,尤其是為了能連上谷歌配置代理就要折騰很久,而且虛擬機本身也不省心。

為此新創建了一個虛擬機從頭開始配置,因為之前折騰的東西可能沒有全部記住,當時也沒有記錄,從頭開始保證一個命令都不差地記錄下來。當然,這裡使用的每一個環節的軟件和系統發生變化都會導致不一致的配置過程,僅供參考。

安裝配置Ubuntu虛擬機

Ubuntu下載地址:http://releases.ubuntu.com/18.04/ubuntu-18.04-desktop-amd64.iso

詳細安裝步驟:

1.安裝選擇鏡像方式,不要選擇下面的下載Ubuntu,很慢

2.進入這個頁面後點擊“手動選擇”

3.選擇下載好的iso文件

4.選擇後識別出Ubuntu,繼續

5.設置用戶名密碼

6.設置在mac系統內虛擬機文件的文件名和位置

7.創建中,這裡等了大概一個小時

安裝Parallels Tools

1.從菜單中選擇安裝Parallels Tools

2.會自動 mount 一個 CDROM很不幸,直接雙擊 install-gui 無法安裝,命令行運行 install 也無法安裝。網上查了很久,最終發現了一篇文章,可以完美解決這個問題:https://gist.github.com/rudolfratusinski/a4d9e3caff11a4d9d81d2e84abc9afbf

這裡是按照上面步驟修改好的安裝文件:百度網盤 (adsh),沒試過直接用行不行。

3.安裝完成後直接重啟重啟後分辨率自動調到最大,可以與mac共享剪貼板了。此時虛擬機文件僅僅7G左右。我又創建了個快照變成8G了。。。

下載WebRTC代碼

修改 Ubuntu 源

推薦使用清華大學開源軟件鏡像站https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/

備份原生source.list sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup修改替換為清華鏡像版本,推薦使用gedit:sudo gedit /etc/apt/sources.list執行 sudo apt update

配置代理

這裡使用環境變量配置 http proxy 的方法。後面還有個坑,需要結合代碼下載步驟說明。

使用主機sockes提供的http代理。虛擬機網絡模式使用默認的共享網絡。在PD的偏好設置裡可以找到網絡設置,可以查看共享網絡地址段:10.211.55.1~254,主機是第一個節點因此IP是10.211.55.2。

查看地址段設置mac上的SS的http代理監聽地址為0.0.0.0才能允許任意IP使用:

設置ss的http代理地址最後設置ubuntu的環境變量。

<code># 可以寫入 .bashrc 文件中
export ALL_PROXY=http://10.211.55.2:1087
export HTTP_PROXY=http://10.211.55.2:1087
export HTTPS_PROXY=http://10.211.55.2:1087
/<code>

下載代碼之前安裝了一些常用軟件sudo apt install curl vim net-tools

下載代碼

命令清單官方文檔:https://webrtc.org/native-code/android/總結一下,執行以下步驟和命令:

<code># 1.安裝必要的軟件
sudo apt install git python
# 2.切換到 home
cd /home/webrtc
# 3.安裝和設置代碼下載工具
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=$PATH:/home/webrtc/depot_tools # 可以寫在 .bashrc 裡
# 4.創建工作目錄並進入
mkdir webrtc_android
cd webrtc_android # 注意接下來執行命令始終在這個目錄下
# 5.下載第一步:fetch
fetch --nohooks webrtc_android
# 6.設置 gclient 代理,原因是 gclient 無法使用 $HTTP_PROXY 設置代理,
# 而要使用 .boto 文件來設置。這就是上文提到的坑:)
export NO_AUTH_BOTO_CONFIG=/home/webrtc/.boto # 可以寫在 .bashrc 裡
echo -e "[Boto]\\nproxy = 10.211.55.2\\nproxy_port = 1087" > /home/webrtc/.boto
# 7.下載第二步:gclient,官網是一個步驟 "gclient sync",這裡可以拆成兩個
gclient sync --nohooks # 同步代碼用時較短
gclient runhooks # 運行一些 hooks,會下載一些文件,其實這個步驟才需要 .boto 設置代理
/<code>

下載第一步:fetch

fetch的步驟會下載16G的代碼和開發環境,會持續很長時間取決於網速。好在每十秒鐘會有一次打印,提醒你仍在下載不是卡死了。

每十秒一次打印fetch過程中git clone失敗會自動重試。但如果整個腳本退出了,那就跪了。直接在原來的位置再次執行fetch是不行的,可以試試下一個命令gclient sync,保險起見可以重來。。。網速不行的總掉線的,可以洗洗睡了。

總之需要穩定的網絡環境,還不能太慢,寫這篇文章時的下載跪了一次,第二天重來,連的網線,網速稍快且很穩定,大概800k/s左右,6個小時。

fetch完成的畫面

設置 gclient 代理

gclient sync 的步驟需要另一種代理設置:參考這篇文章 WebRTC在iOS端的實現/WebRTC在iOS端的實現

主要是設置一個.boto文件,總結為上面清單裡的兩條命令:

<code>export NO_AUTH_BOTO_CONFIG=/home/webrtc/.boto
echo -e "[Boto]\\nproxy = 10.211.55.2\\nproxy_port = 1087" > /home/webrtc/.boto
# 這裡就是創建一個 .boto 文件按照固定的語法寫上代理配置,文件內容如下:



[Boto]
proxy = 10.211.55.2
proxy_port = 1087
/<code>

經過實際應用,並不需要unset掉環境變量,反而運行gclient runhooks時仍然需要環境變量,只要設置好NO_AUTH_BOTO_CONFIG就可以了。

下載第二步:gclient

這個步驟相比第一步很快就會完成,主要耗時在一些文件下載上。之後更新代碼執行 gclient sync 即可。

編譯打包

安裝必要的軟件和包

參考官網:Prerequisite Software >> Install additional build dependencies

<code># 進入到src目錄中
cd src # 執行完後,當前目錄應為 /home/webrtc/webrtc_android/src
# 下載 java相關命令和包,以及其他一些必要的軟件和包
build/install-build-deps-android.sh # 執行過程中要輸入 sudo 密碼
/<code>

工具

WebRTC項目使用了大量的第三方開源項目,代碼龐大複雜,整個構建系統採用了gn gn官方文檔 和ninja ninja官方文檔。

GN

gn命令處理的是名稱為 BUILD.gn 的文件,BUILD.gn 文件中可以定義若干參數,這些參數使 gn 命令執行時可以通過不同的參數值創建不同的編譯配置。例如WebRTC的目標系統是在android上還是ios上。

gn使用文件目錄層次來組織不同的編譯目標,這是非常自然合理的。查看 WebRTC 的目錄結構可以發現每個文件夾下面都對應著一個 BUILD.gn 的文件,含有 BUILD.gn 文件表示這個目錄下是有編譯目標的,這些編譯目標可以依賴子目錄的編譯目標從而組成一套複雜而有序的構建圖。

NINJA

gn的輸出就是擴展名為 .ninja 的文件,這些文件保存在編譯目錄中,可以被 ninja 命令直接使用,ninja文件中的指令都是簡單和明確的,不需要任何額外的邏輯判斷和計算,這使得ninja具有小而快的特點,也是ninja本身的設計初衷。

編譯所有目標

官網上的編譯打包命令:

<code>cd webrtc_android/src


gn gen out/Debug --args='target_os="android" target_cpu="arm"'
ninja -C out/Debug
/<code>

總共會有八千多個構建目標,大約會執行一個小時以上。

編譯 example app

<code>cd webrtc_android/src
gn gen out/Debug --args='target_os="android" target_cpu="arm"'
ninja -C out/Debug AppRTCMobile
/<code>

最後生成的apk位於out/Debug/apks/AppRTCMobile.apk參考官方文檔:https://webrtc.googlesource.com/src/+/master/examples/androidapp/README

打包 aar 文件

WebRTC提供了一個腳本工具可以直接構建一個安卓 aar 的文件,我們直接用這個就可以了。

<code>cd webrtc_android/src
tools_webrtc/android/build_aar.py --build-dir out --arch "armeabi-v7a" "arm64-v8a"
/<code>

–build-dir out指定輸出目錄,如果不指定會在系統臨時目錄下創建–arch “armeabi-v7a” “arm64-v8a” 指定兩種cpu架構,相當於gn命令中的target_cpu="arm"和target_cpu=“arm64”。對每一種cpu架構會創建一個編譯目錄,依次執行gn和ninja命令。

最後將生成的jar和so打包成了aar文件,aar文件位於webrtc_android/src/libwebrtc.aar

編好了 aar 文件後,可以拷貝到 mac 下使用了,在 Android Studio 中可以替換預編譯的 dependency

implementation ‘org.webrtc:google-webrtc:1.0.+’如何替換可以參考安卓官方文檔:https://developer.android.com/studio/projects/android-library#AddDependency

Android Studio

不推薦使用官網提供的方法

按照這個方法是無法編譯成功的,缺少一些步驟,需要手動調整,而且使用generate_gradle.py生成的 gradle 項目比較詭異。

推薦方法

直接將 src/examples/androidapp/ 目錄下的代碼導入到 Android Studio 中,導入後生成的gradle文件也不太完整,可以參考 src/examples/aarproject 中的 gradle 文件來補全。

注意 src/examples/androidapp/third_part/autobanh/lib/autobanh.jar 文件需要拷貝到 libs 目錄下。

以下是 build.gradle 文件內容,供參考

<code>apply plugin: 'com.android.application'

android {
compileSdkVersion 27
buildToolsVersion "27.0.3"

defaultConfig {
applicationId "org.appspot.apprtc"
minSdkVersion 16
targetSdkVersion 21
versionCode 1
versionName "1.0"
testApplicationId "org.appspot.apprtc.test"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.google.code.findbugs:jsr305:3.0.2'
implementation 'org.webrtc:google-webrtc:1.0.+'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
/<code>

原創作者:無貓皆籠,原文鏈接:https://www.jianshu.com/p/e0239bb43f48

歡迎關注我的微信公眾號「碼農突圍」,分享Python、Java、大數據、機器學習、人工智能等技術,關注碼農技術提升•職場突圍•思維躍遷,20萬+碼農成長充電第一站,陪有夢想的你一起成長。