tknakatsu
9/21/2015 - 4:22 PM

WebRTC コトハジメ

WebRTC コトハジメ

#############################
WebRTC コトハジメ
#############################

:更新: 2017-11-04
:作者: @voluntas
:バージョン: 2.1.0
:URL: http://voluntas.github.io/

**WebRTC をググって調べた人向け**

間違いは書いてないと思う。これは WebRTC 1.0 を前提に書いてる。

著者
====

フルスクラッチで WebRTC SFU を開発している。DTLS や SRTP も暗号部分以外はすべて自前実装。

以下は著者が書いた資料。

- `WebRTCの裏側 <https://gist.github.com/voluntas/975bfa230e513d146965>`_
- `WebRTC Conference Japan で話してきた <https://gist.github.com/voluntas/4bfce5ba4479bd25d4cd>`_
- `WebRTC スタックコトハジメ <https://gist.github.com/voluntas/6fcece7f424607c957d5>`_
- `WebRTC の未来 <https://gist.github.com/voluntas/59a135343538c290e515>`_
- `WebRTC SFU コトハジメ <https://gist.github.com/voluntas/4d2bd3e878965bdd747a>`_
- `WebRTC SFU をフルスクラッチで作ってみた <https://gist.github.com/voluntas/7547c305ac7a8a9c62c1>`_
- `リアルタイム動画配信コトハジメ <https://gist.github.com/voluntas/076fee77f30a0ca7a9b9>`_
- `Edge と WebRTC について <https://gist.github.com/voluntas/f174b402f91e63eb84368f929c2289bf>`_
- `Safari と WebRTC について <https://gist.github.com/voluntas/af937c1fd353e6f677e155b53d661807>`_
- `WebRTC スタックを一から実装する場合読んでおくべき資料まとめ <https://gist.github.com/voluntas/193ab447d387532a659d3ede9ab7678f>`_
- `詳解 WebRTC <https://gist.github.com/voluntas/a9dc017ea85aea5ffb7db73af5c6b4f9>`_

間違いや質問について
-----------------

この Gist へのコメントではなく @voluntas まで Twitter にてリプライを飛ばして欲しい。

目的
====

WebRTC は闇が深く、変化が早い技術だ。そのため公開されている情報はすぐ古くなってしまう。それらの古い情報を参照して不幸になる開発者を減らすために書いている。

できるだけ最新情報に追従するようにしている。

概要
====

**ブラウザ同士でリアルタイムコミュニケーションを実現するための仕組み**

WebRTC は P2P を利用したブラウザ同士を前提として技術として作られている。もちろん、WebRTC 自体はプロトコルの組み合わせでしかないため、 P2P を使わなかったり、ブラウザ以外を使ったりすることもできる。

WebRTC の通信プロトコルには TCP ではなく、 UDP が採用されている。これは音声や映像のデータを扱う以外にも、大量のデータを高速に送ることができるようにするためである。

通信はデフォルト暗号化されており、データグラム向けの TLS である DTLS が採用されている。

直接相手とやりとりをする P2P を実現する機能が含まれており、 NAT 越えを実現する仕組みが含まれる。NAT 越えをするためのプロトコルには STUN/TURN そしてそれら2つの技術を組み合わせた ICE と呼ばれる仕組みを採用した。

実際に NAT 越えを実現するためには STUN サーバや TURN サーバが必要となる。通常は TURN/STUN サーバとして 1 台で提供される。

対応ブラウザ
------------

現時点で期待通りに動作するのは Firefox と Chrome と考えてしまってよい。 Edge は Windows 10 の Creators Update (1703) で WebRTC 1.0 に対応したが、正直 WebRTC 対応と言うには厳しい状況。

Edge は Windoww 10 Fall Creators Update (1709) になってもほとんど改善は見られない。

Safari は Safari 11 で WebRTC へ対応した。ただし Safari が対応しているコーデックは H.264 のみ。

二つのチャネル
==============

WebRTC を説明する際、チャネルの種類が曖昧に説明されてることが多い。

WebRTC にはメディアチャネルとデータチャネルの二つがある。

- 映像と音声のデータ通信方式がメディアチャネル
- 好きなデータを放り込めるのがデータチャネル

WebRTC とメディアチャネルが同一と表現されることが多いので要注意。

たとえば日本で成功している WebRTC 事例の一つである MistCDN は `Mist Technologies <https://www.mist-t.co.jp/>`_ が開発している WebRTC のデータチャネルを使った P2P ベースの CDN だ。

海外だと `Peer5 - The Serverless P2P CDN For Video Live Streaming <https://www.peer5.com/>`_ や `Streamroot | Distributed Network Architecture for OTT Video Delivery <https://www.streamroot.io/>`_ がサーバレス CDN を提供している。

CDN といっても今回紹介した P2P CDN は全て **動画配信** を前提としている。HLS や MPEG-DASH の配信を CDN と P2P で補完していくという仕組みだ。

SDP
---

メディアだろうがデータだろうが、お互いの通信を統一するためのプロトコルとして SDP が採用されている。
簡単に言えばメディアでいえば自分は音声をこの形式で送るなどだ。

メディアチャネル
----------------

メディア、つまり映像と音声を送り合う仕組みである。実態は RTP/RTCP と呼ばれるリアルタイムに映像や音声を配信するプロトコルが採用されている。

RTP はとても古いプロトコルであるが、拡張が大量にある。今のところは最低限の実装が行われていると考えてよい。

データチャネル
--------------

データチャネルは SCTP をベースとしているため、映像や音声だって取り扱える。むしろ何でもよい。

SCTP は TCP と UDP のいいところ取りをしたプロトコルだと思ってもらってよい。SCTP もなり古いプロトコルだが、残念ながら流行っているとはいえない。

最近ではデータチャネルの通信を QUIC を利用するという実装も WebRTC が公開しているライブラリには入ってきている。

実際 Google が発表した Allo や Duo は WebRTC over QUIC という話が出てきている。

シグナリング
============

WebRTC はよく P2P の技術と呼ばれるがこれは正しい。ブラウザ同士でデータのやりとりを実現することができる。ただし、シグナリングと呼ばれる仕組みが必須になる。

実はシグナリングにはいろいろな仕組みがあるのだが、 WebRTC では定義されていないため、ここでは大まかに定義する。

- 通信しようとする相手の IP アドレスの解決

  - 相手の名前から IP アドレスを取得するなど。つまりこれから通話する相手の IP アドレスを取得することができるようになる仕組み
- 相手がその通信を許可するかどうか

  - そもそも誰にでも繋がってはいけないので、拒否されているかどうかを判断する仕組み
- 通信状態(セッションと呼ぶ)において使用するパラメータの合意

  - メディアチャネルであれば、お互いの映像に使うコーデックや最大フレームレートなどの合意をとる仕組み

このいくつかの仕組みをまとめてシグナリングと呼ぶことが多い。

これらの仕組みを実現するためにはシグナリングサーバが必要になる。つまりセッションを確立する前に判断しなければいけないため、ブラウザ同士が直接やりとりすることができないからだ。

本来はセッションの終了まで管理すべきであろう。このあたりは **仕様がない** ため実装者に任されている。

MCU と SFU
==========

WebRTC の世界は P2P を前提として入るが、それとは別に MCU と SFU という世界がある。
これは P2P でやりとりをするのではなく、クライアント・サーバモデルでやりとりをする。

MCU や SFU は WebRTC の標準的な考え方からすると異端ではあるが、一定以上の品質や数を担保する場合は必須となる。

MCU (Multipoint Control Unit)
-----------------------------

https://webrtcglossary.com/mcu/

昔からある技術で、3 拠点以上でテレビ会議をする場合に使われている。MCU の特徴はサーバによる合成だ。

つまりそれぞれの音声や映像が別に送られてくるのではなく、サーバで合成されて 1 つの音声や映像として送られてくる。

100 人が参加する会議があったとしても、サーバで 1 つに合成される。

良いことだらけだが、合成するためサーバ側のリソースを恐ろしく使う。

SFU (Selective Forwarding Unit)
-------------------------------

https://webrtcglossary.com/sfu/

SFU という単語が出てきたのはここ数年。ただ概念自体は前からある。SFU は MCU だと CPU リソースを使われてしまうことから考え出された仕組み。

クライアントが配信する音声や映像をサーバが代理で他のクライアントやサーバに送るという仕組み。そのため、クライアントは 10 人参加者がいた場合でもサーバに映像を送るだけで済む。

P2P の場合のフルメッシュと MCU の間の技術でバランスが良い事もあり WebRTC でクライアント・サーバモデルの場合は SFU が選択されることが多い。

よくありそうな質問
==================

仕事で使いたい
--------------

宣伝記事にはなるが、以下に仕事で WebRTC を利用する話をまとめておいたので見てもらいたい。

`仕事で WebRTC <https://gist.github.com/voluntas/379e48807635ed18ebdbcedd5f3beefa>`_

何が大変か
----------

- 最新ブラウザへの追従
- 繋がらない人へのサポート対応

主にこの二点。両方ともこちらで事前に予測は難しい。前者はメーリングリスト見ておいて実際に検証しておけば問題ない。
後者だけはもうネットワーク環境などなど、いろいろなものに依存してしまうのでなんともいえない。実際に運用してノウハウをためるしかない。

基本的にクライアント側で頑張る必要があるので JavaScript が複雑になっていく。


また、ブラウザ同士の仕様差吸収という問題もある。これは全てのブラウザが WebRTC 1.0 の仕様を満たしているわけではない。そのため Chrome 、Firefox 、Edge 、Safari (今後) といったブラウザの差を吸収しなければならない。

Safari では動作しないのか?
---------------------------

Safari 11 で WebRTC に対応した。ただし利用可能なコーデックは H.264 のみ。

HLS や MPEG-DASH とどう違うのか
-------------------------------

その辺の話はこの資料にまとめたので読んでみてほしい。

`リアルタイム動画配信コトハジメ <https://gist.github.com/voluntas/076fee77f30a0ca7a9b9>`_

iOS には Chrome があるがそれでもダメなのか
------------------------------------------

iOS の Chrome は結局モバイル Safari なので、ダメ。 

WebView は RTCPeerConnection は対応しているが getUserMedia はまだ非対応なため、対応していない。

iOS や Android のアプリはどうやって開発すればいいのか
------------------------------------------------------

webrtc.org がちゃんと提供してくれている。

- `Android | WebRTC <https://webrtc.org/native-code/android/>`_
- `iOS | WebRTC <https://webrtc.org/native-code/ios/>`_

さらに最近は Bintray や Cocoapod で最新版のビルドを Google が提供し始めている

- `GoogleWebRTC on CocoaPods.org <https://cocoapods.org/pods/GoogleWebRTC>`_
- `google-webrtc <https://bintray.com/google/webrtc/google-webrtc>`_

これらを上手く活用する事。

結局遅延はどのくらいなのか
--------------------------

環境や回線やマシンパワーに依存するが、好条件であれば 200 ミリ秒程度の遅延。

低回線で配信したい
------------------

ビットレートを下げることで実現は可能。 WebRTC では帯域推定と呼ばれる機能を利用して、低回線の場合は解像度を自動で下げて、ビットレートを抑える仕組みが入っている。

ちなみに 50kbps でも映像は配信可能。

WebRTC は難しいという話をよく聞くが実際どうなのか
-------------------------------------------------

趣味で触る程度なら特に難しくはない。TURN/STUN サーバを立てるのが壁くらいだ。
ただ、WebRTC 自体をビジネスにする場合かなり難しいといって問題ないと思う。

そもそもリアルタイムが NAT 越えやらで難しい。さらに映像や音声は複雑な仕組みが使われている。
WebRTC の仕組み自体は今後もっともっと複雑になっていく。

WebRTC を使うためには STUN サーバは必要なのか
---------------------------------------------

P2P を前提とするならば、必要と認識もらってかまわない。NAT 越えをするために最低限必要なサーバだ。

WebRTC を使うためには TURN サーバは必要なのか
---------------------------------------------

特になくてもよい。ただし特定のネットワーク環境では P2P で通信ができないため、接続確率を上げるためには TURN サーバは必要だ。実際繫がらないを減らすためには TURN サーバは必須。

80 % は TURN が無くても繋がり、 10 % は TURN-UDP があれば繋がり、のこり 10 % は TURN-TCP と TURN-TLS があれば繋がるという話がある。

TURN-TCP や TURN-TLS とはなんなのか
-----------------------------------

TURN の UDP が繋がらないときに TCP 、そして TCP が繋がらないときに TLS にフォールバックしていく仕組み。

TURN-TLS までフォールバックしてつながらない時は諦めるしか無い。

シグナリングの仕組みは何でもいいのか
------------------------------------

まったく規定されていないので何でもよい。よくあるのは WebSocket と JSON の組み合わせだが、 XMPP も使われたりする。オリジナルの場合もあり、様々なライブラリやサービスでのシグナリングの互換性はないと割り切って良い。

セッション確立後の通信は暗号化されているのか
--------------------------------------------

メディアチャネルであれば DTLS-SRTP で、データチャネルであれば DTLS によって暗号化される。

DTLS の証明書検証はどう行われているのか
---------------------------------------

シグナリングを利用して交換する SDP の中身の a=fingerprint に書いてあるフィンガープリントの値を利用した仕組みを使っている。DTLS の証明書検証時にこの fingerprint の値と送られてきた証明書を検証している。

TURN サーバで通信を見られてしまうのではないか
---------------------------------------------

TURN サーバは **暗号化された状態のまま** データをリレーするため、通信状態をみることはできない。

ブラウザ同士の互換性はあるのか
------------------------------

実はすごく複雑なため簡単な回答が出来ない。基本的なものは互換性があるが、それ以外は非互換なものは少なくない。

Chrome や Firefox や Edge 以外に対応するのか
----------------------------------------------

Safari が 11 にて対応。iOS のモバイル Safari も対応している。

`Safari と WebRTC について <https://gist.github.com/voluntas/af937c1fd353e6f677e155b53d661807>`_

Edge の WebRTC 対応はどうなのか
-------------------------------

2017 年 6 月時点でかなり微妙な対応といって間違いない。その辺は以下の資料にまとめてあるので見てほしい。

`Edge と WebRTC について <https://gist.github.com/voluntas/f174b402f91e63eb84368f929c2289bf>`_


高画質で配信したい
------------------

多くの帯域があるネットワークと高性能なマシンが必要になる。ちなみに VP8 や H.264 でフル HD での配信は 3000kbps 程度あればいける。

VP9 を利用すれば 2000kbps 程度で FHD で、30fps な映像が配信可能。

音声が聞こえにくい
------------------

音声はマイクの機能依存になる。もちろん回線はイイ回線があること前提。

`YVC-1000 - スピーカーフォン/マイク&スピーカー - ヤマハ株式会社 <http://jp.yamaha.com/products/communication/usb_conference_speakerphones/yvc-1000/?mode=model>`_

これを買えば解決する。12 万円と高額だが、一つ買えば幸せになれるので本当におすすめ。

WebRTC の技術を勉強したい
-------------------------

API の勉強であれば W3C を見てもらうのが早い、ただブラウザごとに実装が異なるので注意。

`WebRTC 1.0: Real-time Communication Between Browsers <https://www.w3.org/TR/webrtc/>`_

プロトコルスタックの勉強は一筋縄ではいかない。以下にまとめてあるので見てほしい。

`WebRTC スタックを一から実装する場合読んでおくべき資料まとめ <https://gist.github.com/voluntas/193ab447d387532a659d3ede9ab7678f>`_

もう少し踏み込んだ情報が知りたい
------------------------------------

定期的に更新しているので見てもらえれば。

`WebRTC の未来 <https://gist.github.com/voluntas/59a135343538c290e515>`_

広告
====

WebRTC SFU Sora
---------------

`WebRTC SFU Sora <https://sora.shiguredo.jp/>`_

商用の WebRTC SFU です。価格は 100 接続で年間利用料ライセンス 60 万円です。毎年かかります。製品のサポート料金込みです。

複数人数での会議や、 数百人への配信、一対一の面談など様々な用途に利用可能です。

パッケージで提供しますので、自社で運用が可能です。 AWS だろうが GCP だろうが、オンプレだろうがなんでもどうぞ。
サーバさえあれば起動までは 10 分です。デモ機能が内蔵しているので動かすまで 15 分でいけます。

- とにかく **落ちないこと** を目的に作っています
- とにかく **繋がること** を目的に作っています
- とにかく **手間がかからないこと** を目的に作っています
- 最新ブラウザのアップデートに追従しています
- シグナリングサーバ内蔵ですので別途立てる必要はありません
- TURN サーバ内蔵ですので別途立てる必要ありません
- 日本語によるサポート対応しています
- フルスクラッチ自前実装なのですべて把握しています
- 1:1、1:N、複数人会議、録画あります
- Chrome / Firefox / Edge / Safari といった主要ブラウザ全てに対応しています
- Apache 2.0 ライセンスで JavaScript と iOS と Android のクライアント SDK を公開しています

  - https://github.com/shiguredo/sora-js-sdk
  - https://github.com/shiguredo/sora-ios-sdk
  - https://github.com/shiguredo/sora-android-sdk
- 既存システムとの連携を重視しており、Web フック機能を利用して簡単に連携が可能です

  - 認証や、クライアントの接続切断などもすべて HTTP での通知を既存のシステムに送ることができます
- 海外で利用される場合は該非判定書も用意しております


**時間をお金で買いませんか?**

興味のある方は sora at shiguredo.jp までお問い合わせください。

気軽に参加頂けるセミナーも定期的に開催していく予定ですので、興味ある方は是非。

`第1回 WebRTC SFU Sora セミナー <https://github.com/shiguredo/seminar/blob/master/webrtc_sfu_sora_seminar_1.rst>`_

紹介や検討資料も公開しております。

- `WebRTC SFU Sora の紹介 <https://gist.github.com/voluntas/5f3cf1049ee2710401e8bc3ecde4613e>`_
- `WebRTC SFU Sora 検討資料 <https://gist.github.com/voluntas/171ac9ee2ea6377586876602a41decff>`_