最近 めるぽん と一緒にバーチャルライバー向け配信システムを作っています。といっても自分は開発とか一切せずに横から口を出すだけのめんどくさい人をやっています。
開発経緯
もともとバーチャルライバー自体には興味はないんですが、配信はどうやるんだろう?って調べていたりしました。単にバーチャルライバー向けの超低遅延な配信システムを作ったら欲しい人がいるのでは?くらいのモチベーションです。
色々調べてみると殆どが HLS/MPEG-DASH による配信で、遅延も大きくなんてコレは作れば何かしら興味持ってもらえるかも?と思っていたところ IRIAM の中の人から誘われて配信システムの設計を手伝うことになりました。
IRIAM は超低遅延が売りのサービスということで、そっち優先で設計しました。このとき めるぽん にクライアント側の開発を手伝いをしてもらったりしました。
で、結果的に IRIAM の配信システムはとてもうまく動いて、評判もよく、超低遅延も実現できて良かったのですが、そもそも興味がなさすぎたことや IRIAM がうまく言ったので満足したということもあり、自社製品を作るのは諦めることにしました。
そんなとき、またバーチャルライバー配信のお手伝いすることがあって、結局似たようなものを設計しました。そしてまためるぽんに同じようなものを作ってもらいました … 。うーん、であれば自分のアイデアやノウハウをめるぽんにあげて、彼が自社製品として作ったらいいのではないだろうか?と思い、めるぽんに打診したところ興味はあるし作ってみるという話になりました。
最初の開発
当たり前ですが今までお客様に提供した技術をそのままは使えません。ということで、いかに楽をするか、いかにめるぽんの C++ 力とビルド力を活用するかという事を前提にすることにしました。
gRPC
その結果プロトコルには gRPC を利用することにしました。もともと興味はあったのですが HTTP/2 ベースということや、Google がガッツリ使っておりネットワーク周りのチューニングがされていることが理由です。
また UDP ベースのプロトコルはしんどいので、 TCP ベースにしたいと思っていたのもあります。
そこで gRPC を使ったバーチャルライバー向け配信システムにしました。もともとめるぽんは SCTP over UDP を使おうとしてましたが全力で止めました。
Opus
バーチャルライバーであれば音声大事、ということで音声は WebRTC の標準コーデックでもある Opus を選定しました。単に自分が知ってるからです。
音声とデータを gRPC で配信できるサーバは C++ でカリッカリに書いてもらうことにしました。ココが差別化ポイントです。
Unity
Unity で iOS/Android/Windows/macOS 向けの 向けの SDK を作る必要があります。理由は Opus がネイティブライブラリであること、Unity gRPC binding も C++ だからです。
ここはめるぽんのビルド力を発揮してもらうことにしました。
視聴者との双方向を捨てる
じつはリアルタイムの双方向が一番やっかいです。むしろだからこそ WebRTC があるんですよね … 。
ということで視聴者との双方向は捨てることにしました。バーチャルライバー同士のコラボ配信については後で書いてあるのでそちらを読んでください。
gRPC という TCP/IP ベースのプロトコルに乗っかっている以上はそもそも不安定な回線に弱いです、あたりまえですが HoL Blocking が発生します。
なので、一方向やバーチャルライバー同士に特化させることにしました。
コメントやギフト
コメントは gRPC 経由で配信可能な仕組みを提供します。さらにギフトも HTTP API を用意することでそこから好きなデータを指定したルームに配信可能な仕組みを提供することにしました。
結果
そしてできたのが gRPC を利用した音声とモーションデータを 1:10000 に超低遅延で配信可能な Wata です。まだ SDK は用意されていませんが macOS と Windows で動作します。
リアルタイム文字起こし
音声がリアルタイムに文字起こしされるという便利さを pixiv Sketch LIVE で学んだ自分はせっかく C++ で gRPC なのであれば Google の Cloud Speech-to-Text をサーバ側で処理して、送ってしまう仕組みはどうか?と考え、実装してもらうことにしました。
結果は大成功でした。
これでバーチャルライバーが配信しているときの声をリアルタイムで文字起こししてくれるようになります。コレに Google Translate を組み合わせれば … 色々楽しい感じですよね。
映像配信
音声とモーションを利用した配信の最大の欠点ってブラウザに配信できないことです。頑張ればできるんですがモデルデータをどうやって保護するのかなど色々めんどくさいことがあるんですよね。
さらに音声と映像で配信したいって人もいるのではないかと考え、 RTMP での配信を受け取れるようにしてもらうことにしました。
よくあるバーチャルライバーの配信である HLS/MPEG-DASH 方式と違うのは CDN を一切利用せず、プッシュ方式で Wata がクライアントに配信するという仕組みです。そのためかなり低遅延になります。
これは 1:10000 を実現できる Wata ならではの仕組みです。
これで RTMP をWata で経由で、多くのクライアントに直接配信できます。
経路としてはバーチャルライバーが OBS などを利用して RTMP で Wata に配信し、Wata は gRPC で視聴者に送ります。配信に gRPC を利用してるのがポイントです。
gRPC-Web と WASM な H.264 / mp3 デコーダを利用したブラウザへの映像配信
Wata とブラウザの間に Envoy を起き、 gRPC-Web を利用してブラウザに RTMP で送られてきた映像と音声を配信します。そして WASM な H.264/mp3 デコーダを利用し Canvas / WebAudio を利用して表示するという仕組みです。
この仕組自体は特に珍しいものではなく、会議システムやオンラインクレーンゲームに使われていたりします。
クライアント側は「音声とモーションデータ」と「音声と映像」を配信することで、アプリにもブラウザにも配信できます。
ブラウザへの映像配信は視聴者を気軽に増やせるという点で実は結構魅力なんです。「コメントやギフトを送りたい場合はアプリをインストールしてくさだし」という動線も用意できます。
SRT への対応
ただ、RTMP はまぁそんなに素敵なプロトコルではないということもあり、この分野では今後 SRT が主力になる可能性があると思っています。
特にスマホからの配信に関しては間違いないでしょう。OBS も頑張ったりしているようです。
バーチャルライバーは SRT で Wata に音声と映像を送り、 Wata は gRPC で視聴者に送るという仕組みになります。
コラボ配信への対応
配信側は SRT で対応できると考えています。ルームの仕組みを使って双方向はすべて SRT で流していけばいいかなと。配信側はアプリや OBS 前提でいいので、気が楽です。
実際は SRT の Unity クライアントが必要になると思いますが、そこはやっていければと思っています。
まとめ
一方通行なリアルタイム配信を gRPC を利用してどこまで頑張れるか、というチャレンジになります。
売り方としてはパッケージ提供で年間でいくらで使い放題みたいな感じで考えています。Unity SDK も込みです。
最後に Wata を支える技術をまとめました。
- C++
- gRPC
- Opus
- Unity
- RTMP
- SRT
- WASM
- Google Cloud Speech To Text API
- Google Translate API
この製品に興味ある人は是非 melpon at wandbox.org までご連絡ください。かなり攻めてる感じで作っていきます。
進捗は以下のブログで読めますので是非。