OBS (WHIP) 対応機能

概要

OBS が対応を予定している WHIP を利用した OBS 経由での WebRTC 配信に対応しています。

ここでは Sora や OBS の WHIP 仕様について説明します。

注意

  • OBS の WHIP 実装の仕様を正としており RFC ドラフトの WHIP 仕様とは異なる可能性があります
  • Sora は WHEP へ対応していません
  • Sora SDK は WHIP や WHEP へ対応していません

WHIP クライアントのお問い合わせについて

WHIP クライアントに関する質問などの報告は Discord の利用をお願いします。

URL:

https://discord.gg/shiguredo

Sora の WHIP クライアントに関するチャンネルは #sora-whip です。

WHIP とは何か

WHIP は WebRTC-HTTP ingestion protocol の略で、 WebRTC では標準化されていないシグナリングをブロードキャスト/ストリーミング系の配信ツール向けに規定した規格です。

WHIP は仕様を小さくして、実装を簡単にすることで配信ツールが取り込みやすくしています。

クライアントが HTTP POST で Offer SDP を送信して、Answer SDP を受け取るというシンプルなシグナリング規格です。

OBS 30.0.0 にて WebRTC/WHIP が正式にサポートされました。

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

以下からダウンロードができます。

https://obsproject.com/download

WHIP のシーケンス図

OBSWHIP EndpointMedia ServerWHIP ResourceOBSWHIP EndpointMedia ServerWHIP ResourceHTTP POST (SDP Offer)HTTP 201 Created (SDP Answer)WebRTC ConnectionHTTP DELETEHTTP 200 OK

Sora の WHIP のシーケンス図

Sora では WHIP エンドポイント、WHIP リソース、メディアサーバーすべてを Sora が担当します。

OBSSoraAppOBSSoraAppHTTP POST (SDP Offer)認証ウェブフック200 OKallowed : trueHTTP 201 Created (SDP Answer)WebRTC Connectionイベントウェブフックconnection.created200 OKHTTP DELETEイベントウェブフックconnection.destroyed200 OKHTTP 200 OK

OBS 以外の WHIP クライアントへの対応について

新しい WHIP クライアントへの対応は有償での優先実装として対応を検討できますので、 対応希望の WHIP クライアントと優先実装については、サポートまでメールにてご連絡ください。

Sora での利用方法

sora.conf にて whiptrue に指定してください。

whip = true

Bearer トークンを利用した認証機能を利用する場合

sora.conf にて whip_bearer_token_metadata_key を指定してください。

whip_bearer_token_metadata_key = access_token

例えば、 access_token という文字列をした場合、 WHIP 接続時、認証ウェブフックに "metadata": {"access_token": "<bearer_token>""} が入ってきます。 whip_bearer_token を指定した場合は "metadata": {"whip_bearer_token": "<bearer_token>""} が入ってきます。

whip_bearer_token_metadata_key が未指定の場合は、 Bearer トークンが WHIP 接続時に送られてきたとしても Sora は無視して、 metadata も生成しません。

OBS での利用方法

OBS での利用方法は以下の通りです。

  1. サービスに WHIP を選ぶ
  2. サーバーに Sora が提供する WHIP エンドポイント URL を指定する
    • デフォルトでは http://127.0.0.1:5000/whip/<channel_id>
  3. Bearer トークンには好きな文字列を指定する
    • Sora の認証ウェブフックの項目 whip_bearer_token_metadata_key で指定した値をキーとして、 "metadata": {"<whip_bearer_token_metadata_key>": "<bearer_token>""} が認証サーバーに送信されます

切断方法

Location ヘッダーに入ってくるリソースエンドポイント URL に DELETE リクエストを送ることで切断できます。

OBS は配信終了することで切断リクエストを送りますので、意識する必要はありません。

Sora の OBS (WHIP) の挙動

  • Sora は WHIP エンドポイント URL を提供します
    • デフォルトでは http://127.0.0.1:5000/whip/<channel_id> です
  • Sora の WHIP エンドポイントからの配信は、マルチストリームかつ配信のみ(sendonly)として扱われます
  • Sora の WHIP エンドポイントを利用した配信では、シグナリング通知は現時点では利用できません
  • Sora の WHIP リソース URL は WHIP エンドポイントのレスポンスに含まれる Location ヘッダーにて払い出されます

WHIP エンドポイント URL

Sora の OBS (WHIP) 対応は "multistream": true, "role": "sendonly" として機能します。

チャネル ID の指定

OBS ではリクエスト時に JSON でチャネル ID を指定することができません。そのため WHIP エンドポイント URL に channel_id を含めて指定します。 channel_id に URL に利用できない文字が含まれている場合は URL エンコードしてください。

HTTP POST https://sora.example.com/whip/<channel_id>

WHIP エンドポイント URL 例:

https://sora.example.com/whip/sora-channel

WHIP エンドポイントへの HTTP リクエストに対するレスポンスコードは 201 Created です。

WHIP リソース URL

Sora では WHIP リソースエンドポイントは Location ヘッダーに含まれています。

以下は切断する例です。

HTTP DELETE https://sora.example.com/whip-resource/<channel_id>/<secret>

以下は Trickle ICE を利用する例です。

HTTP PATCH https://sora.example.com/whip-resource/<channel_id>/<secret>

<secret> は 32 バイトのランダムな値を base32 でエンコードした文字列です。

WHIP リソース URL 例:

https://sora.example.com/whip-resource/sora/QBF6AFDWZGWM97BNS5YCBSXM54M01D0TFQ48MC9Z3ZJG8YPRQ1Z0

認証仕様

WHIP では認証に Bearer トークンを指定することが可能です。

OBS でも認証情報に Bearer トークンを指定できます。

Sora は sora.confwhip_bearer_token_metadata_key に文字列を指定していた場合、 OBS の HTTP POST 時に Authentication ヘッダーで送られてきた Bearer トークンを、 認証ウェブフックの metadata{"<whip_bearer_token_metadata_key>": "<bearer_token>"} を設定して認証サーバーに送信します。

Sora 自体は Bearer トークンのチェックやデコードなどは行いません。これらは認証ウェブフックのリクエストを受信した認証サーバーが行う必要があります。

ウェブフック仕様

whip

true が入ってきます。

metadata

sora.conf にて whip_bearer_token_metadata_key に指定した文字列をキーとして metadata に入ってきます。

whip_bearer_token_metadata_key = whip_bearer_token

もし文字列を whip_bearer_token にしていた場合は、 "metadata": {"whip_bearer_token": "<bearer-token>"} が送られてきます。

OBS 側に設定した Bearer Token の値がそのまま入ってきます。

multistream

true が入ってきます。

role

sendonly が入ってきます。

channel_id

WHIP エンドポイント URL に渡した値が利用されます。

client_id

WHIP エンドポイント URL にクエリ文字列として client_id=<client_id> を指定した場合、その値が利用されます。

bundle_id

WHIP エンドポイント URL にクエリ文字列として bundle_id=<bundle_id> を指定した場合、その値が利用されます。

spotlight

WHIP エンドポイント URL にクエリ文字列として spotlight=<boolean> を指定した場合、その値が利用されます。

既知の問題として spotlight = true を指定して接続した場合、音声がそのままでは配信されません。 FocusSpotlightFixed API を利用して OBS の接続にフォーカスを当てる必要があります。

詳細は 既知の問題 - OBS (WHIP) 対応機能 を参照してください。

audio / video

OBS 側で指定した値を利用します。 OBS では音声は Opus のみ、映像は H.264 が利用できます。

  • audio: true
  • audio_codec_type: "OPUS"
  • video: true
  • video_codec_type: "H264"

OBS 利用時にはビットレートの指定できないため、 Sora のデフォルトの値が入ってきますが、 OBS の WHIP 実装では SDP での最大ビットレートを無視します。 そのため OBS 側で設定したビットレートで配信が行われます。

simulcast

現時点では false が入ってきます。

その他

  • e2ee: false
  • spotlight: false
  • data_channel_signaling: false
  • ignore_disconnect_webhook: false
  • turn_transport_type: udp
    • TURN が利用不可能な WHIP 実装の場合は udp が割り当てられます
    • TURN が利用可能な WHIP 実装の場合は udp または tcp が適切に割り当てられます

クラスター利用時の挙動

現時点ではクラスター利用時に、接続したノードが指定した channel_id の担当ノードでは無い場合、 担当ノードの IP アドレスを Answer SDP に含めます。

将来的に OBS の WHIP 対応で TURN が対応された場合

クラスター利用時に、接続したノードが指定した channel_id の担当ノードでは無い場合、 担当ノードの TURN URLs を Link ヘッダーにて払い出します。

シーケンス図

シングルノード

OBSSoraAppOBSSoraAppHTTP POST https://sora.example.com/whip/<channel_id>Offer SDP認証ウェブフック"channel_id": "<channel_id>""multistream":true"role": "sendonly""allowed": trueHTTP 201 CreatedAnswer SDPこのタイミングで Link ヘッダーでTURN URLs を払い出すICE 確立DTLS 確立WebRTC 確立イベントウェブフック"connection.created"HTTP 200 OKSRTPSRTPHTTP DELETE https://sora.example.com/whip/<channel_id>/<secret>HTTP 200 OKWebRTC 終了

マルチノード

マルチノードを利用する場合、OBS に設定する WHIP エンドポイントは LB が提供するエンドポイントを利用します。

このシーケンス図では Sora が 2 ノードになっていますが、最低 3 ノード必要です。

OBS (WHIP)ブラウザLBSora 1Sora 2AppOBS (WHIP)ブラウザLBSora 1Sora 2AppparandWSShttps://node1.sora.example.com/signalingWSShttps://node2.sora.example.com/signalingWebSocket 確立WSS "type": "connect"認証ウェブフック"channel_id": "sora""multistream": true"role": "recvonly""allowed": true"type": "offer""type": "answer"WebRTC 確立HTTP POSThttps://sora.example.com/whip/soraOffer SDPHTTP POSThttps://node2.sora.example.com/whip/soraOffer SDP担当ノードに内部通信で処理を Proxy認証ウェブフック"channel_id": "sora""multistream": true"role": "sendonly""allowed": trueSora 2 の IP アドレス または TURN URLsHTTP 201 CreatedAnswer SDPHTTP 201 CreatedAnswer SDPこのタイミングで Link ヘッダーでTURN URLs を払い出すWebRTC 確立イベントウェブフック"connection.created"HTTP 200 OKSRTPSRTPSRTPSRTPHTTP DELETEhttps://node2.sora.example.com/whip/sora/<secret>HTTP 200 OKWebRTC 終了