Web上のビデオコミュニケーションの開発は意外に簡単!技術選択のポイントは?
WebRTCとストリーミング
Web上で扱えるリアルタイムなビデオコミュニケーションの技術は大きく分けて2つのものがあります。WebRTCとストリーミングです。
WebRTCの概要
WebRTCは、P2Pをベースとするコミュニケーションプロトコルで、レイテンシの低さが特徴です。ブラウザにおいては高レイヤーから低レイヤーまで包括的に実装されており、ブラウザAPIにおまかせするような実装になることが特徴です。言い換えれば、あまり細い部分の制御ができないということ。WebRTCだけではデータを保存したり、タイムシフト再生に使ったりということがしづらい仕組みになっています。低レイテンシのライブコミュニケーション専用のプロトコルだと考えると良いでしょう。
さて、WebRTCはP2Pのプロトコルではありますが、接続先を決定するためのサーバが必要であり、このサーバをSTUNサーバと言います。ただ、WebRTCがプロトコル上扱うのは、P2Pの通信だけであり、「あるルームに誰かが入室・退室」するといった機能は別に実装する必要があります(Web Socketが良く使われます)。また、多人数のコミュニケーションをしようとすると、n * (n - 1)本(双方向でそれぞれのチャンネル)のチャンネルが必要になり通信効率が悪くなります。これを解決するためには、一定人数を超える場合は、サーバに中継させる実装にすることが普通です。このサーバをSFUサーバと言います。一方、ファイアウォール等、ネットワークの問題で、P2Pでの接続ができない場合には、SFUサーバと似た機能を持つTURNサーバが使われます。
ストリーミングの概要
WebRTCとは別に、ストリーミングという技術があります。ストリーミングはレイテンシが高い代わりに、低コストで安定した通信ができるという特徴があります。ストリーミングにはさまざまな仕様のものがありますが、今から実装するのであれば、DASHとHLSの2択。それも基本的にはDASHを選ぶことになると思います。DASHもHLSも、HTTPサーバに静的ファイルを置くだけでストリーミングが可能な仕様です。
DASHのプロトコルを例に取って説明すると、DASHのライブストリーミングでは、 ファイル名-タイムスタンプ.拡張子
というようなファイルのパターンをメタデータとしてMPDファイルに書き込んでおきます。そして、必要なタイミングで該当するファイルを配置することでライブストリーミングが可能になります。ここでタイムスタンプの正確性はどうやって担保されるのかという疑問が沸くと思いますが、MPDファイルにはHTTPベースのタイムスタンプサーバを記述するフィールドがあり、このタイムスタンプサーバを参照することで時刻の補正をし、正確なタイミングでのライブ配信を可能にしています。
ちなみに、DASHではライブストリーミング以外の静的ストリーミングも可能ですが、これはこの記事の内容から離れるので割愛します。
WebRTCとストリーミングの違い
WebRTCとストリーミングの違いは何でしょうか。上述したようにレイテンシは大きな違いですが、もう一つは通信遅延が発生した時のデータの扱いです。WebRTCでは通信遅延が起きた時、遅れたパケットを積極的に捨てます。これに対し、ストリーミングでは、すべてのデータをサーバに保存します(クライアントがそれを取得するとは限りませんが、全て取得することも可能です)。
この特性は、両者の用途の違いにあらわれています。典型的には、WebRTCは、リアルタイム性が重視される会議等に適切で、ストリーミングは品質が重視される音楽配信に適切です。
WebRTC | ストリーミング | |
---|---|---|
低い | レイテンシ | 高い |
あり | データロス | なし |
高い | 大量配信時のコスト | 低い |
会議 | 典型的な用途 | 音楽配信 |
WebRTC to ストリーミング変換
上記のようなWebRTCとストリーミングの性質の違いから、WebRTCとストリーミングの良いところを組み合わせたサービス(たとえば、低レイテンシで大量配信)は、技術的に難しくなります。
ただ、「Web会議の内容を多人数に配信する」というように、「少人数で双方向通信をし、それを多人数に配信する」場合は、WebRTCの通信内容をストリーミングに変換する仕組みが使えます。これに特に決まった名前はないのですが、この記事では「WebRTC to ストリーミング変換」と呼ぶことにしましょう。WebRTCの通信をサーバ側で変換しストリーミングに変換することで「少人数で双方向通信をし、それを多人数に配信する」ことができるのです。
ちなみに、standfmさんの技術ブログでも、このパターンが使われていることが分かります。同等の実装は、後述するSaaSでも広く実装されています。
https://note.com/standfm_company/n/nc9d5eb129bc7
これを応用すると、セミナーの視聴者が1000人いて、質問者が指名されたときだけ、その人が発言できるという仕組みも作れます。視聴者には、通常、ストリーミング変換されたものを視聴してもらい、質問者が指名されたときに、WebRTCに昇格させれば良いのです(レイテンシの差から、昇格時に待機時間が生じますが、その間、司会者が場をつなぐような運用でカバーできます)。
WebRTCの実装
ではここで、WebRTCの実装について紹介していきたいと思います。
フルサービス系
WebRTCには優れたSaaSが多数あります。その中でも、リッチなインターフェースを持つものを「フルサービス系」と呼ぶことにします。実装は非常に簡単で、ZOOMやWherebyをそのまま自分のサービスに組み込むようなものだと考えると良いでしょう。ストリーミング変換や、録音機能、さらに、一般の電話に電話を架ける機能が利用できる場合があります。
欠点として価格が高いこと、WebRTCを直接扱えず、サーバ側で高度な処理を行おうとすると独自の実装になってしまうということがあります(たとえば、Vonage Video APIだとLinux向けのC言語のライブラリで直接データを扱うことができますが、node-webrtcのような一般的なライブラリを使えません。)
代表的なものとして以下のものがあります。
1. Vonage Video API (旧TokBox OpenTok)
https://tokbox.com/developer/sdks/js/
ストリーミング変換、録音、電話の架電機能もあります。
2. agora.io
https://jp.vcube.com/service/agora
ストリーミング変換、録音、電話の架電機能もあります。
シンプル系
これに対して、WebRTCそのものに特化したサービスもあります。これらはフルサービスほどの機能がない代わりに、価格が安いことが特徴です。WebRTC APIへのダイレクトなアクセスが可能だということも特徴です。
1. SkyWay
https://webrtc.ecl.ntt.com/api-reference/javascript.html
ルーム機能はフルサービスである一方、WebRTC APIへのダイレクトなアクセスが可能です。ストリーミング変換等の機能はありませんが、上の2つより単価が大幅に安く、バランスの取れたサービスと言えそうです。オープンソースのPeerJSのフォークで、APIはほぼ同一です。
2. Amazon Kinesis Video Stream WebRTC
https://aws.amazon.com/jp/kinesis/video-streams/
room概念が不完全で、3人以上で双方向の通信をするためには、サービス側のチャンネル概念と別に、独自のroom機能を実装しないといけません。一人の配信者に対して10人までしか視聴できないという制限も厳しめです(Vonage Video APIでは、サービスおまかせのフルメッシュで50まで。自分でroomを構築すれば、3000までいけます)。使用量が少なければ、SkyWayよりも使いやすい価格設定となっています。
独自実装
WebRTCには、複数のOSSプロジェクトがありますが、PeerJSをフォークしたものがのSkyWayとして運用されており、大規模実装の実績という意味では一つ頭抜けているように思えます。PeerJSは一時期メンテナンスされてないという問題がありましたが、最近はそうでもないようです。
他の実装については以下の記事にまとまっていますが、これを見る限り、PeerJSに匹敵するものはなさそうに思えます。
https://qiita.com/atskimura/items/97b2cc04e19781f4a4e6
WebRTCのOSSプロダクトを実験的に確認するのは決して難しいことではありません。チュートリアルにしたがえば誰でもできるでしょう。ただ、実際の運用を考慮してスケールするシステムを作るには、インフラ設計が微妙に面倒です。というのも、WebRTCサーバは状態を持つサーバであるため、HTTPサーバのようなロードバランサの仕組みを使うことができないからです。
インフラをスケールさせるためには、ユーザから直接アクセス可能な(通常、パブリックIP、パブリックなドメインを持つ)サーバをスケール対象として、負荷管理およびバランシングの仕組み、既存の接続を安全に保つスケールインの方法等を自分で実装しなくてはいけません。
ストリーミングの実装
WebRTC to ストリーミング
次にストリーミングの実装に移ります。先ほど説明したようなフルサービス系のWebRTCサービスには、WebRTC to ストリーミング変換機能があり、レイテンシや品質をそこまで気にしないのであればこれを使って、比較的かんたんにストリーミング配信を開始することができますまた、自前で実装したい場合も、node-webrtc + ffmpeg, Vonage Video APIのLinux API + ffmpegと言った形で比較的シンプルに実装できます(インフラ管理はWebRTCの場合と同じで面倒ですが・・・)。
Web以外の実装
ただ、WebRTC to ストリーミングではレイテンシや品質が十分ではない場合があります。Webでは使えないストリーミングプロトコルを用いたサービスであれば、Amazon MediaElement, Akamai Media Delivery Solutions等、さまざまなサービスがありますが、いずれも重い変換サーバを挟むことになり、レイテンシは大きめになります。
ダイレクトストリーミング / 低レイテンシストリーミング
では、ブラウザやスマートフォンアプリから直接ストリーミングすることはできないのかというと、そんなに難しいことではありません。特にDASHの場合、Chrome/AndroidはWebM-DASH, Safari/iOSはMPEG-DASHという制限はありますが、一応、Webだけでストリーミング配信にそのまま使えるデータの生成が可能です。また、スマートフォンアプリを開発する場合、iOS, Androidともにこの開発が可能です。
こうした形でストリーミングを実装した場合、サーバコストを大幅に抑えられるだけでなく、会議のタイムシフト再生(追っかけ再生)、超レイテンシストリーミング、カジュアルなライブ共有サービスなど技術上、ビジネス上の選択肢が大幅に広がります。こちらは弊社の独自技術になるため、ご興味のある方は、お問い合わせください。
まとめ
Web上でオンラインビデオサービスを作るのは非常に簡単で、既存サービスをマッシュアップすることで大部分のことは実現できます。ただし、レイテンシや品質、価格上の問題があり、サービスに要求される要件によっては、独自の技術開発、場合によっては研究開発が必要になるケースもあります。このあたりの問題でお困りの場合、ぜひ弊社にご相談いただけると幸いです。