sora-unity-sdkがAndroidに正式対応したらしいのでサンプルを動かしてみた

![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/a9bb7360-a084-8af0-683f-05e2d7179900.gif)

株式会社時雨堂様が提供してくださっているsora-unity-sdkがAndroidに正式に対応したらしいので、サンプルを動かしてみました。

試した環境

sora-unity-sdk 2020.5

PC
Windows10
Unity2019.1.14f1

スマホ
Android10
Motog8

#1.サンプルの入手
GitHubから入手。
https://github.com/shiguredo/sora-unity-sdk-samples

READMEに依ると

>
sora-unity-sdk のインストール
Windows の場合は install.bat を、macOS の場合は install.sh を実行して下さい。 これで各種サンプルを実行するために必要になる sora-unity-sdk をインストールできます。

とのことなので`install.bat`を実行します。しかしこの実行ファイルの中身を見てみると`sora-unity-sdk v2020.4`をインストールする設定になっているようです。今回、試したいのは`2020.5`だったので`install.ps1`の$SORAUNITYSDK_VERSIONを修正します。

```.sh:install.ps1

$SORAUNITYSDK_VERSION = "2020.5"

```

修正した上でコマンドプロンプトで`install.bat`を実行して、`sora-unity-sdk v2020.5`をプロジェクトにインストールします。

<img width="600" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/591a7102-5f2b-a499-e65f-24b69ee0f080.png">

#2.Sora Laboを使うように設定
とりあえず動かしてみたいので、時雨堂様が提供してくださっている`Sora Labo`を利用します。検証目的なら無償で利用できますが、商用利用はできないようです。簡単な利用規約があるのでよく確認してから利用しましょう。今回は検証目的なので大丈夫です。
https://sora-labo.shiguredo.jp/
<img width="600" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/60a95d29-534b-cdad-4704-5c1fb47c42b2.png">

サインアップしてログインしたらUnityに戻って設定していきます。

適当なサンプルシーンを開きます。今回は`multi_sendrecv`にします。
<img width="600" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/5366329e-e37f-3928-6a00-69f5da9d8af9.png">


Scriptというオブジェクトにアタッチされている`Sora Sampleコンポーネント`にSora Laboに接続するための設定を記入していきます。

Sora Laboのダッシュボードに記述してある`シグナリングURL`, `シグナリングキー`をコピペしてUnityの`Sora Sampleコンポーネント`に貼り付けます。

<img width="600" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/b60c1a14-d80a-004e-4819-d95d57990512.png">

次に`Channel Id`を設定します。[sora-laboのドキュメント](https://github.com/shiguredo/sora-labo-doc)に依ると

>
チャネル ID を <自分の GitHub Username>@<好きな Room ID> のように指定してください

とのことなので適当に設定します。ここでは便宜上`<GITHUB_USERNAME>@sora-labo`とします。

また、今回はUnityのカメラを送受信したいので、`Capture Unity Camera`のチェックを入れます。

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/a75beb0c-a689-2e0e-075d-29cbafdb5611.png">

ここまでの設定でUnity Editor上で挙動を確認できるようになったはずです。Sora Laboに`マルチストリーム受信`というページがあるので、そこから確認してみます。Unityカメラの映像がブラウザから確認できるはずです。

<img width="600" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/eb8d0389-0a42-5d3e-5d23-d1a13ff91fb0.png">

#3.Androidで確認できるように設定
Android向けにビルドして実機で確認できるように設定していきます。まずビルドターゲットをAndroidに変更します。

[sora-unity-sdkのドキュメントによると](https://github.com/shiguredo/sora-unity-sdk/blob/develop/doc/ANDROID.md)

>
* arm64-v8a のライブラリしか入れていないので armeabi-v7a の端末では動きません。
    * libSoraUnitySdk.so のインスペクタ -> Platform settings -> Android の設定で CPU が ARM64 になっていることを確認して下さい。
    * Player Settings -> Other Settings -> Target Architectures で ARM64 にチェックが入っていることを確認して下さい。
* Vulkan で動かす必要があります。
    * Player Settings -> Other Settings の Graphics APIs で Vulkan が先頭にあることを確認して下さい。
* OpenGLES モードでの動作は未確認です。
* 最低でも API LEVEL 24 （Android 7.0）が必要です。
* Pixel 3 で解像度が 16 の倍数じゃない時に映像が乱れる問題があります。

とのことなので、書いてある通りに設定していきます。

まず`Assets\Plugins\SoraUnitySdk\android\arm64-v8a\libSoraUnitySdk.so`のTarget ArchitecturesをARM64に変更します。変更したら忘れずにApplyしましょう。

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/398ba620-4837-3cf7-0b55-0dfcaf3e0a46.png">

次にPlayer Settingsの設定を変更していきます。Other SettingsのTarget ArchitecturesをARM64に。Graphics APIsのAuto Graphics APIのチェックをはずしてVulkanに設定します。さらにMinimum API LevelをAPI LEVEL 24にしておきましょう。

<img width="600" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/57c750a7-eed0-d199-263b-c504a15462cd.png">

#4.オブジェクトが映らない問題

一応、以上で設定はできたはずなんですが、私の環境だと問題が発生しました。Unityのカメラにオブジェクトが映らないという問題です。

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/d6ff5425-d046-3d6d-57fd-a15e8446e242.jpeg">

本来なら球体が映らはずだけど、映らない。この問題はAndroidの実機だけじゃなくてUnity Editor上でも発生しました。

結論から言うと、Project Settings->Graphics->Tier SettingsのUser DafaultsのチェックをはずしてUSE HDRのチェックを入れると解決します。

<img width="600" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/1b9be4e4-4d29-ab16-1f49-63e7ae2963e3.png">

この問題が起こった理由は特定できていませんが、検証してみた結果、ShaderのRenderTargetがOpaqueのオブジェクトが映らないという症状のようです。RenderTargetを`Transparent`にすると映るようになりました。まだBuild Settingsで対象プラットフォームをPCにしても治るようです。たぶんVulkan関連の何かが原因な気がします。

何か必要な設定を忘れていたのか、自分の実行環境の問題なのか、よく分かりません。

なんか描画順とか、Unityのカメラをキャプチャしてテクスチャにする処理とかに何かヒントがある気がします。WaitForEndOfFrameのタイミングでUnityのカメラの映像をVulkanを直接叩いてキャプチャするっていう実装になっているようなんですが、これでなんで映らないのか謎です。[WaitForEndOfFrameは描画系の処理の最後に実行される](https://docs.unity3d.com/ja/2018.4/Manual/ExecutionOrder.html)ようなので、キャプチャするタイミングとしては適切な気がします。

原因を探るならたぶんこの辺のキャプチャする仕組みがどうなってるのか見る必要がある気がするんですが、Vulkanとか低レイヤーのことは門外漢なので、私にはよく分からなかったです。今回はとりあえずUSE HDRのチェックを入れたら写ったので良しとしました。
https://github.com/shiguredo/sora-unity-sdk/blob/develop/src/unity_camera_capturer_vulkan.cpp

#5.結果
ということでsora-unity-sdkをAndroidで使うことができました。

![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101808/a9bb7360-a084-8af0-683f-05e2d7179900.gif)

使っているスマホはMotog8というローエンド端末なんですが、想像以上にヌルヌル動きます。遅延もほとんどないと言っていいんじゃないでしょうか。すごいですね。

#6.最後に

先日、[NDI SDKをAndroidで使うっていう記事](https://qiita.com/stupid_student2/items/ccef2a52277334de2072)を書きました。NDIはローカルネットワーク上で映像や音声の送信を行うのに対してsora-unity-sdkはSoraを介してどこからでもアクセスできます。

またNDI SDKのAndroid実装は送信にしか対応してませんでしたが、こちらは送信も受信もできます。ただSoraを商用利用するにはお金がかかります。(NDI SDKは無料だったはず) 

NDIもWebRTCも使うなら、表面的な理解だけでは駄目で、チューニングして軽量化したりする必要がありますね。

# 追記
特定のオブジェクトが映らない問題は修正されたようです。
https://github.com/shiguredo/sora-unity-sdk/commit/417477dca1532474703c16d1f271f08979d4ffb5