DMMグループの一番深くておもしろいトコロ。
テクノロジー

WebRTCを利用した超低遅延な映像配信

DMMグループの一番深くておもしろいトコロ。

はじめに

こんにちは。ライブコミュニケーション事業部 2.0スクラムチームの菊池です。 現在稼働しているライブ配信サービスのFlashからWebRTCへのリプレイスを行っています。 主にバックエンドを担当しています。
今回はなぜWebRTCを選択したのか、また開発における苦労などのお話をさせていただきます。

2.0スクラムチームについてはこちらinside.dmm.com

なぜFlash -> WebRTCにしたのか

Flashからほかの技術へ置き換えるならば、候補になるのは視聴側であれば、以下の3つでしょうか。

  • HLS(HTTP Live Streaming)
  • WebRTC
  • MPEG-DASH ※対応ブラウザが少ない

MPEG-DASHに関しては、現状対応ブラウザが少ないので現実的ではないでしょう。その上で配信側は外部ツールを使ずブラウザのみで完結させるのであればWebRTC一択という結論になりました。 なので配信→視聴の組み合わせ的に以下のどちらかになるでしょう。

  • WebRTC -> HLS
  • WebRTC -> WebRTC

何を採用するべきかは、サービスの性質によって変わってきます。
例えば、YouTubeのライブ配信では最低数秒の遅延があります。
YouTubeのように一人のユーザーが多数のユーザーに映像を一方向的に配信する形式では、数秒ほどの遅延なら視聴者はほとんどそれを意識せずに配信を楽しむことができるでしょう。
また、ユーザー方向からのアクションとしてテキストチャットを送ることができます。
このときユーザーは、配信者のリアクションで遅延があることに気づきますが、テキストチャットの場合、ほとんど問題にならないでしょう。

しかし、今回リプレイスするサービスでは配信者と視聴者が双方向に映像と音声を送り合ってビデオチャットする機能があります。
そうなった場合、許される遅延は「1秒未満」と考えています。
音声による会話だと、遅延が数秒あるだけでものすごい不便さを感じてしまいます。

YouTubeなどのライブ配信サービスはHLSを使用しています。
HLSでは、配信側のクライアントから送られてきた映像をサーバで数秒の動画ファイルに分割します。
この数秒の動画ファイルをwebサーバーに配置し、クライアントにpullさせる方式です。

HLSを採用する場合のメリットはCDNを利用できること。 ダウンロードした分に関しては映像が止まったりせずにスムーズに再生できます。 また動画ファイルをすぐに破棄せずに保持しておけば過去にさかのぼって配信を視聴することも可能になります。
一方、デメリットは遅延です。
私自身がほかのサービスでHLSを採用したケースでは、遅延がどうしても5〜6秒ぐらいは出てしまいました。
チューニング次第ではもっと短くできますが、「1秒未満」というのは難しいです。

そこで今回のプロジェクトではWebRTCを採用することになりました。
UDPベースで直接映像を視聴クライアントに直接送信する方式のWebRTCでは、「超低遅延な映像配信」が可能になります。
ただし、回線の品質などの影響をもろに受けるのでHLSに比べて安定性という面では劣ってしまいます。

WebRTC.org

ですので、数秒の遅延が許されるのならばHLSの採用を検討するべきです。

SFUによる配信側の負荷軽減

WebRTCのシンプルな構成では、単にクライアント同士が直接コネクションを張って通信します。

しかし、視聴クライアントが多くなると、そのすべてとコネクションを張らなければならない配信側の負荷が上がってしまう。 今回のサービスでは1つのチャンネルを数十から数百のユーザーが一度に視聴する場合があるので、この状態ではサービスを提供できません。

配信側クライアントの負荷を軽減するために SFU(Selective Forwarding Unit )という仕組みがあります。 簡単に説明すると映像や音声のやり取りをサーバー経由で行います。

WebRTCをサーバー経由して使用することによって視聴側も配信側もすべてのクライアントがサーバーとの単一のコネクションを持てば良いことになるので、視聴クライアントが増えても配信クライアントの負荷は上がりません。

また他にも、SFUを使用すればサーバ側で映像の録画ができたり、認証機能を付けたりできるようにもなるメリットがあります。

サイマルキャストによる複数画質の配信

様々な環境のユーザーに対して安定したサービスの提供をするためには、視聴側に視聴画質を選択できるようにしたほうが親切です。 遅い回線なら画質の低い映像を受信してスムーズに視聴し、速い回線なら画質の高い映像を視聴できるからです。

WebRTCでは、複数の画質の映像を提供する方法としてサイマルキャストがあります。 配信クライアントから複数の画質の映像を配信するもので、サーバーで処理をして映像を分けるのではなく初めから配信側で複数の映像を同時に送信する点がポイントです。 そのため、配信側で単一の画質の映像を配信する時に比べて負荷が上がってしまうという問題があります。 今回のプロジェクトでは、このサイマルキャストはいったん見送ることにしました。

コーデックの選択

コーデックとは映像をエンコードする時のアルゴリズムを指します。 どのコーデックを使用して映像をエンコードするかでも画質やクライアントの負荷が変わってきます。大抵の場合、候補として上がってくるのが以下の3つでしょう。

  • VP8 容量はそんなに節約できない。いまさら採用するメリットはないかも。
  • VP9 容量がかなり節約できるが、CPU負荷高め。
  • H264 対応ブラウザ多い。

それぞれで対応するブラウザなどが変わってくるので、どのブラウザをサポートしてどのブラウザをサポートしないのかなどで採用するコーデックが変わってきます。

地味な画質のチューニング

リプレイスに際して、画質の見直しも行われました。
既存システムが作られてから15年ほど経っているので、「高画質」という言葉の意味もだいぶ変わっています。 かといって、何も考えずに高画質にしようとすると動画が重くなってしまうので、画像の大きさやフレームレートを調整してビットレートをどこまでさげられるのかといった地味なチューニングを行うことになります。
数値ではわからない感性的な品質なので、少しずつ値を変えていって見た目を比較していく作業が必要になります。
動きの大きい場合と小さい場合で圧縮率が変わり、動くとノイズは大きくなります。
仮に止まったままだと正しく品質を判定できないので、カメラに向かってずっと手をふっていたりする必要があります。
これが結構疲れます。
サービスの性質上、動きが多いか少ないかで適切な値が結構変わってくるのではないでしょうか。

「おっ、案外きれいだ!」
「あれ……」
「動いたらだめだー!」

 

監視の回線とマシンスペック

サービスの運用業務の1つに配信の監視があります。 ルールに違反している配信を即座に停止し、警告を出すという業務です。 監視クライアントでは一度に何十もの映像を同時に表示しなければならないのですが、配信側の負荷を考えてサイマルキャストをしないという方針をとったため、監視クライアントもユーザーと同じ画質の映像を受信しなければならなくなってしまいました。

そのため、監視をするためのPCの要求スペックがとても高くなってしまいました。 実機での検証ではGPUの有無、ブラウザの種類等の条件を変えて映像のカクつきやユーザー側の視聴クライアントとの遅延の差を比較していきました。

検証でわかったのは、ChromeではGPUを使ってCPUの負荷を抑えてくれています。 一方、FirefoxではGPUを全然使ってくれないということでした。
同じPCを使ってもFirefoxとChromeでは2倍ぐらいの差がありました。

監視のために結構高いGPUを積んだPCを採用しようとしています。
開発に使っているPCよりもハイスペックで羨ましいです。

さらに、コストが高くなってしまうのはPC本体の価格だけではありませんでした。
ネット回線の費用がとんでもなく高額になってしまったのです。
そこで考えたのが、VDIを使えば監視に使用する回線を節約できるのではないかということです。 しかし、試しにVDIのサービスを利用して検証してみたところ、手ごろな値段で要求に見合うスペックのVDIを提供しているサービスがなく、この案は不採用になりました(結構いいアイディアだと思っていたのですが)。

その他いろいろな問題

ブラウザのバージョンアップが怖い話

ブラウザのバージョンアップ後に動かなくなってしまうことが結構あったりします。

仮想カメラが使えない話

仮想カメラアプリケーションが使えない不具合に遭遇したWindowsのFirefox。 デバイスの順番によっても影響があるので、外部カメラをもう一台つなぐと回避できたりします。 WebRTCのテストサイトもうまく動作しないです。 Firefoxの不具合らしいのですが、これって解消されるのでしょうか(執筆時点でのバージョンは67.0)。

負荷分散が大変そうな話

視聴クライアントとサーバーとの接続が張りっぱなしになるので、負荷分散が難しいですよね(HLSだったらとても楽なのですが)。 配信を開始するときにどのSFUのサーバーを使用するかを選択するのですが、人気の配信者だと多くの視聴者が集まって負荷が高くなります。 誰が人気の配信者なのかを覚えておいて、同じサーバーに固まらないようにするなどの工夫が必要なのかなと考えたりもします。

最後に

というわけで、あれこれ書きましたが、リプレイス作業は現在も真っ只中で進行中です。ここで挙げたものはごく一部のものでさまざまな問題とぶつかっていますが、仮に皆さんがWebRTCの開発をする際は、せひ参考にしていただけたらうれしいです。

dmm-corp.com

シェア

関連する記事

関連する求人