こんにちは、ねこまんまです。
先日、ピクシブはWebRTCプロジェクトのフォークを公開しました。このフォークにはオリジナルのプロジェクトには含まれていないいくつかの変更が施されていますが、その中でも大きな機能追加である、WebRTCの.NETバインディングを紹介します。
このバインディングを用いることによって、Unityや.NET Framework、Monoといった.NETプラットフォームで映像や音声のライブ配信、受信が可能になります。
なぜWebRTCと.NETなのか
動画のライブ配信、受信は、高度な技術でありながら、既にインターネット上で広く普及しており、新規開発者には独創的かつ新な価値をもたらす応用が求められています。ピクシブでは、WebRTCをユーザーからサーバーへの動画転送に利用した、ImageFlux Live Streamingというサービスを開発し、さくらインターネット様で提供していただくことで、動画のライブ配信、受信を容易にし、開発者は重要なアプリケーションに固有の体験を設計、実装することに集中することを可能にしています。
一方で、アプリケーションに魅力ある体験をもたらすと注目されているフレームワークの1つとして、Unityがあります。近年、パソコンやスマートフォンのグラフィックス処理性能は格段に向上しており、Unityはより多くの人がこの能力を活用できるようにすることを目標に開発されています。
Democratize game development! - Unity Technologies ゲーム開発を民主化する!
今ではUnityはゲーム開発に留まらず、自身のアプリケーションで高度なグラフィックスを様々な媒体で提供したい開発者にとって重要な選択肢となっています。より有効な応用が求められるWebRTCと、魅力的なプラットフォームとしてのUnity。これらが合わされば、エンドユーザーに新たな価値を提供できます。
幸いなことに、Unityはその機能を多種多様な機器で活用できるようにするため、.NETプラットフォームに基づくMonoランタイムを包括的に導入しています。.NETプラットフォームはMicrosoft Windowsを起点としながらも、現在では著名なモバイルアプリ開発環境であるXamarinに導入されており、.NET向けに書かれたプログラムはそのような環境でも動作させることが可能です。今回、WebRTCの能力を.NETにもたらすことで、Unityはもちろん、Windowsに含まれる.NET FrameworkやXamarin、Monoにも潜在的な活用の幅を広げました。
あらゆる制約を排した設計
これまでにも.NETないしUnityでWebRTCを利用する事例はありました。例えば、最近ではUnity Technologies社がUnity Render Streamingを、将来的なロードマップを含めて公開しています。 しかしながら、WebRTCの多機能さ故に、このような先行事例では一部の機能のみが選択され、また利用可能な媒体も制限されました。例えば、現時点ではUnity Render Streamingは配信側の実装に限定されており、NVIDIAのハードウェアエンコーダーを搭載したコンピュータでWindowsを動作させる必要があります。
今回公開した.NETバインディングの設計では、こういった制約を排することに最大限の注意が払われています。この.NETバインディングにはWebRTCで映像と音声を配信、受信するのに十分な機能が提供されており、更に必要があればWebRTCを直接操作できるC++で拡張可能なAPIを実装しています。利用可能な媒体はUnityとWebRTCの両方でサポートされているもの全て、具体的にはWindows (x64), Linux (x64), Android (ARM, AArch64), iOS (ARM, AArch64, x64), macOS (x64) に対応しています。入出力も自由に扱えるように設計されており、例えばUnityのシーン上にWebRTCで配信するための専用のカメラを用意して、特定の視点から撮影するといったことや、3Dのオブジェクトに受信した映像を写したテクスチャを貼りつけるといったことも可能です。これによりUnityの表現力を最大限に発揮できます。
導入するには
サーバー WebRTCをアプリケーションに導入する最初の一歩は、必要なサーバーを導入するところから始まります。サーバーは、最低限必要なピア間での相互接続を確立するシグナリングやICE、それに加えて配信を中継するルーティング、動画を合成するミキシングといった機能を提供します。ImageFlux Live Streamingの場合、ユニークな機能として大規模配信に向けて、WebRTCでユーザーから受け取った動画をHLS形式に変換して配信する機能があります。 こういった機能の中から必要なものを選び、サーバーを選定、あるいは実装する必要があります。
Unityプロジェクトへの導入 いざ準備が整ったら、Unityプロジェクトへの導入を行います。GitHub Releasesでビルド済みのUnityパッケージを配布しているので、こちらを利用することができます。
Releases · pixiv/webrtc https://github.com/pixiv/webrtc/releases
このパッケージは、アセットパッケージではなく、新しいUnityパッケージフォーマットになっています。追加するには、com.pixiv.webrtc.tgzをダウンロードし、com.pixiv.webrtcパッケージとして、Unityのドキュメントに従って追加します。
https://docs.unity3d.com/Manual/upm-localpath.html
例えば、Unityプロジェクトの直下 (AssetsやLibraryといったフォルダがあるフォルダ) に com.pixiv.webrtc.tgzとして保存したとき、Packages/manifest.json に次のように記述します。
{ "dependencies": { "com.pixiv.webrtc": "file:../com.pixiv.webrtc.tgz" } }
ビルドの設定を変更したい、ソースコードに変更を加えたいといった場合には自身でビルドすることも可能です。リリースに用いたビルド手順はREADME.pixiv.mdに記載されています。
シグナリングの実装 WebRTCの導入で最も困難なことはシグナリングの実装です。シグナリングとはピア間でのやりとりに必要な交渉を行うことで、開発者が自身で実装しなければなりません。
これはP2P接続を確立する前段階となり、シグナリングサーバーを介したやりとりになるので、クライアント側ではシグナリングサーバーの仕様に沿った実装が必要になります。このバインディングのAPIはWeb APIに類似しているので、既存のシグナリングサーバーの場合、Web APIを用いたクライアントのリファレンス実装があれば、これを参考に実装することができます。今回作成したフォークでは、ImageFlux Live Streamingで利用しているサーバー実装、SoraのJavaScript SDKを参考に開発したシグナリングの実装が同梱されています。
SoraのJavaScript SDK https://github.com/shiguredo/sora-js-sdk
今回作成したC#でのSoraのシグナリングの実装 https://github.com/pixiv/webrtc/tree/branch-heads/pixiv-m77/examples/unity/Assets/Sora
これらを単純に比べると差は大きいように見えますが、詳細を見ると行われている手続きは同じことが分かります。
ネイティブAPI
バインディングのAPIはネイティブAPIに沿っているため、ネイティブAPIの理解が開発に役立ちます。リポジトリに含まれるC++のヘッダファイルには、APIの詳細な説明が含まれているので、これを参考にしましょう。
また、特に注意を要するものにスマートポインタの利用があります。WebRTCのスマートポインタは受け渡されるオブジェクトを破棄すべきかどうか、また受け渡したのちに継続してオブジェクトを利用できるかを示しているので、それに従いましょう。バインディングでは、受け渡されたオブジェクトが破棄されるか (すべきか) どうかは System.IDisposable を実装しているかどうかで表されているので、IDisposableを実装するオブジェクトを受け取った場合には不要になったときに確実に Dispose メソッドが呼び出されるように注意しなければなりません。
分からない!動かない!知りたい!私ももっとよくできる!
以上で、ピクシブが製作したWebRTCの.NETバインディングについて紹介しました。ただ、この記事だけでは、実際に導入するときにどうすればよいか、問題に直面したときにどうすればよいか分からないこともあるかもしれません。また、アプリケーションにとって必要な機能 (例えば、Windowsでのハードウェアエンコーダー対応やデータチャネル対応など) の要望もあるかもしれません。そういったときには、GitHubやUnity Forumで気軽にご相談ください。GitHubではpull requestで改善も受け付けています。
https://github.com/pixiv/webrtc
https://forum.unity.com/threads/released-oss-net-bindings-for-webrtc-with-unity-package.754100/
一方で、アプリケーションがより明確な場合、このバインディングを利用せず、専用の、より簡潔なバインディングやC++側の実装を行うことも可能でしょう。そういった場合にも、このバインディングは参考になるかもしれません。その際にも、もし疑問点があればご相談ください。 関連情報の紹介 ピクシブで開発したImageFlux Live Streamingは、さくらインターネットがサービスとして提供しています。Unityに限らず、ライブ配信について課題を抱えている方はぜひお問い合わせください。
ピクシブではWebRTCやHLSなどライブストリーミングの技術にどっぷりはまってみたい方を募集しています。興味を持った方はぜひご応募ください。 【中途採用】画像配信サービス「ImageFlux」エンジニア(東京本社)の採用情報 | ピクシブ株式会社
また、UnityはVRoid MobileやVRoid Studio、VRoid SDKにおいても採用されています。これらの製品で挑戦してみたい方も積極的に募集しています。
VRoidプロジェクトで3Dの創作の未来を一緒につくるエンジニア募集 - ピクシブ株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedly