WebRTC Unity Pluginサンプルをビルドする方法 (Android向け)
はじめに
あまり話題にはなっていませんが、本家webrtcライブラリのソースコードには、2017/5月ごろからひっそりとunity pluginのサンプルが入っています。しかし残念ながら、自分が探した限りでは、これをビルドしたライブラリのバイナリ配布や、それを使うUnityプロジェクトは公開されていません。
そこで、この使い方を模索していきます。 今回はひとまずこれをビルドする方法です。
1行で
Android向けのビルド済みライブラリファイルが以下のリンク先にあるのでダウンロードして頂けると良いと思います。詳しい使い方は調査中でもあり、また次回に。
https://github.com/mhama/webrtc-dev-env/releases
まあ、それだけでは味気ないと思うので、細かいことを書いていきます。
Unity Pluginサンプルとは?
こちらのディレクトリに存在するサンプルです。UnityのC#からWebRTCが利用できそうな内容になっています。サンプルといってもライブラリ側のみです。使う方法はサンプルもなく、任されています。
https://chromium.googlesource.com/external/webrtc/+/master/examples/unityplugin/
Android向けのインストラクションがこちらにありますが、ビルドの仕組みに関してだいぶ高い理解度を要する印象です。今回の記事は、基本的にはこの内容に従っています。
https://chromium.googlesource.com/external/webrtc/+/master/examples/unityplugin/ANDROID_INSTRUCTION
以下のREADMEには、PeerConnectionMという、C#側からネイティブのライブラリ機能を利用するクラスのサンプルコード が掲載されています。
https://chromium.googlesource.com/external/webrtc/+/master/examples/unityplugin/README
構成としては、以下のような形になっており、C言語定義の関数を通じてWebRTCのAPIに間接的にアクセスする形になっています。
C++ libwebrtcライブラリ本体 ↕ C++ simple_peerconnection (クラス) ↕ C++ unity_plugin_api (C関数定義) ↑ ここまでが webrtcライブラリ (libjingle_peerconnection_so.so) ---------------------- ↓ ここからがUnity Assets内 C# SimplePeerConnectionM (クラス) ↕ Unity 任意のスクリプト
動作環境
READMEにはWindowsとAndroidが対象と書かれていますが、今回の記事はインストラクションが存在するAndroidをターゲットとします。
どのバージョンをビルドするか?
webrtcライブラリのソースコードは変化が早いです。それに対して、unity pluginライブラリ部分が変化に対応できておらず、最新のソースだとそれなりに修正しないとビルドできなさそうな感じでした。このため、現状では、「適切なバージョン」を選択してビルドする必要があります。
今回は、Unity Plugin関連の修正Commitが入ったこちらのタイミングを利用してビルドを行います。 https://chromium.googlesource.com/external/webrtc/+/51e2046dbcbbb0375c383594aa4f77aa8ed67b06
バグ解消のCommitが入って最新ソースでちゃんとビルドできるようになると嬉しいですね。
ビルド環境
Dockerを利用して、ある程度必須ライブラリがインストールされたイメージを起点にします。Dockerが利用できるプラットフォームであれば大丈夫です。
Dockerイメージ
mhama/webrtc-dev-env-java8 というイメージをスタートポイントにします。 (java8が入っているものがなかったので調整してDockerHubに登録しました)
ビルドの基本
WebRTCライブラリは、もともとchromiumのソースコードから派生した関係で、chromiumビルド用のツールセットによるビルドとなっています。このためfetch, gclient, ninja, gnなど慣れないコマンドが多いかとは思います。
chromium系ビルド用語
depot_tools
fetchなどを含む、ビルド用のツールが入ったリポジトリです。
fetch
初期ソースコードを取得してくるツールです。途中で失敗した場合はディレクトリ削除してやりなおす必要があります。ちなみに、バージョン指定してソースコードを取得する方法は結局わかりませんでした。
gclient
正確にはわかりませんが、依存ライブラリなどを引っ張ってくるようです。
gn
ninjaのビルドファイルを生成してくれるようです。 Makefileを作ってくれるCMakeとかconfigureみたいな感じでしょうか。
ninja
ビルドツールで、Makeのようなものです。速いらしいです。
ビルド手順
docker起動
dockerから上記イメージでコンテナを起動し、その中で作業します。
Kitematic (GUIツール)の場合
Kitematicで webrtc-dev-env-java8 イメージを探して起動してください。EXECというボタンからシェルを出してスクリプトを実行してください。
コマンドラインの場合
# -itでターミナルを有効にする。-dオプションをつけて、シェルを抜けてもすぐに停止しないようにする docker run -itd mhamanaka/webrtc-dev-env-java8 /bin/bash
ビルド時のフォルダ構成
- /home/root
スクリプト
お待ちかね、上記dockerイメージを起点として一発でビルドできるスクリプトが以下です! ただし!一回Google Playライブラリのところでライセンスへの承認を求められるので、Y [改行] を入力する必要があります。
# depot-toolsをインストール git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git export PATH=$PATH:`pwd`/depot_tools # ソースコードを取得 mkdir webrtc cd webrtc fetch --nohooks webrtc # ..... 結構時間かかります。 # ソースコードを特定バージョンに切り替えます cd src git checkout 51e2046db cd .. # 依存関係を解決します。 echo "target_os = [ 'android' ]" >> .gclient gclient sync # ... まあまあ時間かかります。 # ここでGooglePlayのライセンスのため、 Y [改行] の入力が必要です。 # エクスポート対象をいじります。 cd src echo '{ global: *; };' > build/android/android_only_jni_exports.lst echo '{ global: *; };' > build/android/android_only_explicit_jni_exports.lst # 対象環境向けのninjaビルドファイルを生成します。 gn gen out/Android --args='target_os="android" target_cpu="arm"' # ライブラリ本体(.so)をビルドします。 ninja -C out/Android webrtc_unity_plugin # .... そこそこ時間かかります。 # できたライブラリファイルを、名前を変えつつ ~/webrtc 以下にコピーしておきます。 cp out/Android/libwebrtc_unity_plugin.so ../libjingle_peerconnection_so.so # javaライブラリをビルドします。 ninja -C out/Android libwebrtc_unity # ... ちょっと待ちます。 # できたjarファイルを、 ~/webrtc 以下にコピーしておきます。 cp out/Android/lib.java/examples/libwebrtc_unity.jar ../. cd ..
- さらに細かい問題に対処して自動化したバージョンは以下の場所にあります。
- Google Playライブラリのライセンス確認入力回避
- tarコマンドでの展開時にCannot change ownershipのようなエラーがたくさん出る問題への対処
などを追加しています。
https://github.com/mhama/webrtc-dev-env/blob/master/build-webrtc-unity.sh
生成したライブラリファイルをdockerから外に出す
さらに、dockerの外のホストOS側から、以下みたいにして出力ファイルをローカル環境に持ってきましょう。dockerコンテナ名はcontainer_nameであるの場合のコマンドです。 docker ps
でコンテナ名を確認してください。
docker cp container_name:/home/root/webrtc/libwebrtc_unity.jar . docker cp container_name:/home/root/webrtc/libjingle_peerconnection_so.so .
以上!この2つのファイルをUnityから利用しますが、それは次回に。
それと、上記方法で「正常に動作する」ライブラリが作成できている保証はありません。ただ一定程度動作しているように見えるところまでは確認しています。
CircleCIによるライブラリビルドの自動化
今回のライブラリ作成プロセスを、CircleCIを利用して自動化できます。フリープランでも動作すると思います。結構なサイズのダウンロードを行うので無理かと思いましたが、大丈夫でした。
CircleCIの設定ファイルはこちらです。
https://github.com/mhama/webrtc-dev-env/blob/master/.circleci/config.yml
リポジトリ https://github.com/mhama/webrtc-dev-env をforkするなりしてから、CircleCIにプロジェクト追加するだけで、自動ビルドが動作すると思います。
ビルドは約30分かかるようです。待ちましょう。
後述のGitHubリリース機能の関係で、最終的に "FAILED" と出ると思いますが、Artifactsの項目を開いて2つのライブラリファイル (libjingle_peerconnection_so.so と libwebrtc_unity.jar) が存在すればビルドは実質的には成功しています。
GitHubへの自動リリース
上述の設定ファイルにはGitHubへのリリース機能があります。ただし、これを利用するにはCircleCIで、GITHUB_TOKENという環境変数に、GitHubのアクセストークンをセットする必要があります。
GitHubからのAPIアクセストークンの取得
自分のアカウントの設定画面から、 Developer settings -> Personal Access Tokens とたどります。 Generate New Tokenボタンを押すと詳細設定画面になります。適当に名前をつけて、公開リポジトリであれば public_repo にチェックをつけて、Generate Tokenボタンを押してください。そこで表示されたトークン文字列をどこかにメモしておきましょう。
GITHUB_TOKEN環境変数の設定
CircleCIのプロジェクトで前述のビルド (FAILED)まではできている前提になります。プロジェクトの画面から、右上の歯車ボタンをクリックして設定画面を出して、Environment Variables の項目をクリックしてください。Add Variableボタンを押して、
を入力して、Add Variableボタンを押して確定させてください。
あとはプロジェクトのRebuildを実行すると、GitHubリリースの作成が行われると思います。
参考ページ
ネイティブ環境向けのWebRTCライブラリビルド方法です。100%同じではないですが、大枠では共通する部分が多いです。
追記
後編で使い方を書きましたのでリンクしておきます。(2018/4/26) hammmm.hatenablog.com