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にはWindowsAndroidが対象と書かれていますが、今回の記事はインストラクションが存在する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
    • depot_tools : 各種ビルドツールです。パスを通しておきます。
    • webrtc
      • .gcloud : gcloud用の設定ファイルです。OS種別などを記述します。
      • src : webrtcライブラリのソースです。git管理されています。
        • out : ビルド結果ディレクトリです。
          • Android : Androidのビルド結果です。今回のライブラリ等もこの下にできます。

スクリプト

お待ちかね、上記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リリースの作成が行われると思います。

参考ページ

追記

後編で使い方を書きましたのでリンクしておきます。(2018/4/26) hammmm.hatenablog.com