WebRTC を今から学ぶ人に向けて
ライセンス
Creative Commons — 表示 - 非営利 - 改変禁止 4.0 国際 — CC BY-NC-ND 4.0
内容
これから WebRTC を学ぶ人が何を学ぶべきで、何は学ばないべきなのかを書く。定期的に更新していく。
趣味で学びたい人はターゲットに入っていません、仕事で利用する場合のみがターゲット。
まとめ
急がば回れで、W3C の資料を理解できるまで読み込む。
下手にフレームワークに依存したりして簡単な仕組みを覚えてしまうと後からツライ。
- Media Capture and Streams
- WebRTC 1.0: Real-Time Communication Between Browsers
- Identifiers for WebRTC's Statistics API
作って学ぶも良いが、まずは出てくる単語などの意味を理解できるのが一番効率がいい。
仕組みについてはハイパフォーマンスブラウザネットワーキングと WebRTC for the Curious を読めばあとは RFC やソースコードを読むだけになる。
W3C 応用編
- WebRTC Extensions
- WebRTC Encoded Transform
- Scalable Video Coding (SVC) Extension for WebRTC
- Media Capture and Streams Extensions
- MediaStreamTrack Content Hints
Twitter 版
著者
- 商用 WebRTC SFU 開発者
- WebRTC プロトコルスタック実装者
- End to End Encryption プロトコルスタック実装者
- QUIC プロトコルスタック実装者
著者が書いた資料
お勧め書籍
-
O'Reilly Japan - ハイパフォーマンス ブラウザネットワーキング
- とにかく素晴らしい良著なのでこれは必ず買うべき
- O'Reilly Japan - Real World HTTP 第2版
- プロフェッショナルSSL/TLS – 技術書出版と販売のラムダノート
お勧めサイト
-
Real time communication with WebRTC
- 一通り体験できるので、これがお勧め
- シグナリングサーバを立てなくてよい
-
Introduction | WebRTC for the Curious
- プロトコルの詳細を RFC まではちょっと .. という人向けの最高の資料
- Pion の作者が書いてる
-
はじめに | 好奇心旺盛な人のためのWebRTC
- 日本語翻訳版です
お勧めしないこと
- 〜が作れる教材系
- WebRTC を 教材を作る事 でしか経験していない人が作った教材がほとんどのため
- 特定製品に依存した資料
- たとえは時雨堂が公開している WebRTC SFU Sora が重視されている資料
- 趣味で学ぶは対象外
- 趣味でやるなら何したっていい、好きに学ぶのが良いと思う
- 仕事で利用する場合は自前か製品(OSS を含む) を利用するのどちらかになる
- 1:1 であれば WebRTC P2P を検討しても良い
- それ以外は WebRTC SFU を検討するべき
- WebRTC SFU の自作はコスト面からいってメリットが少ない
- Discord / WhatsApp / Zoom を目指しているなら別
- そもそも Discord などを目指してるならこれを読んでる場合ではなく RFC を読むべき
- WebRTC P2P を学ぶ
- 最小限覚えるべきは 3 つ
- シグナリングサーバ
- TURN サーバ
- WebRTC API
- シグナリングサーバ
- WebSocket が多い
- socket.io だろうが Firebase だろうがなんでもいい
- シグナリングサーバの開発は難しくない
- TURN サーバ
- 利用するだけなら coturn 使えばいい
- 枯れているプロトコルだし、枯れている仕組み
- WebRTC API
- ブラウザかそれ以外かで難易度が変わる
- デスクトップは Electron がお勧め
- モバイルは地獄
- ブラウザは W3C WebRTC API を読み込めば大丈夫
- offer
- answer
- candidate
- WebRTC が難しいのは W3C WebRTC API を読み込んでない事がほとんど
- WebRTC API はリアルタイムを扱っているにも関わらず恐ろしいほどシンプルに作られている
- W3C WebRTC API にはきっちり状態遷移なども書かれている
- フレームワークはめんどうな部分を隠蔽してるので学ぶのには向いていない
- 1 から試行錯誤するのをお勧めする
WebRTC API (P2P) 限定であれば、フレームワークを用いずとも 1 から開発しても 1-2 ヶ月程度で十分仕事で使えるレベルの知識は得られる。一通りの知識が必要になるので、大変お勧め。
WebRTC が大変なのは問題が起きたときなので、試行錯誤の経験はあった方がいい。
- TURN サーバの仕組みの理解が難しい問題
- TURN サーバがどんな仕組みで動いているのかは理解できるならしたほうがいい
- TURN サーバの情報は少ない
- 自力で学ぶのは大変
- 残念だけど RFC 読むのが一番効率がいい
- 実際のソースコードを読むのはお勧め
- aioice https://github.com/aiortc/aioice
- pion/turn https://github.com/pion/turn
- coturn https://github.com/coturn/coturn
- 多機能だが読みやすいので頑張れるなら是非
- 昔書いたのを書き直したりしている
- WebRTC SFU という選択
- クライアント・サーバモデル
- 本流
- 自力で WebRTC SFU を作るメリットはない
- 既存製品の劣化版になる
- メンテナンスのコストが高い
- 機能追加のコストが高い
- 劣化版を作り上げるなら、既存製品を利用していくべき
- WebRTC SFU を触るのであれば 4 つお勧めがある
- OSS で触れるのを前提とする
- mediasoup
- C++/JavaScript で書かれている
- ロジック部分が JavaScript で書かれている
- 実績も多くある
- SFU 特化型のため便利機能はない
- スペイン産
- Pornhub はこれ
- Janus Gateway
- 機能が盛りだくさん
- やりたいことのほとんどができる
- ロジックは Lua で書ける
- 実績が多くある
- イタリアのナポリ産
- Twitter Spaces はこれ
- Jitsi
- 会議サービス向けに作られたため会議向けの機能が多い
- Java と JNI なので覚悟が必要
- 多くの企業が自社サービス/自社製品 Jitsi ベースだったりする
- フランス産
- Pion
- Go で書かれた WebRTC スタック
- Pion ベースの WebRTC SFU も公開されてる
- 世界中の多くの開発者が貢献している
- 作者はもともと Amazon だったが、今は Apple にいる
mediasoup / Janus Gatway / Jitsi / Pion のどれかを選んでがっつりさわれば WebRTC SFU の仕組みを理解できる。どれを触るかはいろいろ触ってみてきめるのがよい。
Twilio が買収した Kurento というのもある、 Kurento 開発者から圧を受けたのでここで紹介しておきたい。
おまけ
Pion を使って作った WebRTC SFU 紹介
- Livekit
- Pion を利用して書かれた WebRTC SFU
トラブル解析をどう学ぶべきか
- WebRTC の問題
- 繋がらない
- 聞こえない
- 映らない
- 繋がらない問題は TURN を利用していない場合がほとんど
- TURN-TCP / TURN-TLS をポート 443 番にしてだめならあきらめるしかない
- coturn でしっかり TURN-TCP と TURN-TLS の設定を覚えた方がいい
- Safari は Let's Encrypt を利用した TURN-TLS をはじく問題がある
- 今後修正される予定
- 聞こえない問題はデバイス周りの設定がほとんど
- モバイルだと音量が小さくなるといった問題があったりもする
- ブラウザだとデバイスとの相性問題もある
- JavaScript 側で頑張る以上の選択肢はない
- Google Meet はいろいろ頑張ってるので、参考にするといい
- マイクの性能問題もある
- ノイズがひどくて聞こえないとかもよくある
- Google Meet は独自のノイキャン(Wasm) を導入したりしている
- 問題解決はハードルが高い世界だと思った方がいい
- 映像が見えないのも聞こえないと同様の世界でデバイス問題が多い
- こちらも JavaScript でがんばるしかない
トラブル解析は環境依存がほとんどなので問題解決が難しい。
- 問題の原因が不安定な回線やマシンスペックの問題という場合もある
- その場合は「クライアントの統計情報」を収集するのが一番良い
- WebRTC 統計 API を学ぶのが最短距離
- 統計項目を学ぶのはコストが高い
- ただし統計機能を理解するとなぜ繋がらないかを調べやすい
- 以下は全て統計機能から調べられる
- 回線が不安定だった
- エンコーダが不安定だった
- マシンスペックが足りなかった
WebRTC 統計 API を学ぶのはとてもお勧めしたい。
- WebRTC のプロトコルスタックを学ぶ価値はほぼない
- メリットがない上に、コストが高すぎて無駄
- 使い道もほぼない
- WebRTC スタックの専門家の需要などほぼないので、そこに投資するのは時間の無駄
- フレームワークを学ぶ前に基本的な知識を抑えてから学んだ方がいい
- SDK には製品事に癖がある
- WebRTC クライアント側でソースコードがクローズドな物を選ぶと地獄
- フレームワークは面倒な部分を吸収してくれるのが魅力
- 面倒な部分は学ぶ必要ないところでもある
- 基礎的なことだけ学べばフレームワークを学ぶコストは低くなる
モバイル iOS/Android の WebRTC を学ぶ場合
- 1 から学ぶのはハードルが高すぎるのでフレームワークを利用する事をお勧めする
- フレームワークを利用すると問題が隠蔽されるという課題は残り続ける
-
WebRTC ネイティブライブラリガイド for iOS and Android
- 覚悟を持って突撃するといい
デスクトップ向け WebRTC を学びたい場合
-
よほどの理由がない限り Electron を検討するべき
- Discord は Electron を採用
- W3C の知識がそのまま利用できるのも嬉しい
-
軽量やハードウェアアクセラレータの恩恵を受けたいなら狙うならネイティブを頑張る必要がある
-
Fultter を検討しても良い
ラズパイや NVIDIA Jetson 向けの WebRTC を学びたい場合
- ブラウザでよいかどうかを検討する
-
WebRTCをブラウザ外で使ってブラウザでできることを増やしてみませんか?(電子版) - でんでんらぼ - BOOTH
- これが日本語唯一の資料なので、これを買って読むべき
- ブラウザが重い場合は手前味噌で恐縮だが WebRTC Native Client Momo のソースを読むのが良い
- 多くのノウハウが詰まっている
Unity 向けの WebRTC を学びたい場合
-
Unity-Technologies/com.unity.webrtc: WebRTC package for Unity
- 公式が用意してくれているので、こちらを調べてみるのが良い
WebRTC で不安定な回線を再現したい場合
- tc コマンドと iptable コマンドがお勧め
-
thombashi/tcconfig: A tc command wrapper. Make it easy to set up traffic control of network bandwidth/latency/packet-loss/packet-corruption/etc. to a network-interface/Docker-container(veth).
- このツールが本当に素晴らしい
-
WebRTC フェイクネットワーク
- Chrome にはフェイクネットワークを再現する機能がある
WebRTC で利用されるコーデックについて
- ビットレートを抑えれば、ネットワークが細くても安定する
- 音声コーデックは Opus が今のところ決定版
- Lyra がどうなるか
- 映像コーデックは VP8 / VP9 / AV1 / H.264 / H.265 がある
- VP8 / H.264 は実装必須
- H.264 は多くの環境でハードウェアアクセラレータがある
- AV1 は Chrome M90 から対応
- 負荷がとても高いが利用はできる
- VP9 は Safari 15 で対応
- H.265 は Safari が実験的に対応しているだけ
- VP8 / H.264 は実装必須
IPv4 NAT
-
徹底解説 v6プラス | 日本ネットワークイネイブラー株式会社
- "第5章 IPv4 NAT" がおそらく日本語で唯一ここまで詳細に説明してくれている資料なのでお勧め
仮想背景や背景ぼかし
Google が公開している Selfie Segmentation - mediapipe を利用する。
簡単に利用できるライブラリを公開しているので興味あれば。
@shiguredo/virtual-background - npm
ノイズ抑制
RNNoise: Learning Noise Suppression を Wasm に変換して利用する。
簡単に利用できるライブラリを公開しているので興味あれば。
@shiguredo/noise-suppression - npm