セッションウェブフック¶
概要¶
セッションウェブフックは、セッションの状態を送信するウェブフックです。
例えばチャネルに誰も接続していない状態で新しく接続されたタイミングや、 誰も接続しない状態が一定時間続いたタイミングで、 ウェブフックを利用してセッションの状態などを HTTP リクエストで送信する機能です。
また、セッション開始時にウェブフックの戻り値で録画開始や音声ストリーミングなどを指定することができ、 今まで API を叩いていた処理をウェブフックで行うことができるようになります。
目的¶
セッションは実際にチャネルに参加しているクライアントの集まりです。
もともと Sora にはチャネルを作るという概念がありません。 チャネルに誰も接続していない状態で、新しく接続があれば、チャネルが利用されている状態になります。
そのため、チャネルが利用されているかどうかの判断は HTTP API を利用したり、 イベントウェブフックリクエストの送信を利用したりして、アプリケーション側で判断する必要がありました。
このセッションウェブフックは、新しくチャネルに状態を持たせ、 その状態をウェブフックリクエストで送信することで、API やイベントウェブフックを利用せずに、 チャネルの状態を判断することができるようになります。
セッション ID¶
特定の期間チャネルに接続していたクライアントをグルーピングするために、 Sora はセッション ID という値を払い出します。 セッション ID は Sora が指定するため、書き換えることはできません。
セッション ID は UUIDv4 を Base32 でエンコードした 26 バイトの文字列です。
ログ¶
セッションウェブフックのログは log/session_webhook.jsonl と log/session_webhook_error.jsonl に出力されます。
これは session_webhook_url を指定していなくても出力されます。
session_webhook.jsonl¶
セッションウェブフックで送信した すべて の処理を書き込みます。
session_webhook_error.jsonl¶
セッションウェブフックの送信が正常に処理できなかった処理を書き込みます。
ステータスコードが 200 番台以外の場合
タイムアウトした場合
設定¶
session_webhook_url¶
セッションウェブフックリクエストの送信先を指定してください。
session_webhook_url = https://example.com/sora/session/webhook
session_created_timeout¶
セッションが存在しない状態で、新しくセッションを生成する際の制限時間です。 これはセッションウェブフック処理も含めた時間で、この時間を超えるとタイムアウトとなり、切断されます。
デフォルトでは 5 秒です。
session_created_timeout = 5 s
session_destroyed_timeout¶
そのチャネルの接続数が 0 になってから新しい接続が無い場合に、 session.destroyed のセッションウェブフックリクエストを送信するまでの時間を指定します。
デフォルトでは 15 秒です。
session_destroyed_timeout = 15 s
session_updated_webhook_interval¶
session.updated の送信間隔を指定します。
デフォルトでは 1 min (1 分) です。単位は min しか指定できません。
session_updated_webhook_interval = 1 min
ログ¶
セッションウェブフックのログは log/session_webhook.jsonl と log/session_webhook_error.jsonl に出力されます。
これは session_webhook_url を指定していなくても出力されます。
session_webhook.jsonl¶
セッションウェブフックの送信が 正常に動作した 処理を書き込みます。
項目¶
id
Base32 UUIDv4
timestamp
RFC 3339 UTC マイクロ秒
req
リクエスト
センシティブデータはマスクされます
res
レスポンス
センシティブデータはマスクされます
url
セッションウェブフック URL
セッションウェブフックが指定されていなければ含まれません
session_webhook_error.jsonl¶
セッションウェブフックの送信が正常に処理できなかった処理を書き込みます。
ステータスコードが 200 番台以外の場合
タイムアウトした場合
項目¶
id
Base32 UUIDv4
timestamp
RFC 3339 UTC マイクロ秒
req
リクエスト
センシティブデータはマスクされません
reason
ウェブフックエラー理由
url
セッションウェブフック URL
セッションウェブフックが指定されていなければ含まれません
spotlight が既存セッションと異なる場合の挙動¶
既存セッションが存在する場合、 spotlight が異なる新規接続が来た場合は、
INVALID-MESSAGE エラーを返し切断するようになります。
session.created¶
セッション生成
同時接続数が 0 のチャネル ID に対して、新しい接続の認証が成功したタイミングで session.created ウェブフックリクエストを送信します。
チャネルの同時接続数が 0 の場合でも、 spotlight の値が一致するセッションが過去に生成されており、
まだ破棄されていない場合には、そのセッションが使用されるため session.created ウェブフックは送信されません。
キー |
型 |
内容 |
|---|---|---|
type |
string |
"session.created" |
id |
string |
ウェブフック ID (ユニーク) |
label |
string |
sora.conf の label にて指定した値 |
node_name |
string |
Sora ノード名 |
version |
string |
Sora のバージョン |
channel_id |
string |
チャネル ID |
session_id |
string |
セッション ID |
timestamp |
string (RFC3339 UTC マイクロ秒) |
ウェブフック作成時間 |
created_time |
integer (UNIX 時間) |
セッション生成時間 |
created_timestamp |
string (RFC3339 UTC マイクロ秒) |
セッション生成時間 |
spotlight |
boolean |
スポットライトが有効かどうか |
external_signaling_url |
string |
(クラスター機能が有効の場合) 接続先の external_signaling_url |
{
"channel_id": "sora",
"created_time": 1638337454,
"created_timestamp": "2021-12-01T05:44:14.523736Z",
"id": "2YN2DQE5KD3GSFSVPAYZ7VTAV4",
"label": "WebRTC SFU Sora",
"spotlight": false,
"node_name": "[email protected]",
"session_id": "NPR769YPQ914K10FW42PGH4TKW",
"timestamp": "2021-12-01T05:44:14.523912Z",
"external_signaling_url": "wss://node-01.example.com/signaling",
"type": "session.created",
"version": "2023.2.0"
}
戻り値¶
セッションウェブフックは "type": "session.created" の戻り値を指定できます。
session_metadata¶
注釈
この項目はセンシティブデータとして扱われます。
session_metadata を指定した場合、セッション更新時の session.updated とセッション破棄時の "type": "session.destroyed" のウェブフックリクエストに session_metadata が含まれます。
{
"session_metadata": "<JSON>"
}
session_lifetime¶
セッション生成のタイミングで、セッションのライフタイムを指定することができます。
例えば 3600 を指定した場合、 3600 秒後にセッションは破棄されます
{
"session_lifetime": 3600
}
session_lifetimeの指定にかかわらず、セッションの同時接続数が 0 になると、 session_destroyed_timeout に指定した時間が経過したタイミングでセッションが破棄されます秒 で指定してください
最大 2,592,000 秒 (30 日) まで指定できます
セッション生成後に変更することはできません
session_lifetimeが未指定の場合は 無制限 ですsession.destroyedのreasonにlifetime_expiredが入りますconnection.destroyedのreasonにsession_destroyedが入りますセッションのライフタイムが終了すると、セッションが破棄され切断します
セッションのライフタイムが終了すると、セッションウェブフック
session.destroyedが送信されます
spotlight_number¶
セッション生成のタイミングで、スポットライト機能が有効な場合に、スポットライトの数を指定することができます。
クライアント単位でのシグナリング接続時や認証ウェブフック成功時の spotlight_number と異なる値を払い出した場合、
エラーとなりますので注意してください。 spotlight_number はセッションウェブフックでの指定を推奨します。
セッション単位の spotlight_number を変更するには ChangeSpotlightNumber API を利用する必要があります。
{
"spotlight_number": 3
}
group_id¶
セッション生成のタイミングで、セッションをグルーピングする group_id を指定することができます。
ListSessions API にて group_id を指定することで、指定した group_id のセッションのみを返します。
group_id は 1 バイト以上 255 バイト以下の文字列です。未指定の場合は session_id が入ります。
{
"group_id": "group_01"
}
duplicate_client_id¶
セッション生成のタイミングで、
クライアント ID が重複した場合の挙動を duplicate_client_id で指定することができます。
duplicate_client_id に evict を指定した場合、
既に接続している同一クライアント ID の接続を破棄するような挙動になります。
duplicate_client_id には allow または evict を指定できます。
allowは今まで通り重複を許容しますevictは既存の接続を破棄し、新規接続を受け入れます、つまり既存接続を追い出します
未指定の場合は sora.conf の default_duplicate_client_id の値を利用します。
{
"duplicate_client_id": "evict"
}
max_connections¶
max_connectionsを指定した場合、セッション単位での最大同時接続数が指定した値になります。途中で最大同時接続数を変更することはできません。指定できる範囲は
0..10000ですmax_connectionsが0の場合は誰も接続することができなくなりますセッションが同時接続数制限に達した場合はクライアントに
SERVICE-UNAVAILABLEを通知しますセッションが同時接続数制限に達した場合は ignore_connection_failed_webhook が
falseの場合は connection.failed が送信されますmessageに"SERVICE-UNAVAILABLE"が含まれます
{
"max_connections": 3
}
注意
trial_max_connectionsは 2025 年 12 月リリース予定の Sora にて廃止します。今後は
max_connectionsを指定してください。trial_max_connectionsとmax_connectionsを同時に指定した場合はmax_connectionsが優先されますtrial_max_connections廃止後は無視します
recording¶
recording を true を指定した場合、セッション単位の録画を開始します。
詳細は 録画機能 (セッション単位) の session.created をご確認ください。
{
"recording": true
}
recording_expire_time¶
recordingがtrueの場合のみ有効です。録画の有効期限を秒単位で指定しますrecording_expire_timeを3600を指定した場合、 3600 秒後に録画は終了します
詳細は 録画機能 (セッション単位) の session.created をご確認ください。
{
"recording_expire_time": 3600
}
recording_split_only¶
recordingがtrueの場合のみ有効です。録画を分割のみで行うかどうかを指定しますrecording_split_onlyをtrueに指定した場合、録画は分割のみで行われます
詳細は 録画機能 (セッション単位) の session.created をご確認ください。
{
"recording_split_only": true
}
recording_split_duration¶
recordingがtrueの場合のみ有効です。分割録画の分割時間を秒単位で指定しますrecording_split_durationを60を指定した場合、 60 秒ごとに録画が分割されます
詳細は 録画機能 (セッション単位) の session.created をご確認ください。
{
"recording_split_duration": 60
}
recording_metadata¶
recording が true の場合のみ有効です。recording.report ウェブフックやレポートファイルに含まれます。
詳細は 録画機能 (セッション単位) の session.created をご確認ください。
{
"recording_metadata": {"spam": "egg"}
}
recording_format¶
recording が true の場合のみ有効です。録画ファイルのフォーマットを指定します。
webm と mp4 が指定できます。
詳細は 録画機能 (セッション単位) の session.created をご確認ください。
{
"recording_format": "mp4"
}
forwarding_filters¶
forwarding_filters を指定した場合、転送フィルターをセッションに対して反映することができます。
転送フィルタールールの詳細については 転送フィルター機能 をご確認ください。
{
"forwarding_filters": [
{
"action": "allow",
"rules": [
// チャネルに接続しているすべてのコネクションに音声のみ転送する
[
{"field": "kind", "operator": "is_in", "values": ["audio"]}
]
]
}
]
}
forwarding_filter¶
注意
forwarding_filter は 2025 年 12 月リリース予定の Sora にて廃止します。
forwarding_filter を指定した場合、転送フィルターをセッションに対して反映することができます。
転送フィルタールールの詳細については 転送フィルター機能 をご確認ください。
{
"forwarding_filter": {
"action": "allow",
"rules": [
// チャネルに接続しているすべてのコネクションに音声のみ転送する
[
{"field": "kind", "operator": "is_in", "values": ["audio"]}
]
]
}
}
audio_streaming¶
audio_streaming を true に指定した場合、そのセッションで音声ストリーミングが有効になります。
音声ストリーミング機能の詳細については 音声ストリーミング機能 をご確認ください。
{
"audio_streaming": true
}
audio_streaming_auto¶
audio_streaming_auto を true に指定した場合、そのセッションで音声ストリーミングが有効になり、
かつ自動開始、自動停止機能が有効になります。
この設定を true にするときには audio_streaming も true に設定する必要があります。
詳細は audio_streaming 関連の払い出し設定の組み合わせによる動作 をご確認ください。
{
"audio_streaming": true,
"audio_streaming_auto": true
}
session.destroyed¶
セッション破棄
同時接続数が 0 になったチャネル ID が一定時間経過したタイミングで、 session.destroyed ウェブフックリクエストを送信します。
キー |
型 |
内容 |
|---|---|---|
type |
string |
"session.destroyed" |
id |
string |
ウェブフック ID (ユニーク) |
label |
string |
sora.conf の label にて指定した値 |
node_name |
string |
Sora ノード名 |
version |
string |
Sora のバージョン |
channel_id |
string |
チャネル ID |
group_id |
string |
セッションをグルーピングする ID |
session_id |
string |
セッション ID |
timestamp |
string (RFC3339 UTC マイクロ秒) |
ウェブフック作成時間 |
created_time |
integer (UNIX 時間) |
セッション生成時間 |
created_timestamp |
string (RFC3339 UTC マイクロ秒) |
セッション生成時間 |
destroyed_time |
integer (UNIX 時間) |
セッション破棄時間 |
destroyed_timestamp |
string (RFC3339 UTC マイクロ秒) |
セッション破棄時間 |
spotlight |
boolean |
スポットライトが有効かどうか |
spotlight_number |
integer |
スポットライトが有効な場合、スポットライト数 |
total_connections |
integer |
延べ接続数 |
max_connections |
integer |
最大同時接続数 |
connections |
array (object) |
(クラスター機能が無効の場合) セッションに参加した接続情報 |
session_metadata |
json |
(値がある場合) session.created の戻り値で指定した値 |
external_signaling_url |
string |
(クラスター機能が有効の場合) 接続先の external_signaling_url |
reason |
string |
セッションが破棄された理由 ("normal", "validation_error", "webhook_error", "terminated_api", "lifetime_expired", "abort") |
{
"channel_id": "sora",
"connections": [
{
"audio": true,
"audio_codec_type": "OPUS",
"client_id": "W9QE86Z0BS1QFFPZ2QB5DRZ2HC",
"bundle_id": "W9QE86Z0BS1QFFPZ2QB5DRZ2HC",
"connection_id": "W9QE86Z0BS1QFFPZ2QB5DRZ2HC",
"connection_created_timestamp": "2021-12-01T05:44:23.051704Z",
"connection_destroyed_timestamp": "2021-12-01T05:44:57.083215Z",
"role": "sendrecv",
"simulcast": false,
"video": true,
"video_bit_rate": 1000,
"video_codec_type": "VP9",
"video_vp9_params": { "profile_id": 0 },
},
{
"audio": true,
"audio_codec_type": "OPUS",
"client_id": "JXMYW6GPX54EH0HGA5X4130FBM",
"bundle_id": "JXMYW6GPX54EH0HGA5X4130FBM",
"connection_id": "JXMYW6GPX54EH0HGA5X4130FBM",
"connection_created_timestamp": "2021-12-01T05:44:21.500272Z",
"connection_destroyed_timestamp": "2021-12-01T05:44:56.878019Z",
"role": "sendrecv",
"simulcast": false,
"video": true,
"video_bit_rate": 1000,
"video_codec_type": "VP9",
"video_vp9_params": { "profile_id": 0 },
},
{
"audio": true,
"audio_codec_type": "OPUS",
"client_id": "F8VK9R71BN5S5EDE737C8XAA3C",
"bundle_id": "F8VK9R71BN5S5EDE737C8XAA3C",
"connection_id": "F8VK9R71BN5S5EDE737C8XAA3C",
"connection_created_timestamp": "2021-12-01T05:44:19.811385Z",
"connection_destroyed_timestamp": "2021-12-01T05:44:55.897819Z",
"role": "sendrecv",
"simulcast": false,
"video": true,
"video_bit_rate": 1000,
"video_codec_type": "VP9",
"video_vp9_params": { "profile_id": 0 },
},
{
"audio": true,
"audio_codec_type": "OPUS",
"client_id": "VBYS5TV5S510F98GS2VK015AKG",
"bundle_id": "VBYS5TV5S510F98GS2VK015AKG",
"connection_id": "VBYS5TV5S510F98GS2VK015AKG",
"connection_created_timestamp": "2021-12-01T05:44:14.716974Z",
"connection_destroyed_timestamp": "2021-12-01T05:44:57.197372Z",
"role": "sendrecv",
"simulcast": false,
"video": true,
"video_bit_rate": 1000,
"video_codec_type": "VP9",
"video_vp9_params": { "profile_id": 0 },
}
],
"created_time": 1638337454,
"created_timestamp": "2021-12-01T05:44:14.523736Z",
"destroyed_time": 1638337502,
"destroyed_timestamp": "2021-12-01T05:45:02.199179Z",
"id": "M7K1AVS9KS34V9XFJJH04TB400",
"label": "WebRTC SFU Sora",
"max_connections": 4,
"node_name": "[email protected]",
"group_id": "NPR769YPQ914K10FW42PGH4TKW",
"session_id": "NPR769YPQ914K10FW42PGH4TKW",
"spotlight": false,
"timestamp": "2021-12-01T05:45:02.199419Z",
"total_connections": 4,
"session_metadata": {"spam": "egg"},
"type": "session.destroyed",
"version": "2023.2.0"
}
connections¶
connections に入ってくる以下の二つは RFC3339 形式の時間ではなく null が入ってくる場合があります。
connection_created_timestamp
connection_destroyed_timestamp
これは、認証は成功し、セッションに参加はしたが、何らかの理由で WebRTC が確立に失敗した場合発生します。
両方ともの値に null が入ってきます。
reason¶
session.destroyed には reason が含まれ、セッションが破棄された理由が入ります。
"normal"は通常のセッション破棄"validation_error"は session.created の戻り値が正常ではなかったことによるエラーによるセッション破棄このセッション破棄は session_created_response_validate_warning_as_error が
trueの場合のみ発生します例外: 転送フィルター機能 に関するバリデーション失敗は、この設定に関わらずエラーになりセッション破棄になります
"webhook_error"はセッション生成時のウェブフック session.created のウェブフック処理中にエラーが発生したことによるセッション破棄以下はエラー例です
session_webhook_url と接続できなかった場合
ウェブフック送信先からステータスコードが 2XX 以外だった場合
ウェブフック送信先からの JSON がパースできなかった場合
ウェブフック送信先からの JSON のパース結果が JSON Object 以外だった場合
ウェブフック送信先との HTTPS に失敗した場合
ウェブフック送信先との mTLS に失敗した場合
"terminated_api"は TerminateSession API によるセッション破棄"lifetime_expired"はセッションライフタイムの期限切れによるセッション破棄"abort"は異常発生のセッション破棄
クラスター有効時¶
クラスター有効時には connections 項目は含まれません。
{
"channel_id": "sora",
"created_time": 1638337454,
"created_timestamp": "2021-12-01T05:44:14.523736Z",
"destroyed_time": 1638337502,
"destroyed_timestamp": "2021-12-01T05:45:02.199179Z",
"id": "M7K1AVS9KS34V9XFJJH04TB400",
"label": "WebRTC SFU Sora",
"max_connections": 4,
"node_name": "[email protected]",
"group_id": "NPR769YPQ914K10FW42PGH4TKW",
"session_id": "NPR769YPQ914K10FW42PGH4TKW",
"spotlight": false,
"timestamp": "2021-12-01T05:45:02.199419Z",
"reason": "normal",
"total_connections": 4,
"session_metadata": {"spam": "egg"},
"external_signaling_url": "wss://node-01.example.com/signaling",
"type": "session.destroyed",
"version": "2023.2.0"
}
session.updated¶
セッション更新
注釈
このウェブフックリクエストの送信を停止することができます。
sora.conf の ignore_session_updated_webhook を true にしてください。
session.created 送信後、一定間隔で session.updated ウェブフックリクエストを送信します。
送信間隔はデフォルトで 1 分です。 session_updated_webhook_interval で送信間隔を変更できます。
session.updated の状態を記録することで、もし何らかの理由で session.destroyed が送信されなかった場合でも、
そのセッションが存在しているかどうかの判断を行う事ができるようになります。
キー |
型 |
内容 |
|---|---|---|
type |
string |
"session.updated" |
id |
string |
ウェブフック ID (ユニーク) |
label |
string |
sora.conf の label にて指定した値 |
node_name |
string |
Sora ノード名 |
version |
string |
Sora のバージョン |
channel_id |
string |
チャネル ID |
group_id |
string |
セッションをグルーピングする ID |
session_id |
string |
セッション ID |
timestamp |
string (RFC3339 UTC マイクロ秒) |
ウェブフック作成時間 |
created_time |
integer (UNIX 時間) |
セッション生成時間 |
created_timestamp |
string (RFC3339 UTC マイクロ秒) |
セッション生成時間 |
spotlight |
boolean |
スポットライトが有効かどうか |
spotlight_number |
integer |
スポットライトが有効な場合、スポットライト数 |
total_connections |
integer |
延べ接続数 |
max_connections |
integer |
最大同時接続数 |
connections |
array (object) |
(クラスター機能が有効の場合) セッションに参加した接続情報 |
session_metadata |
json |
(値がある場合) session.created の戻り値で指定した値 |
external_signaling_url |
string |
(クラスター機能が有効の場合) 接続先の external_signaling_url |
{
"channel_id": "sora",
"connections": [
{
"audio": true,
"audio_codec_type": "OPUS",
"client_id": "W9QE86Z0BS1QFFPZ2QB5DRZ2HC",
"bundle_id": "W9QE86Z0BS1QFFPZ2QB5DRZ2HC",
"connection_id": "W9QE86Z0BS1QFFPZ2QB5DRZ2HC",
"connection_created_timestamp": "2021-12-01T05:44:23.051704Z",
"connection_destroyed_timestamp": "2021-12-01T05:44:57.083215Z",
"role": "sendrecv",
"simulcast": false,
"video": true,
"video_bit_rate": 1000,
"video_codec_type": "VP9",
"video_vp9_params": { "profile_id": 0 },
},
{
"audio": true,
"audio_codec_type": "OPUS",
"client_id": "JXMYW6GPX54EH0HGA5X4130FBM",
"bundle_id": "JXMYW6GPX54EH0HGA5X4130FBM",
"connection_id": "JXMYW6GPX54EH0HGA5X4130FBM",
"connection_created_timestamp": "2021-12-01T05:44:21.500272Z",
"connection_destroyed_timestamp": "2021-12-01T05:44:56.878019Z",
"role": "sendrecv",
"simulcast": false,
"video": true,
"video_bit_rate": 1000,
"video_codec_type": "VP9",
"video_vp9_params": { "profile_id": 0 },
},
{
"audio": true,
"audio_codec_type": "OPUS",
"client_id": "F8VK9R71BN5S5EDE737C8XAA3C",
"bundle_id": "F8VK9R71BN5S5EDE737C8XAA3C",
"connection_id": "F8VK9R71BN5S5EDE737C8XAA3C",
"connection_created_timestamp": "2021-12-01T05:44:19.811385Z",
"connection_destroyed_timestamp": "2021-12-01T05:44:55.897819Z",
"role": "sendrecv",
"simulcast": false,
"video": true,
"video_bit_rate": 1000,
"video_codec_type": "VP9",
"video_vp9_params": { "profile_id": 0 },
},
{
"audio": true,
"audio_codec_type": "OPUS",
"client_id": "VBYS5TV5S510F98GS2VK015AKG",
"bundle_id": "VBYS5TV5S510F98GS2VK015AKG",
"connection_id": "VBYS5TV5S510F98GS2VK015AKG",
"connection_created_timestamp": "2021-12-01T05:44:14.716974Z",
"connection_destroyed_timestamp": "2021-12-01T05:44:57.197372Z",
"role": "sendrecv",
"simulcast": false,
"video": true,
"video_bit_rate": 1000,
"video_codec_type": "VP9",
"video_vp9_params": { "profile_id": 0 },
}
],
"created_time": 1638337454,
"created_timestamp": "2021-12-01T05:44:14.523736Z",
"id": "M7K1AVS9KS34V9XFJJH04TB400",
"label": "WebRTC SFU Sora",
"max_connections": 4,
"node_name": "[email protected]",
"group_id": "NPR769YPQ914K10FW42PGH4TKW",
"session_id": "NPR769YPQ914K10FW42PGH4TKW",
"spotlight": false,
"timestamp": "2021-12-01T05:45:02.199419Z",
"total_connections": 4,
"session_metadata": {"spam": "egg"},
"external_signaling_url": "wss://node-01.example.com/signaling",
"type": "session.updated",
"version": "2023.2.0"
}
connections¶
connections に入ってくる以下の二つは RFC3339 形式の時間ではなく null が入ってくる場合があります。
connection_created_timestamp
connection_destroyed_timestamp
これは、認証は成功し、セッションに参加はしたが、何らかの理由で WebRTC が確立に失敗した場合発生します。
両方ともの値に null が入ってきます。
クラスター有効時¶
クラスター有効時には connections 項目は含まれません。
{
"channel_id": "sora",
"created_time": 1638337454,
"created_timestamp": "2021-12-01T05:44:14.523736Z",
"id": "M7K1AVS9KS34V9XFJJH04TB400",
"label": "WebRTC SFU Sora",
"max_connections": 4,
"node_name": "[email protected]",
"group_id": "NPR769YPQ914K10FW42PGH4TKW",
"session_id": "NPR769YPQ914K10FW42PGH4TKW",
"spotlight": false,
"timestamp": "2021-12-01T05:45:02.199419Z",
"total_connections": 4,
"session_metadata": {"spam": "egg"},
"external_signaling_url": "wss://node-01.example.com/signaling",
"type": "session.updated",
"version": "2023.2.0"
}
録画機能 (セッション単位) 有効時¶
セッションで録画機能 (セッション単位) が有効な場合、 "recording" が含まれます。
録画が有効ではない場合は "recording" 項目は含まれません。
キー |
型 |
内容 |
|---|---|---|
recording_id |
string |
録画機能 (セッション単位) の ID |
format |
string |
録画機能 (セッション単位) のフォーマット |
start_timestamp |
string |
セッションでの録画が開始された時刻 (RFC 3339 (UTC)) |
split_only |
boolean |
セッションでの録画が分割のみかどうか |
recording_metadata (オプション) |
JSONValue |
録画機能 (セッション単位) のメタデータ |
expire_time (オプション) |
integer |
セッションでの録画期限 |
expired_at (オプション) |
integer |
セッションでの録画期限 (Unix time) |
split_duration (オプション) |
integer |
セッションでの録画分割有効時の分割時間 |
{
"channel_id": "sora",
"created_time": 1638337454,
"created_timestamp": "2021-12-01T05:44:14.523736Z",
"id": "M7K1AVS9KS34V9XFJJH04TB400",
"label": "WebRTC SFU Sora",
"max_connections": 4,
"node_name": "[email protected]",
"group_id": "NPR769YPQ914K10FW42PGH4TKW",
"session_id": "NPR769YPQ914K10FW42PGH4TKW",
"spotlight": false,
"timestamp": "2021-12-01T05:45:02.199419Z",
"total_connections": 4,
"session_metadata": {"spam": "egg"},
"external_signaling_url": "wss://node-01.example.com/signaling",
"type": "session.destroyed",
"version": "2023.2.0",
"recording": {
"recording_id": "WHEJ888HQ55KDCFE3TZ4VPFQHR",
"format": "mp4",
"recording_metadata": {"spam": "egg"},
"expire_time": 3600,
"expired_at": 1615527737,
"split_duration": 3600,
"split_only": false,
"start_timestamp": "2021-03-12T04:42:17.455668Z"
}
}
recording.started¶
重要
このウェブフックリクエストが送信されるにはセッションベースの録画を利用する必要があります
録画開始
data.start_timestamp
録画機能 (セッション単位) を開始したタイムスタンプ (RFC3339 UTC マイクロ秒) が入ります
data.expire_time
この項目はオプションです
API による開始を行った場合は StartRecording API で指定した
expire_timeが入りますsession.created ウェブフックリクエストの戻り値により録画を開始した場合は戻り値
recording_expire_timeが入ります指定していない場合は
expire_timeの項目が入ってきません
data.expired_at
この項目はオプションです
API による開始を行った場合は StartRecording API で指定した
expire_timeから計算した有効期限 (UNIX Time) が入りますsession.created ウェブフックリクエストの戻り値により録画を開始した場合は戻り値
recording_expire_timeから計算した有効期限 (UNIX Time) が入りますexpire_timeを指定していない場合はexpired_atの項目が入ってきません
data.split_duration
この項目はオプションです
API による開始を行った場合は StartRecording API で指定した
split_durationが入りますsession.created ウェブフックリクエストの戻り値により録画を開始した場合は戻り値
recording_split_durationが入ります指定していない場合は
split_durationの項目が入ってきません
data.split_only
API による開始を行った場合は StartRecording API で指定した
split_onlyが入りますsession.created ウェブフックリクエストの戻り値により録画を開始した場合は戻り値
recording_split_onlyが入ります指定していない場合は
falseが入ります
data.recording_metadata
この項目はオプションです
API による開始を行った場合は StartRecording API で指定した
metadataが入りますsession.created ウェブフックリクエストの戻り値により録画を開始した場合は戻り値
recording_metadataが入ります指定していない場合は
recording_metadataの項目が入ってきません
data.format
この項目はオプションです
API による開始を行った場合は StartRecording API で指定した
formatが入りますsession.created ウェブフックリクエストの戻り値により録画を開始した場合は戻り値
recording_formatが入ります指定していない場合は default_recording_format の値が入ります
{
"type": "recording.started",
"id": "<Base32-UUIDv4>",
"version": "<String>",
"label": "<String>",
"node_name": "<String>",
"channel_id": "<String>",
"group_id": "<Base32-UUIDv4>",
"session_id": "<Base32-UUIDv4>",
"session_metadata": "<JSON>",
"timestamp": "<UTC RFC3339 Timestamp>",
"data": {
"channel_id": "<String>",
"recording_id": "<Base32-UUIDv4>",
"recording_metadata": "<JSON-Object>",
"split_only": "<Boolean>",
"created_at": "<UNIX-Time>",
"expire_time": "<Integer>",
"expired_at": "<UNIX-Time>",
"start_timestamp": "<UTC RFC3339 Timestamp>",
"split_duration": "<Integer>",
"format": "<String{webm, mp4}>"
}
}
recording.report¶
重要
このウェブフックリクエストが送信するには、セッションベースの録画を利用する必要があります
注釈
セッションが破棄されたタイミングでの recording.report は session.destroyed の 後 に送信されます。
録画結果報告
data.archives[].start_time_offset
録画を開始してから何秒経過した後にこの録画が開始したかを表しています
data.archives[].stop_time_offset
録画を開始してから何秒経過した後にこの録画が終了したかを表しています
data.recording_metadata
StartRecording API で指定した metadata 、または
session.createdで払い出したrecording_metadataが入ります指定していない場合は
recording_metadataの項目が入ってきません
data.expired_at
期限が切れた日時を UNIX Time で返します
一括録画時 recording.report¶
{
"type": "recording.report",
"id": "<Base32-UUIDv4>",
"version": "<String>",
"label": "<String>",
"node_name": "<String>",
"channel_id": "<String>",
"group_id": "<String>",
"session_id": "<String>",
"session_metadata": "<JSON>",
"timestamp": "<UTC RFC3339 Timestamp>",
"data": {
"channel_id": "<String>",
"group_id": "<String>",
"session_id": "<String>",
"recording_id": "<Base32-UUIDv4>",
"recording_metadata": "<JSON-Object>",
"split_only": "<Boolean>",
"split_duration": "<Integer>",
"created_at": "<UNIX-Time>",
"expire_time": "<Integer>",
"expired_at": "<UNIX-Time>",
"file_path": "<String>",
"filename": "<String>",
"file_written": "<Boolean>",
"start_timestamp": "<UTC RFC3339 Timestamp>",
"stop_timestamp": "<UTC RFC3339 Timestamp>",
"format": "<String{webm, mp4}>",
"archives": [
{
"label": "<String>",
"node_name": "<String>",
"client_id": "<String | Base32-UUIDv4>",
"bundle_id": "<String | Base32-UUIDv4>",
"connection_id": "<Base32-UUIDv4>",
"file_path": "<String>",
"filename": "<String>",
"metadata_file_path": "<String>",
"metadata_filename": "<String>",
"start_time_offset": "<Integer>",
"start_timestamp": "<UTC RFC3339 Timestamp>",
"stop_time_offset": "<Integer>",
"stop_timestamp": "<UTC RFC3339 Timestamp>",
"size": "<Integer>"
},
{
"label": "<String>",
"node_name": "<String>",
"client_id": "<String | Base32-UUIDv4>",
"bundle_id": "<String | Base32-UUIDv4>",
"connection_id": "<Base32-UUIDv4>",
"file_path": "<String>",
"filename": "<String>",
"metadata_file_path": "<String>",
"metadata_filename": "<String>",
"start_time_offset": "<Integer>",
"start_timestamp": "<UTC RFC3339 Timestamp>",
"stop_time_offset": "<Integer>",
"stop_timestamp": "<UTC RFC3339 Timestamp>",
"size": "<Integer>"
}
],
"failed_archives": [
{
"label": "<String>",
"node_name": "<String>",
"client_id": "<String | Base32-UUIDv4>",
"bundle_id": "<String | Base32-UUIDv4>",
"connection_id": "<Base32-UUIDv4>"
},
{
"label": "<String>",
"node_name": "<String>",
"client_id": "<String | Base32-UUIDv4>",
"bundle_id": "<String | Base32-UUIDv4>",
"connection_id": "<Base32-UUIDv4>"
}
]
}
}
分割録画時 recording.report¶
{
"type": "recording.report",
"id": "<Base32-UUIDv4>",
"version": "<String>",
"label": "<String>",
"node_name": "<String>",
"channel_id": "<String>",
"group_id": "<String>",
"session_id": "<String>",
"session_metadata": "<JSON>",
"timestamp": "<UTC RFC3339 Timestamp>",
"data": {
"channel_id": "<String>",
"group_id": "<String>",
"session_id": "<String>",
"recording_id": "<Base32-UUIDv4>",
"recording_metadata": "<JSON-Object>",
"split_only": "<Boolean>",
"split_duration": "<Integer>",
"created_at": "<UNIX-Time>",
"expire_time": "<Integer>",
"expired_at": "<UNIX-Time>",
"file_path": "<String>",
"filename": "<String>",
"file_written": "<Boolean>",
"start_timestamp": "<UTC RFC3339 Timestamp>",
"stop_timestamp": "<UTC RFC3339 Timestamp>",
"format": "<String{webm, mp4}>",
"archives": [
{
"label": "<String>",
"node_name": "<String>",
"client_id": "<String | Base32-UUIDv4>",
"bundle_id": "<String | Base32-UUIDv4>",
"connection_id": "<Base32-UUIDv4>",
"start_time_offset": "<Integer>",
"start_timestamp": "<UTC RFC3339 Timestamp>",
"stop_time_offset": "<Integer>",
"stop_timestamp": "<UTC RFC3339 Timestamp>",
"split_last_index": "<String>"
},
{
"label": "<String>",
"node_name": "<String>",
"client_id": "<String | Base32-UUIDv4>",
"bundle_id": "<String | Base32-UUIDv4>",
"connection_id": "<Base32-UUIDv4>",
"start_time_offset": "<Integer>",
"start_timestamp": "<UTC RFC3339 Timestamp>",
"stop_time_offset": "<Integer>",
"stop_timestamp": "<UTC RFC3339 Timestamp>",
"split_last_index": "<String>"
}
],
"failed_archives": [
{
"label": "<String>",
"node_name": "<String>",
"client_id": "<String | Base32-UUIDv4>",
"bundle_id": "<String | Base32-UUIDv4>",
"connection_id": "<Base32-UUIDv4>"
},
{
"label": "<String>",
"node_name": "<String>",
"client_id": "<String | Base32-UUIDv4>",
"bundle_id": "<String | Base32-UUIDv4>",
"connection_id": "<Base32-UUIDv4>"
}
]
}
}
audio-streaming.started¶
重要
このウェブフックリクエストが送信されるには
sora.conf の ignore_audio_streaming_webhook が false である必要があります。
以下の 2 つの条件で音声ストリーミングが開始した時にウェブフックリクエストを送信します。
StartAudioStreaming API が実行されるか、 またはセッションウェブフックで
audio_streaming: true払い出されたタイミングでウェブフックリクエストを送信します。音声ストリーミングの ウェブフック を利用時に SubscribeAudioStreamingResultPush API が呼び出される、もしくはクライアントが接続されて、 そのチャネルで音声ストリーミングの結果をサブスクライブしているクライアント数が 1 以上になった場合
session.created よりも必ず 後に ウェブフックが送信されます。
キー |
型 |
内容 |
|---|---|---|
type |
string |
"audio-streaming.started" |
id |
string |
ウェブフック ID (ユニーク) |
label |
string |
sora.conf の label にて指定した値 |
node_name |
string |
Sora ノード名 |
version |
string |
Sora のバージョン |
channel_id |
string |
チャネル ID |
group_id |
string |
セッションをグルーピングする ID |
session_id |
string |
セッション ID |
timestamp |
string (RFC3339 UTC マイクロ秒) |
ウェブフック作成時間 |
created_time |
integer (UNIX 時間) |
セッション生成時間 |
created_timestamp |
string (RFC3339 UTC マイクロ秒) |
セッション生成時間 |
spotlight |
boolean |
スポットライトが有効かどうか |
session_metadata |
json |
(値がある場合) session.created の戻り値で指定した値 |
external_signaling_url |
string |
(クラスター機能が有効の場合) 接続先の external_signaling_url |
data |
object |
音声ストリーミング固有 |
data には以下が含まれます。
キー |
型 |
内容 |
|---|---|---|
audio_streaming_auto |
boolean |
自動開始/停止が有効かどうか |
audio_streaming_started_timestamp |
string (RFC3339 UTC マイクロ秒) |
音声ストリーミングを開始した時間 |
{
"channel_id": "sora",
"created_time": 1638337454,
"created_timestamp": "2021-12-01T05:44:14.523736Z",
"id": "2YN2DQE5KD3GSFSVPAYZ7VTAV4",
"label": "WebRTC SFU Sora",
"spotlight": false,
"node_name": "[email protected]",
"group_id": "NPR769YPQ914K10FW42PGH4TKW",
"session_id": "NPR769YPQ914K10FW42PGH4TKW",
"timestamp": "2022-12-01T05:44:14.523912Z",
"type": "audio-streaming.started",
"version": "2023.2.0",
"session_metadata": {"spam": "egg"},
"external_signaling_url": "wss://node-01.example.com/signaling",
"data": {
"audio_streaming_auto": true,
"audio_streaming_started_timestamp": "2021-12-01T05:44:16.523912Z"
}
}
audio-streaming.stopped¶
重要
このウェブフックリクエストが送信されるには
sora.conf の ignore_audio_streaming_webhook が false である必要があります。
以下の 3 つの条件で音声ストリーミングが停止した時にウェブフックリクエストを送信します。
セッションが破棄された場合
StopAudioStreaming API が呼び出す場合
音声ストリーミングの ウェブフック を利用時に UnsubscribeAudioStreamingResultPush API が呼び出される、もしくはクライアントが切断されて、 そのチャネルで音声ストリーミングの結果をサブスクライブしているクライアント数が 0 になった場合
session.destroyed よりも必ず 前に ウェブフックが送信されます。
キー |
型 |
内容 |
|---|---|---|
type |
string |
"audio-streaming.started" |
id |
string |
ウェブフック ID (ユニーク) |
label |
string |
sora.conf の label にて指定した値 |
node_name |
string |
Sora ノード名 |
version |
string |
Sora のバージョン |
channel_id |
string |
チャネル ID |
group_id |
string |
セッションをグルーピングする ID |
session_id |
string |
セッション ID |
timestamp |
string (RFC3339 UTC マイクロ秒) |
ウェブフック作成時間 |
created_time |
integer (UNIX 時間) |
セッション生成時間 |
created_timestamp |
string (RFC3339 UTC マイクロ秒) |
セッション生成時間 |
spotlight |
boolean |
スポットライトが有効かどうか |
session_metadata |
json |
(値がある場合) session.created の戻り値で指定した値 |
external_signaling_url |
string |
(クラスター機能が有効の場合) 接続先の external_signaling_url |
data |
object |
音声ストリーミング固有 |
data には以下が含まれます。
キー |
型 |
内容 |
|---|---|---|
audio_streaming_auto |
boolean |
自動開始/停止が有効かどうか |
audio_streaming_started_timestamp |
string (RFC3339 UTC マイクロ秒) |
音声ストリーミングを開始した時間 |
audio_streaming_stopped_timestamp |
string (RFC3339 UTC マイクロ秒) |
音声ストリーミングを停止した時間 |
{
"channel_id": "sora",
"created_time": 1638337454,
"created_timestamp": "2021-12-01T05:44:14.523736Z",
"id": "2YN2DQE5KD3GSFSVPAYZ7VTAV4",
"label": "WebRTC SFU Sora",
"spotlight": false,
"node_name": "[email protected]",
"group_id": "NPR769YPQ914K10FW42PGH4TKW",
"session_id": "NPR769YPQ914K10FW42PGH4TKW",
"timestamp": "2022-12-01T05:44:14.523912Z",
"type": "audio-streaming.stopped",
"version": "2023.2.0",
"session_metadata": {"spam": "egg"},
"external_signaling_url": "wss://node-01.example.com/signaling",
"data": {
"audio_streaming_auto": true,
"audio_streaming_started_timestamp": "2021-12-01T05:44:16.523912Z",
"audio_streaming_stopped_timestamp": "2021-12-01T05:44:16.523912Z"
}
}
API¶
TerminateSession API¶
セッションを強制的に終了させる API です。
channel_id を指定して、セッションを終了させます。
session_id を追加で指定することができますが、 session_id が見つからない場合はエラーになります。
API 実行中に新規の接続が来た場合、その接続はいったん保留して、セッション破棄後に新規セッションでの接続として扱います。
クラスター時の挙動について¶
セッションが存在していたノードで障害が起きた場合でも、 session.destroyed は送信されます¶
別のノードが session.destroyed を送信します。その際 reason 項目には abort が入ります。
reason が abort の場合、以下の情報が 最新の状態 ではない場合があります。
total_connectionsmax_connections
セッションが存在していたノードで障害が起きた際、同一ウェブフックが複数回送られる事があります¶
以下のウェブフックは複数回送られる可能性はあります、その際はウェブフックの "id" は同一になります。
session.destroyedrecording.startedrecording.reportaudio-streaming.stopped
クラスターリレー時の挙動について¶
セッションウェブフックはどのノードが送信しますか?¶
session.created を送信したノードが session.destroyed を送信します。
HTTP ヘッダー¶
警告
この機能は 実験的機能 のため、正式版では仕様が変更される可能性があります
注釈
JSON のパース時の判断などに利用してください。
sora-session-webhook-type¶
注意
x-sora-session-webhook-type は非推奨です、 sora-session-webhook-type を利用してください
セッションウェブフックの HTTP ヘッダー に sora-session-webhook-type または x-sora-session-webhook-type というヘッダー名でセッションウェブフックのタイプが入ってきます。
type が session.created の場合は sora-session-webhook-type: session.created または x-sora-session-webhook-type: session.created のように値が入ってきます。
sora-session-id¶
セッションウェブフックの HTTP ヘッダー に sora-session-id というヘッダー名でセッション ID が入ってきます。
セッション ID が 46NNAV9S0X3TD778A1JBYYCBS8 の場合は sora-session-id: 46NNAV9S0X3TD778A1JBYYCBS8 のように値が入ってきます。
シーケンス図¶
sequenceDiagram
autonumber
participant C1 as クライアント1
participant C2 as クライアント2
participant S as Sora
participant A as アプリケーションサーバー
C1->>S: type: connect
S->>+A: 認証ウェブフック
A-->>-S: 200 OK
S->>+A: セッションウェブフック<br/>type: session.created
A-->>-S: 200 OK
S->>C1: type: offer
C1->>S: type: answer
Note over C1,A: クライアント1 WebRTC 確立
S->>+A: イベントウェブフック<br/>type: connection.created
A-->>-S: 200 OK
C2->>S: type: connect
S->>+A: 認証ウェブフック
A-->>-S: 200 OK
S->>C2: type: offer
C2->>S: type: answer
Note over C1,A: クライアント2 WebRTC 確立
S->>+A: イベントウェブフック<br/>type: connection.created
A-->>-S: 200 OK
C1->>S: "type": "disconnect"
S->>+A: イベントウェブフック<br/>type: connection.destroyed
A-->>-S: 200 OK
S->>C1: WebSocket Close
Note over C1,A: クライアント1 WebRTC 切断
C2->>S: "type": "disconnect"
S->>+A: イベントウェブフック<br/>type: connection.destroyed
A-->>-S: 200 OK
S->>C2: WebSocket Close
Note over C1,A: クライアント2 WebRTC 切断
note right of S: 接続数 0 から 15 秒経過
S->>+A: セッションウェブフック<br/>type: session.destroyed
A-->>-S: 200 OK