Progressive

PeerCast のブラウザ移植に向けての技術検証

2019-09-15PeerCast

WebRTC のおかげでブラウザーの中だけで P2P ができるようになってから もう随分時間が経っちゃいました。 WebRTC を使うことで PeerCast と同等のバケツリレー式動画配信システムが構築可能を 検証したところ、割となんとかなりそうだということがわかりました。 そしてアプリだけ公開してろくにREADMEも書かずに放置してて残念なことになってたので、 良い機会なので書きなぐっておくことにしました。

WebRTC ってなんやねん

ブラウザーで P2P 通信ができるやつです。もっと具体的には 通信規格とブラウザーで動く JavaScript の API 仕様のセットです。 元々はブラウザーで Skype とかそういうのをやりたいねって思惑で生まれたやつです。

WetRTC の P2P には 2 つのモードがあります。 一つがデータチャンネルという単純にデータを送るやつで、 もう一つがメディアチャンネルという Web カメラなどの動画を 良い感じに帯域チェックして良い感じにエンコして良い感じに送ってくれるやつです。

このメディアチャンネルってなかなか厄介で、動画のソースはウェブカメラや動画ファイルにしかできないし、 受け取り先はもらった動画を他人に送り付けるにはもう一度エンコする必要があり(※1)、 中継を挟むたびに動画が劣化してしまいます。 なので PeerCast のようなバケツリレーには直接使えそうにないです。

一方データチャンネルは単純にデータを指定して相手に送り付けるやつです。 そこに劣化は存在しません。その代わりエンコやら帯域チェックやらを全部自分でやる必要があります。

WebRTC は PeerCast になれるのか

なれません(おい)。 WebRTC は直接 TCP でデータをやり取りするのではなく WebRTC の中の通信規格で P2P の接続相手とデータのやり取りをします。なので TCP で独自の通信規格でデータをやり取りする PeerCast とは繋がりません。

PeerCast と直接つながることはできないものの、 WebRTC の世界に PeerCast 的なものを構築することはできます。

ブラウザーの世界で動画をリレーしてみる

まず送る動画が必要です。もちろんライブなので長さが不確定のものです(※2)。 今はもう OBS などが話す RTMP がデファクトスタンダードなのでこれを使います。 次にこの RTMP を受け取ります。実はブラウザーの世界にはまだ RTMP を直接送り付けられません。 仕方がないのでデスクトップアプリで受け取ります。 デスクトップアプリで受け取ったら、 HTTP サーバーになってブラウザーを待ち受けます。 ここにブラウザーがつないで来たら、 WebRTC で繋がって動画をデータチャンネルで送り付けます。 ここまでで、 OBS から RTMP でデスクトップアプリに動画を送り、 さらにデスクトップアプリからブラウザーへ動画を送ることができます。

ブラウザーは RTMP をちょちょいとバラすと video タグで再生できます(※3)。 そして別のブラウザーと WebRTC で繋がったら(※4)、サーバーから受け取っているデータをそのまま別のブラウザーにリレーします。

作ってみた (去年)

それを検証したのが去年3月に作ってた hitorilive です。

https://github.com/progre/hitorilive

起動すると TCP 1936 番(初期値)で OBS から RTMP を受け付けて、 TCP 17144 番(初期値)で ブラウザーからの接続を受け付けます。「P2P配信リレーを有効にする」にチェックを入れておくとリレーもできます。

当時何人かが使ってくれていてなんとなく動いてたと思います。 自分は万年弱小配信者なので大人数での検証ができずそのまま放置されました。

まだできてないこと

帯域チェックはやってないです。多分サーバーに対して定量のデータ送って時間測るくらいを作るのは何でもないと思います。

リレー管理とかはないです。構造的には必ずルートに繋がないと配信が見れないので PeerCast よりも強い管理ができそうです。

そもそもどういうリレーツリーを組むのかとかは超適当です。各ピアの最大リレーは固定だった気がしますが 1 だったか 2 だったかは最早おぼえてないです。

まとめ

出資してくださいってのは 9 割冗談で書きましたが他はマジな話です。出資じゃなくてもだれか作ってくれてもいいのよ?

※1 去年くらいに試した時点で。送り先との帯域を見てエンコ品質を決めてるっぽいのでわりと避けられなさそうだけどどうなんだろか。
※2 長さが不確定のものは MP4 にはなれないことはあれくま先生の授業を受けた皆さんならご存じですね?
※3 bilibili 動画の中の人たちが実現してます。中国人こわ。 https://github.com/Bilibili/flv.js
※4 WebRTC を使って他のブラウザーと繋がるにはサーバーが必要です。この辺りは PeerCast もルートモードが必要なので似たようなもんです。