OBS Studio WHIP 対応機能¶
注意
この機能を利用する場合は事前にサポートまでご連絡ください
警告
この機能は 実験的機能 のため、正式版では仕様が変更される可能性があります
概要¶
OBS Studio が対応している WHIP を利用した WebRTC 配信に対応しています。
ここでは Sora や OBS の WHIP 仕様について説明します。
注意¶
OBS の WHIP 実装の仕様を正としており RFC の WHIP 仕様とは異なる可能性があります
現時点では Sora SDK は WHIP へ対応していません
現時点では WHIP を利用した接続の統計ウェブフックの送信には対応していません
WHIP クライアントのお問い合わせについて¶
WHIP クライアントに関する質問などの報告は Discord の利用をお願いします。
Sora の WHIP クライアントについての質問やバグ報告は Discord の #sora-sdk-faq
チャンネルにお願いします。
WHIP とは何か¶
WHIP は WebRTC-HTTP ingestion protocol の略で、 WebRTC では標準化されていないシグナリングをブロードキャスト/ストリーミング系の配信ツール向けに規定した規格です。
WHIP は仕様を小さくして、実装を簡単にすることで配信ツールが取り込みやすくしています。
クライアントが HTTP POST で Offer SDP を送信して、Answer SDP を受け取るというシンプルなシグナリング規格です。
OBS 30.0.0 にて WebRTC/WHIP が正式にサポートされました。
最新版は以下からダウンロードができます。
https://obsproject.com/download
WHIP のシーケンス図¶
sequenceDiagram participant OBS as OBS participant WE as WHIP Endpoint participant MS as Media Server participant WS as WHIP Resource OBS->>+WE: HTTP POST (SDP Offer) WE-->>-OBS: HTTP 201 Created (SDP Answer) note over OBS,MS: WebRTC Connection OBS->>+WS: HTTP DELETE WS->>-OBS: HTTP 200 OK
Sora の WHIP のシーケンス図¶
Sora では WHIP エンドポイント、WHIP リソース、メディアサーバーすべてを Sora が担当します。
sequenceDiagram participant OBS as OBS participant S as Sora participant A as App OBS->>+S: HTTP POST (SDP Offer) S->>+A: 認証ウェブフック A-->>-S: 200 OK<br>allowed : true S-->>-OBS: HTTP 201 Created (SDP Answer) note over OBS,S: WebRTC Connection S->>+A: イベントウェブフック<br>connection.created A-->>-S: 200 OK OBS->>+S: HTTP DELETE S->>+A: イベントウェブフック<br>connection.destroyed A-->>-S: 200 OK S->>-OBS: HTTP 200 OK
OBS の WHIP 対応について¶
警告
OBS の WHIP 対応については Discord https://discord.gg/shiguredo の #sora-sdk-faq にてご相談ください。
2024 年 6 月 時点での OBS では WHIP 対応では輻輳制御が実装されていません。 これは OBS の WHIP 対応するために利用している libdatachannel が輻輳制御に対応していないためです。
そのため、回線が不安定になったとしても、ビットレートを下げたりするといったことは行いません。
H.265 (HEVC) 対応¶
- Pull-Request:
OBS 30.2 で H.265 が利用できるようになる予定です。
サイマルキャスト対応¶
- Pull-Request:
今後 OBS で対応される予定です。 Sora では 2024 年 12 月リリース予定の Sora にて対応予定です。
TURN 対応¶
- Pull-Request:
今後 OBS で対応される予定です。
Sora で OBS WHIP の TURN を有効にするには sora.conf
にて whip_turn を true
に指定してください。
OBS 以外の WHIP クライアントへの対応について¶
重要
Sora の WHIP 実装は OBS の WHIP 対応のみをサポートしています。 それ以外のクライアントの WHIP 実装には対応していません。
新しい WHIP クライアントへの対応は有償での優先実装として対応を検討できますので、 対応希望の WHIP クライアントと優先実装については、サポートまでメールにてご連絡ください。
ブラウザ
GStreamer
FFmpeg
Sora での利用方法¶
sora.conf
にて whip を true
に指定してください。
whip = true
Bearer トークンを利用した認証機能を利用する場合¶
sora.conf
にて whip_bearer_token_metadata_key を指定してください。
whip_bearer_token_metadata_key = whip_access_token
例えば、 access_token
という文字列をした場合、
WHIP 接続時、認証ウェブフックに "metadata": {"access_token": "<bearer_token>""}
が入ってきます。
whip_token
を指定した場合は "metadata": {"whip_token": "<bearer_token>""}
が入ってきます。
whip_bearer_token_metadata_key
が未指定の場合は、
Bearer トークンが WHIP 接続時に送られてきたとしても Sora は無視して、
metadata
も生成しません。
OBS での WHIP 利用方法¶
OBS での利用方法は以下の通りです。
サービスに WHIP を選ぶ
サーバーに Sora が提供する WHIP エンドポイント URL を指定する
デフォルトでは
http://127.0.0.1:5000/whip/<channel_id>
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>
channel_id
が sora の WHIP エンドポイント URL 例:
https://sora.example.com/whip/sora
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
注釈
OBS に Bearer トークンを指定した場合は、WHIP リソースエンドポイント URL にも Bearer トークンは送られます
認証仕様¶
WHIP では認証に Bearer トークンを指定することができます。
OBS でも認証情報に Bearer トークンを指定できます。
Sora は sora.conf
で whip_bearer_token_metadata_key
に文字列を指定していた場合、
OBS の HTTP POST 時に Authentication ヘッダーで送られてきた Bearer トークンを、
認証ウェブフックの metadata
に {"<whip_bearer_token_metadata_key>": "<bearer_token>"}
を設定して認証サーバーに送信します。
Sora 自体は Bearer トークンのチェックやデコードなどは行いません。これらは認証ウェブフックのリクエストを受信した認証サーバーが行う必要があります。
ウェブフック仕様¶
whip¶
true
が入ってきます。
ignore_disconnect_websocket¶
false
が入ってきます。
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 に渡した値が利用されます。
注釈
URL デコード済みの値が入ります
client_id¶
WHIP エンドポイント URL にクエリ文字列として client_id=<client_id>
を指定した場合、その値が利用されます。
注釈
URL デコード済みの値が入ります
bundle_id¶
WHIP エンドポイント URL にクエリ文字列として bundle_id=<bundle_id>
を指定した場合、その値が利用されます。
注釈
URL デコード済みの値が入ります
spotlight¶
WHIP エンドポイント URL にクエリ文字列として spotlight=<boolean>
を指定した場合、その値が利用されます。
既知の問題として spotlight = true
を指定して接続した場合、音声がそのままでは配信されません。 FocusSpotlightFixed API を利用して OBS の接続にフォーカスを当てる必要があります。
詳細は 既知の問題 - OBS 対応機能 を参照してください。
注釈
URL デコード済みの値が入ります
audio / video¶
OBS 側で指定した値を利用します。 OBS では音声は Opus のみ、映像は H.264 と H.265 と AV1 が利用できます。
audio: true
audio_codec_type: "OPUS"
video: true
video_codec_type: "H264" | "AV1"
OBS 利用時にはビットレートの指定できないため、 Sora のデフォルトの値が入ってきますが、 OBS の WHIP 実装では SDP での最大ビットレートを無視します。 そのため OBS 側で設定したビットレートで配信が行われます。
警告
H.265 は OBS 30.2 で利用できるようになります
simulcast¶
注意
現時点では OBS の WHIP 対応はサイマルキャストに未対応です。OBS 側の対応待ちです。
現時点では false
が入ってきます。
sora_client¶
OBS WHIP で User-Agent として送られてくる情報を sora_client
に含めています。
"sora_client": {
"raw": "Mozilla/5.0 (OBS-Studio/30.1.0; Mac OS X; ja-JP)",
"type": "OBS-Studio-WHIP",
"version": "30.1.0",
"environment": "environment":"Mozilla/5.0 (OBS-Studio/30.1.0; Mac OS X; ja-JP)"
},
その他¶
e2ee: false
spotlight: false
data_channel_signaling: false
ignore_disconnect_webhook: false
turn_transport_type: udp
OBS はまだ TURN に対応していません
対応したとしても TURN-UDP のみなのでここが tcp になる事はありません
認証ウェブフック成功時の払い出し¶
基本的には OBS で指定した値がそのまま利用されますので、 以下の値以外は指定することはお勧めしません。
client_id
bundle_id
event_metadata
recording_block
signaling_notify_metadata
connection_lifetime
cluster_affinity
playout_delay_min_delay
playout_delay_max_delay
rtp_packet_loss_simulator_incoming
クラスター利用時の認証ウェブフックの挙動¶
クラスター利用時に、 WHIP で接続したノードではないノードに接続を振り分ける場合、 Sora は認証情報を担当ノードに Proxy を行います。
接続は接続したノードで行われますが、認証ウェブフックは担当ノードから送信されます。 その後 WebRTC 接続確立は担当ノードと行います。
シーケンス図¶
sequenceDiagram participant O as OBS (WHIP) participant S1 as Sora 1 participant S2 as Sora 2 participant A as App O->>+S1: HTTP POST<br>https://sora-02.example.com/whip/sora<br>Offer SDP Note over S1: 担当ノードは Sora 2 S1->>+S2: ノード間通信で認証処理を Proxy S2->>+A: 認証ウェブフック<br>"channel_id": "sora"<br>"multistream": true<br>"role": "sendonly" A-->>-S2: "allowed": true S2-->>-S1: Sora 2 の IP アドレス S1-->>-O: HTTP 201 Created<br>Answer SDP<br>Candidate: Sora 2 IP アドレス note over O,S2: WebRTC 確立 S1->>+A: イベントウェブフック<br>"connection.created" A-->>-S2: HTTP 200 OK O-)S2: SRTP O-)S2: SRTP O->>+S2: HTTP DELETE<br>https://sora-02.example.com/whip/sora/<secret> S2-->>-O: HTTP 200 OK note over O,S2: WebRTC 終了
TURN の利用¶
注意
現時点では 正式リリース版 OBS は WHIP の Link
ヘッダーを利用した TURN Urls の払い出しに未対応です。
既に対応 Pull-Request がマージ済で、リリース待ちです。
sora.conf
で whip_turn を有効にすることで Sora は Link
ヘッダーに TURN URLs を払い出します。
Sora の仕様として TURN を有効にした場合は TURN のみの通信 を行います、 そのため TURN に対応していない OBS が利用できなくなります。
OBS の TURN 機能¶
OBS で WebRTC を実現している libdatachannel が利用している ICE ライブラリの libjuice は、 TURN-UDP のみに対応しています。 そのため TURN-TCP や TURN-TLS には対応していません。
録画利用時の注意¶
OBS WHIP で H.264 を利用している場合、 x264 以外を利用することを推奨します
クラスター利用時の挙動¶
現時点ではクラスター利用時に、接続したノードが指定した channel_id
の担当ノードでは無い場合、
担当ノードの IP アドレスを Answer SDP に含めます。
OBS の WHIP 対応で TURN へ対応した場合¶
クラスター利用時に、接続したノードが指定した channel_id
の担当ノードでは無い場合、
担当ノードの TURN URLs を Link ヘッダーにて払い出します。
シーケンス図¶
単独¶
sequenceDiagram participant O as OBS participant S as Sora participant A as App O->>+S: HTTP POST https://sora.example.com/whip/<channel_id><br>Offer SDP S->>+A: 認証ウェブフック<br><br>"channel_id": "<channel_id>""multistream": true<br>"role": "sendonly" A-->>-S: "allowed": true S-->>-O: HTTP 201 Created<br>Answer SDP Note left of S: このタイミングで Link ヘッダーで、<br>TURN URLs を払い出す note over O,S: ICE 確立 note over O,S: DTLS 確立 note over O,S: WebRTC 確立 S->>+A: イベントウェブフック<br>"connection.created" A-->>-S: HTTP 200 OK O-)S: SRTP O-)S: SRTP O->>+S: HTTP DELETE https://sora.example.com/whip/<channel_id>/<secret> S-->>-O: HTTP 200 OK note over O,S: WebRTC 終了
クラスターかつロードバランサー¶
クラスターを利用する場合、OBS に設定する WHIP エンドポイントはロードバランサーが提供するエンドポイントをお勧めしています。
このシーケンス図では Sora が 2 ノードになっていますが、最低 3 ノード必要です。
sequenceDiagram participant O as OBS (WHIP) participant B as ブラウザ participant LB as LB participant S1 as Sora 1 participant S2 as Sora 2 participant A as App par B-xS1: WSS<br>https://node1.sora.example.com/signaling and B->>S2: WSS<br>https://node2.sora.example.com/signaling<br> note over B,S2: WebSocket 確立 end B->>S2: WSS "type": "connect" S2->>+A: 認証ウェブフック<br>"channel_id": "sora"<br>"multistream": true<br>"role": "recvonly" A-->>-S2: "allowed": true S2-)B: "type": "offer" B-)S2: "type": "answer" note over B,S2: WebRTC 確立 O->>+LB: HTTP POST<br>https://sora.example.com/whip/sora<br>Offer SDP LB->>+S1: HTTP POST<br>https://node2.sora.example.com/whip/sora<br>Offer SDP S1->>+S2: 担当ノードに内部通信で処理を Proxy S2->>+A: 認証ウェブフック<br>"channel_id": "sora"<br>"multistream": true<br>"role": "sendonly" A-->>-S2: "allowed": true %% S2-->>-S1: Sora 2 の IP アドレス または TURN URLs S2-->>-S1: Sora 2 の IP アドレス S1-->>-LB: HTTP 201 Created<br>Answer SDP LB-->>-O: HTTP 201 Created<br>Answer SDP %% Note left of S2: このタイミングで Link ヘッダーで、<br>TURN URLs を払い出す note over O,S2: WebRTC 確立 S1->>+A: イベントウェブフック<br>"connection.created" A-->>-S2: HTTP 200 OK O-)S2: SRTP S2-)B: SRTP O-)S2: SRTP S2-)B: SRTP O->>+S2: HTTP DELETE<br>https://node2.sora.example.com/whip/sora/<secret> S2-->>-O: HTTP 200 OK note over O,S2: WebRTC 終了