😤

WebRTC のシグナリング規格 WHIP と WHEP について

2023/03/31に公開

これは一部時雨堂製品の宣伝記事になっています

自社製品で WHIP に対応し、 WHEP にも対応していっいるので、雑に書いておこうと思います。

プロトコルの細かい説明などはしていないので、各自 ChatGPT に聞いたりして調べてください。

まだドラフト段階のプロトコルなので、今後仕様が変わっていきますので要注意です。

定期的にアップデートしていきます。

WHIP / WHEP とは

WHIP / WHEP とは簡単に言うと WebRTC でのシグナリングの規格です。

なぜそんな規格が必要なのか?、実は WebRTC ではシグナリングの規格は存在しません。
自由です。なので各種サービスで独自のシグナリングを実装しています。

なぜシグナリングの規格がないと困るのか、WHIP の言い出しっぺ方から聞く機会があり、OBS への対応が目的という話でした。

OBS はもともと MS が提供していた Mixer という WebRTC (Janus Gateway カスタマイズを利用) を利用したサービス向けの FTL という独自プロトコルに対応していました。

https://github.com/microsoft/ftl-sdk

ただ、FTL はあまりにも独自すぎるため、他の配信サービスは使えませんし、
そもそも Mixer がサービス終了してしまったのでなんともです。

OBS などの配信ツールで使えるようにするには 共通のシグナリング規格 が必要になります。

WHIP

WebRTC を配信に利用しようとしてシグナリングの規格を決めたのが WHIP です。WHIP は WebRTC-HTTP ingestion protocol の略です。

WHIP の特徴は SDP Offer を HTTP POST で投げつけて、201 Created で SDP Answer を返すというものです。そのときの content-typeapplication/sdp です。

201 Created の戻りに Location ヘッダーで、WHIP のこのコネクションを切断したりするリソース用の URL を返します。

つまり HTTP Req/Res だけで SDP の交換を終わらせて、その後は WebRTC に切り替えるという事が可能になります。

実際この仕様で OBS 30.0 で搭載されました。

https://github.com/obsproject/obs-studio/releases/tag/30.0.0

WHIP を実装することで OBS から WebRTC を利用して配信することができるようになります。これが WHIP を仕様策定する目的です。

WHIP に対応すると何がいいのか

OBS には仮想カメラという機能があるので、それを使うことでブラウザ経由で OBS 仮想カメラを使って配信はできます。ただその場合はブラウザを経由する必要があり、HWA などがうまいこと使えません。

そのため OBS から直接配信できるようになる WHIP は、OBS の恩恵を最大に受けられるようになります。

WHIP 対応サービス

現時点では WHIP 仕様策定者がいる Dolby が対応しています。

WHIP

また、 Cloudflare が提供する Stream サービスも WHIP にベータ版ではありますが対応しています。

WebRTC (beta) · Cloudflare Stream docs

Cloudflare の WHIP 実装は Go の WebRTC 実装である Pion が利用されています。

https://x.com/rrnn/status/1775980426537963904

WHIP リソース

WHIP はシグナリングを繋ぎっぱなしにするという概念がありません。そのため切断は Location ヘッダーで払い出したリソースにたいして HTTP DELETE を投げつけるという仕組みです。

ちなみに WebRTC のメディアチャネルに切断という概念は一応あります。RTCP の Bye を送ることで切断が可能ですが、これはほとんど使われていません。

また WebRTC では取得した ICE 候補をサーバーにそのたびに送る trickle ICE という概念があります。また ICE リスタートという機能もあり、これらは HTTP PATCH でアップデートしていくという方針になっています。

そのときの mime-type は application/trickle-ice-sdpfrag です。

WHIP で負荷分散

WHIP はシグナリングの規格のため、配信先のメディアサーバーとはエンドポイントが異なる場合があります。実際 WHIP でも WHIP エンドポイントとメディアサーバーは別になっています。

ただ、実際 WebRTC SFU を開発している身からすると、シグナリングエンドポイントとメディアサーバーを分けるメリットはそんなに大きくないので、サーバ構成を複雑にするだけな気がします。

WHIP で TURN

WHIP でも TURN サーバは利用可能です。この場合は HTTP POST の戻り値の 201 Created の Link ヘッダーを利用します。

以下は WHIP の RFC ドラフトからの引用です。OBS ではなくブラウザで WHIP を利用する場合はクライアント側ヘッダーから iceServers に組み立て直す必要があります。

Link: <stun:stun.example.net>; rel="ice-server"
Link: <turn:turn.example.net?transport=udp>; rel="ice-server";username="user"; credential="myPassword"; credential-type="password"
Link: <turn:turn.example.net?transport=tcp>; rel="ice-server"; username="user"; credential="myPassword"; credential-type="password"
Link: <turns:turn.example.net?transport=tcp>; rel="ice-server"; username="user"; credential="myPassword"; credential-type="password"

TURN-TCP や TURN-TLS については、 UDP に通信ができない環境で配信するなよというお気持ちはあります。

WHIP と認証

自分がとても重要だと思っているのがこの部分です。WHIP はシグナリングの規格ということもあり、自由な認証が作れないと思います。

WHIP の認証は HTTP Authorization ヘッダーを利用して Bearer トークンを指定することができます。

OBS は Bearer トークンを指定することが可能でです。

Image from Gyazo

ちなみに Cloudflare Stream の WHIP の認証は URL ベースです。つまり URL にばれにくいシークレットを入れるタイプです。個人的にこれでもいいとは思います。

https://customer-<CODE>.cloudflarestream.com/<SECRET>/webRTC/publish

WHIP とサイマルキャストと SVC

配信側が複数の画質を WebRTC SFU へ配信することで、視聴者側が画質を選択できるようにするサイマルキャストという仕組みがあります。

WHIP でもサイマルキャストは利用可能です。もともと WebRTC のサイマルキャストはクライアント主導です。クライアントがどんな解像度でビットレートの映像を何種類送るかを選択可能です。

複数のストリームを送るサイマルキャストとは別に SVC という機能があります。
SVC は Scalable Video Coding の略です。

WebRTC では拡張機能として実装されています。
Scalable Video Coding (SVC) Extension for WebRTC

SVC は 1 本のストリームに複数のレイヤーを持たせることができる仕組みです。
興味がある方は以下を是非読んでみてください。
WebRTC SVC 拡張と AV1 コーデック

OBS の WHIP 実装でもサイマルキャストは対応予定です。

OBS の WHIP

WHEP に行く前に OBS の WHIP 実装について触れていくことにします。

もともと OBS では FTL というマニアックなプロトコルが利用できることは前述しましたが、
WHIP の提案者たちは OBS の WebRTC プラグインを開発していました。

CoSMoSoftware/OBS-studio-webrtc: This is a fork of OBS-studio with generic support for webrtc. It leverages the same webrtc implementation most browsers use.

ただ、OBS の今の PR は実はいろいろな経緯があります。

WebRTC の通信部分だけが欲しい OBS にとっては libdatachannel を採用しました。

libdatachannel っててっきり DataChannel ライブラリかと思っていたら WebRTC の通信部分だけを実装したライブラリでした。

ibdatachannel is a standalone implementation of WebRTC Data Channels, WebRTC Media Transport, and WebSockets in C++17 with C bindings for POSIX platforms (including GNU/Linux, Android, FreeBSD, Apple macOS and iOS) and Microsoft Windows.

これはとても良い判断な気がします。

そして OBS 30.0 で WHIP が利用できるようになりました。

Release OBS Studio 30.0 · obsproject/obs-studio

AV1 対応

OBS 31.0 で WHIP の AV1 に対応しました。

WHEP

WHIP は配信者向けのシグナリング規格でしたが、 WHEP は視聴者側のシグナリング規格です。WebRTC-HTTP Egress Protocol の略でつまりメディアサーバーから音声や映像を受信する仕組みです。
基本的にはブラウザやスマホで利用される事になると思います。

WHEP はまだ模索中でサーバー Offer からクライアント Offer に切り替わるくらいドラスティックな変更が行われています。
クライアント Offer に切り替わったことで、プロトコル自体はほぼ WHIP と一緒になりました。

WHEP と SSE

WHEP の拡張機能の一つとして SSE が提案されています。 SSE は server-sent events の略です。

Using server-sent events - Web APIs | MDN

SSE はサーバから片方向送信用 WebSocket みたいなものです。これを使うことで視聴者側にリアルタイムで通知を送ることができるようになります。

こちらも Link ヘッダーを使います。WHIP 側でも提案されています。

以下は RFC ドラフトからの引用です。

Link: <https://whep.ietf.org/resource/213786HF/sse>;
      rel="urn:ietf:params:whep:ext:core:server-sent-events"
      events="active,inactive,layers,viewercount"

WHEP と SSE とレイヤーイベント

WHEP の SSE を利用して、レイヤーイベントを発火させる ABR も提案されています。YouTube とかにある画質選択ですね。

WebRTC SFU にはある機能なので、現実的な気がします。

WHEP と SSE と視聴者イベント

WHEP の SSE を利用して、視聴者数を通知するという機能も提案されています。これも YouTube Live とかにある視聴者数ですね。

これも WebRTC SFU にある機能なので、現実的な気がします。

まとめ

  • WHIP / WHEP という配信向け WebRTC シグナリング規格が提案されている
  • OBS が WHIP へ対応しそう
  • WHIP / WHEP は今後片方向低遅延配信のデファクトとして利用されていきそう
  • Media over QUIC Transport が一般的になるまでは WHIP 時代が続きそう

時雨堂の WHIP / WHEP への取り組み

OBS が WHIP へ対応するのはとても大きな事だと判断して、 OBS の WHIP 対応を進めていきます。

  • 2023 年 6 月リリースの WebRTC SFU Sora にて実験的に WHIP へ対応
  • 2024 年 6 月リリースの WebRTC SFU Sora にて WHIP を正式版へ
  • 2024 年 6 月リリースの WebRTC SFU Sora にて実験的に WHEP へ対応
  • 2024 年 6 月リリースの WebRTC SFU Sora にて実験的に H.265 へ対応
  • 2024 年 6 月リリースの WebRTC SFU Sora にて実験的に TURN へ対応

OBS の WHIP/WHEP 実装への貢献、 OBS が利用している libdatachannel への貢献を積極的に行っています。

実際動いている例

時雨堂の WebRTC SFU Sora に WHIP 経由で OBS から H.264 (macOS HWA) で配信をし、ブラウザで受信している例です。

Image from Gyazo

参考資料

Discussion