すべての操作に、
API を。
SENCA の管理 API は、JSON を HTTP でやりとりします。パスはすべて /api/v1 から始まります。OpenAPI の定義(docs/api/openapi.yaml)にある 88 個の操作を、分類ごとに並べました。認証やエラーの扱いなど全体に共通する決まりは、管理 API と SDK で詳しく説明しています。
01認証
リクエストに Authorization: Bearer <token> を付けます。値が senca_ で始まれば API トークン、それ以外は JWT として扱います。
02権限
必要な権限(scope)は操作ごとに決まっていて、下の一覧の各操作に書いてあります。tenant:admin があれば、node:admin が要るもの以外はすべて呼び出せます。
03再送と同時更新
POST に Idempotency-Key を付けておけば、リトライしても二重には処理されません(24 時間は同じ応答を返します)。PATCH では、ほかの変更を上書きしないよう If-Match(ETag の値)が必須です。
04エラー
エラーの本文は application/problem+json 形式です。応答にはすべて X-Request-Id が付きます。リクエストを送りすぎると 429 が返り、次に送れるまでの時間が Retry-After に入ります。
配信(ストリーム)
streams · 12 個の操作ストリームは 1 本の配信の単位です。ここでは作成・変更・削除のほか、ストリームキーの再発行、視聴者向けの署名付き URL の発行、変換の計画の確認、静止画の取得を扱います。
POST /api/v1/streams
{"name":"demo"}
{
"id": "60dd5cca4fa2785a5d8eefc3b1f5d1bc",
"name": "demo",
"generation": 1,
"desired_state": "running",
"observed_state": "waiting_input",
"hls": {"container": "ts", "segment_ms": 2000, "window": 6},
"ingest": {
"rtmp_url": "rtmp://127.0.0.1:1935/live",
"stream_key": "sk_zgo54TfcU8PEPmrJDH34OHnjYR5Ot6nv__hlyLSf4pk",
"whip_url": "http://127.0.0.1:8080/whip/60dd5cca4fa2785a5d8eefc3b1f5d1bc"
}
} POST /api/v1/streams/{id}/playback-url
{"ttl_secs": 3600}
{
"expires_at": "2026-11-03T01:16:01Z",
"playback": {
"hls": "http://127.0.0.1:8080/s/1793668561/nWqDQOWkMTMY3Z2GoC94Rw/live/60dd…/index.m3u8",
"rtmp": "rtmp://127.0.0.1:1935/play/60dd…?exp=1793668561&sig=nWqDQOWkMTMY3Z2GoC94Rw",
"whep": "http://127.0.0.1:8080/whep/60dd…?exp=1793668561&sig=nWqDQOWkMTMY3Z2GoC94Rw"
}
} PATCH /api/v1/streams/{id}
If-Match: "1"
{"latency_profile":"low","hls":{"segment_ms":2000,"window":6,"container":"fmp4"}} POST /streams ストリームの作成 stream:write
- パス
- POST /api/v1/streams
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · StreamCreate
- 成功したとき
- 201 作成しました · Stream
- 返す状態コード
- 201 · 400 · 401 · 403 · 409 · 415 · 422 · 500
配信を受け付けるストリームを作成します。応答の ingest には、配信ソフトに設定する取り込み先の URL とストリームキーが入ります。
ingest.stream_key が返るのは、この応答と POST /streams/{id}/keys の応答だけです。同じ Idempotency-Key で再送したときの応答では null になり、stream_key_redacted: true が付きます。
name はテナント内で一意です(重複すると 409)。ストリームはテナントあたり 1000 本までで、超えると 403(QUOTA_EXCEEDED)です。
入力・出力・変換は、この本文には書きません。配信者が送ってくる映像は、RTMP・SRT・WHIP で受信します。外部へ取りに行く入力と外部への出力は POST /streams/{id}/inputs・/outputs で、変換は /pipelines で別に設定します。
captions を指定すると、配信中の音声を外部の音声認識(と翻訳)のサービスへ送り、ライブ HLS に WebVTT の字幕(master.m3u8・sub_{lang}.m3u8)を追加します。指定しなければ、外部へは何も送りません。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| name* | StreamName | ストリームの名前。1〜64 文字の英数字と _・-・.(. で始めることはできません)。テナント内で一意です |
| latency_profile | LatencyProfile | 遅延の設定。standard は通常の HLS、low は LL-HLS(低遅延の HLS。part の長さは min(500 ms, segment_ms / 4))、interactive は WebRTC・MoQ 向けです(LL-HLS の part は 200 ms で、開始時の待ち時間と送信のバッファーを小さくします) |
| codec_profile | CodecProfile | any か royalty_free。royalty_free(特許料のかからないコーデックだけを使う方針)では、H.264・H.265・AAC を、理由を示して拒否します。このとき hls.container は fmp4 にしてください |
| recording | RecordingPolicy | 自動録画の設定。enabled: true で、配信が始まると自動で録画します。retention_days は保持日数です(1〜36500、null で無期限) |
| snapshots | SnapshotPolicy | null | 静止画を一定の間隔で保存する設定。interval_secs(1〜86400 秒)ごとに撮り、keep(1〜10000 枚)を超えると古いものから削除します。null で設定しません |
| hls | HlsSettings | HLS の設定。segment_ms(セグメントの長さ。500〜10000、既定 2000)、window(ライブのプレイリストに含めるセグメントの数。3〜60、既定 6)、container(ts か fmp4、既定 ts) |
| limits | Limits | 上限の設定。max_viewers はノードごとの同時視聴者数の上限で、超えた新しい視聴は断ります(HLS・WHEP・RTSP では 503)。max_ingress_bps は入力のビットレートの上限(直近 3 秒の平均)で、5 秒続けて超えると配信者を切断し、その後 10 秒間は新しい配信を受け付けません |
| metadata | Metadata | 任意のキーと値(どちらも文字列)。32 組まで、キーは 1〜64 文字、値は 1024 文字までです |
| desired_state | "running" | "stopped" | running(既定)か stopped。stopped のストリームは配信を受け付けません |
| captions | CaptionSettings | null | 字幕と翻訳の設定(CaptionSettings)。指定すると、配信中の音声を音声認識サービスへ送って文字に起こし、ライブ HLS に WebVTT の字幕を追加します。null で設定しません |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /streams ストリームの一覧 stream:read
- パス
- GET /api/v1/streams
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 ストリームの一覧 · StreamList
- 返す状態コード
- 200 · 400 · 401 · 403
テナントのストリームを、ID の昇順で返します。
クエリパラメーター
- limit — 1 回に返す件数(1〜1000、既定 100)
- cursor — 前の応答の
next_cursorの値(最後に返した ID)。これより大きい ID から返します
GET /streams/{id} ストリームの取得(望ましい状態と実際の状態) stream:read
- パス
- GET /api/v1/streams/{id}
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 ストリーム · Stream
- 返す状態コード
- 200 · 401 · 403 · 404
ストリームの設定と、望ましい状態(desired_state)、実際の状態(observed_state)を返します。
PATCH /streams/{id} ストリームの設定の変更 stream:write
- パス
- PATCH /api/v1/streams/{id}
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · StreamPatch
- 成功したとき
- 200 変更後のストリーム · Stream
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 412 · 415 · 422 · 428 · 500
指定した項目だけを置き換えます(JSON Merge Patch を簡単にした方式です)。If-Match が必須です。
snapshots: null で静止画の設定を、captions: null で字幕の設定を削除します。それ以外の項目の null は「変更しない」という意味です。
hls・recording・limits・metadata・captions は、オブジェクト全体を置き換えます。たとえば {"hls":{"segment_ms":1000}} を送ると、window・container は既定値に戻ります。
desired_state: stopped にすると、配信を受け付けなくなります。配信中であれば、その時点で配信を終了します。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| name | StreamName | 新しい名前。1〜64 文字の英数字と _・-・.(. で始めることはできません)。テナント内で一意です |
| latency_profile | LatencyProfile | 遅延の設定。standard は通常の HLS、low は LL-HLS(低遅延の HLS。part の長さは min(500 ms, segment_ms / 4))、interactive は WebRTC・MoQ 向けです(LL-HLS の part は 200 ms で、開始時の待ち時間と送信のバッファーを小さくします) |
| codec_profile | CodecProfile | any か royalty_free。royalty_free(特許料のかからないコーデックだけを使う方針)では、H.264・H.265・AAC を、理由を示して拒否します。このとき hls.container は fmp4 にしてください |
| recording | RecordingPolicy | 自動録画の設定。enabled: true で、配信が始まると自動で録画します。retention_days は保持日数です(1〜36500、null で無期限) |
| snapshots | SnapshotPolicy | null | 静止画を一定の間隔で保存する設定。interval_secs(1〜86400 秒)ごとに撮り、keep(1〜10000 枚)を超えると古いものから削除します。null で設定を削除します |
| hls | HlsSettings | HLS の設定(segment_ms・window・container)。全体を置き換えるため、書かなかった項目は既定値に戻ります |
| limits | Limits | 上限の設定。max_viewers はノードごとの同時視聴者数の上限で、超えた新しい視聴は断ります(HLS・WHEP・RTSP では 503)。max_ingress_bps は入力のビットレートの上限(直近 3 秒の平均)で、5 秒続けて超えると配信者を切断し、その後 10 秒間は新しい配信を受け付けません |
| metadata | Metadata | 任意のキーと値(どちらも文字列)。32 組まで、キーは 1〜64 文字、値は 1024 文字までです |
| desired_state | "running" | "stopped" | running か stopped。stopped にすると配信を受け付けなくなります |
| captions | CaptionSettings | null | 字幕と翻訳の設定(CaptionSettings)。指定すると、配信中の音声を音声認識サービスへ送って文字に起こし、ライブ HLS に WebVTT の字幕を追加します。全体を置き換えます。null で設定を削除します |
* は必須の項目です。ここに無い項目を送ると 400 になります。
DELETE /streams/{id} ストリームの削除 stream:write
- パス
- DELETE /api/v1/streams/{id}
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404 · 412 · 500
ストリームと、その予約を削除します。録画は削除しません。配信中であれば、配信者を切断します。成功すると 204 を返します。
POST /streams/{id}/keys ストリームキーの再発行 stream:write
- パス
- POST /api/v1/streams/{id}/keys
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 200 新しい鍵を含むストリーム · Stream
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 500
鍵が漏れたときなどに、ストリームキーを新しくします。新しい鍵は ingest.stream_key で返り、古い鍵はその時点で使えなくなります。リクエストの本文は無視します。成功すると 200 です(201 ではありません)。
POST /streams/{id}/playback-url ライブ再生の署名付き URL の発行 subscribe
- パス
- POST /api/v1/streams/{id}/playback-url
- 認証・権限
- Bearer トークン・subscribe
- リクエストの本文
- application/json · PlaybackRequest
- 成功したとき
- 200 再生 URL · LivePlayback
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 415
視聴者向けの、期限付きの再生 URL(HLS・RTMP・WHEP)を発行します。本文は省略できます(空のときは Content-Type を確かめません)。有効期間 ttl_secs の既定は 300 秒で、上限はノードの設定 --max-playback-ttl で決まります。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| ttl_secs | integer | null | 有効期間(秒)。既定は 300 で、上限はノードの設定 --max-playback-ttl で決まります |
* は必須の項目です。ここに無い項目を送ると 400 になります。
POST /streams/{id}/plan 変換と資源の計画の確認(何も変更しません) stream:read
- パス
- POST /api/v1/streams/{id}/plan
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 計画 · Plan
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409
このストリームに必要な変換と資源の見積もりを返します。何も変更しません。配信が始まる前は、仮の計画(state: provisional)です。対応していないコーデックは、結果の code: UNSUPPORTED_CODEC でわかります。リクエストの本文は無視します。
GET /streams/{id}/snapshot 今の映像の静止画 stream:read
- パス
- GET /api/v1/streams/{id}/snapshot
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 静止画
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 422 · 500 · 503 · 504
配信中の映像から、今の 1 枚を静止画にして返します。画像の形式は format で選べます。
静止画は、コーデックワーカー(変換を担当する別プロセス)が映像を復号して作ります。
主なエラー:
- 配信中でないとき、映像のトラックが無いとき: 409(クラスターで、配信を別のノードが受信しているときは 409
OWNERSHIP_LOST) - キーフレームがまだ届いていないときは最大 5 秒待ち、届かなければ 504(
INPUT_TIMEOUT、retryable: true) - E2EE(エンドツーエンド暗号化)のルームからエクスポートしたストリーム: 422(
details.reason: "e2ee") - コーデックワーカー が動いていない、または映像を復号できるデバイスが無い: 503(
CAPACITY_UNAVAILABLE。retryable: falseのためRetry-Afterは付きません)。H.264・H.265 はハードウェアでだけ復号します - コーデックワーカー が
UNSUPPORTED_CODECを返した(royalty_freeの方針に反するなど): 422。INVALID_CONFIGを返した: 400。それ以外の失敗: 500
クエリパラメーター
- format — 画像の形式。
jpeg(既定)・jpg・png
GET /streams/{id}/snapshots 保存した静止画の一覧 stream:read
- パス
- GET /api/v1/streams/{id}/snapshots
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 静止画の一覧 · SnapshotList
- 返す状態コード
- 200 · 401 · 403 · 404
ストリームについて保存した静止画を、撮った時刻の順に返します。ページングはなく、クエリパラメーターは無視します。
GET /streams/{id}/snapshots/{sid} 保存した静止画の取得 stream:read
- パス
- GET /api/v1/streams/{id}/snapshots/{sid}
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 静止画
- 返す状態コード
- 200 · 401 · 403 · 404
DELETE /streams/{id}/snapshots/{sid} 保存した静止画の削除 stream:write
- パス
- DELETE /api/v1/streams/{id}/snapshots/{sid}
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404
録画・VOD
recordings · 9 個の操作録画の一覧・取得・削除と、VOD としての再生、MP4 へのエクスポートを扱います。録画を手動で始めるときは POST /streams/{id}/recordings を使います。
POST /api/v1/streams/{id}/recordings
{"name":"manual-1","retention_days":30} → 202(state: recording)
POST /api/v1/recordings/{id}/stop → 202 GET /api/v1/recordings/{id}/export.mp4?start=2026-11-04T01:00:00Z&end=2026-11-04T01:10:00Z POST /streams/{id}/recordings 録画の開始 stream:write
- パス
- POST /api/v1/streams/{id}/recordings
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · RecordingStart
- 成功したとき
- 202 録画を開始しました · Recording
- 返す状態コード
- 202 · 400 · 401 · 403 · 404 · 409 · 415 · 500
ストリームの録画を始めます。202 で録画を返し、Location は /api/v1/recordings/{id} です。本文は省略できます。
状態コードは 202 ですが、応答の本文は処理の進み具合ではなく、録画そのものです。
主なエラー:
- ストリームが
stoppedのとき: 409 - 同じストリームの同時録画がすでに 8 本あるとき: 403(
QUOTA_EXCEEDED) - クラスターで、配信を別のノードが受信しているとき: 409(
OWNERSHIP_LOST、details: {owner_node, owner_api})。そのノードへリクエストを送り直してください
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| name | string | null | 録画の名前(省略できます) |
| retention_days | integer | null | 保持日数(1〜36500) |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /recordings 録画の一覧 recording:read
- パス
- GET /api/v1/recordings
- 認証・権限
- Bearer トークン・recording:read
- 成功したとき
- 200 録画の一覧 · RecordingList
- 返す状態コード
- 200 · 400 · 401 · 403
録画を ID の昇順で返します。削除中(deleting)の録画は含めません。state クエリパラメーターは受け付けますが、今は絞り込みに使いません。
クエリパラメーター
- limit — 1 回に返す件数(1〜1000、既定 100)
- cursor — 前の応答の
next_cursorの値(最後に返した ID)。これより大きい ID から返します - stream — ストリームの ID で絞り込みます
- state — 受け付けますが、今は無視します(絞り込みません)
GET /recordings/{id} 録画の取得(インデックスと状態) recording:read
- パス
- GET /api/v1/recordings/{id}
- 認証・権限
- Bearer トークン・recording:read
- 成功したとき
- 200 録画 · Recording
- 返す状態コード
- 200 · 401 · 403 · 404
録画の状態とインデックスを返します。
PATCH /recordings/{id} 録画の保持期限・リーガルホールド・名前の変更 stream:write
- パス
- PATCH /api/v1/recordings/{id}
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · RecordingPatch
- 成功したとき
- 200 変更後の録画 · Recording
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 412 · 415 · 428 · 500
録画の保持期限(retention_until)、リーガルホールド(legal_hold。法的な理由などで削除を禁止する設定)、名前を変更します。If-Match が必須です。
リーガルホールドを解除する(legal_hold: false)には、recording:delete の権限も必要です(無ければ 403)。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| retention_until | string | null | 保持期限(RFC 3339)。null で無期限にします |
| legal_hold | boolean | true で削除を禁止します。解除するには recording:delete の権限も必要です |
| name | string | 録画の名前(128 文字まで) |
* は必須の項目です。ここに無い項目を送ると 400 になります。
DELETE /recordings/{id} 録画の削除 recording:delete
- パス
- DELETE /api/v1/recordings/{id}
- 認証・権限
- Bearer トークン・recording:delete
- 成功したとき
- 202 削除を受け付けました · RecordingDeleting
- 返す状態コード
- 202 · 401 · 403 · 404 · 409 · 412 · 500
録画を削除します。削除は受け付けた後に進むため、応答は 202 です。録画中であれば、止めてから削除します。リーガルホールド中の録画は削除できません(409)。
POST /recordings/{id}/stop 録画の停止 stream:write
- パス
- POST /api/v1/recordings/{id}/stop
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 202 停止を受け付けました · Recording
- 返す状態コード
- 202 · 400 · 401 · 403 · 404 · 409 · 500
録画を止めます。録画中でなければ 409 です。停止は受け付けた後に進むため、応答の state がまだ recording のことがあります。リクエストの本文は無視します。
POST /recordings/{id}/playback-url 録画の再生(VOD)の署名付き URL の発行 recording:read
- パス
- POST /api/v1/recordings/{id}/playback-url
- 認証・権限
- Bearer トークン・recording:read
- リクエストの本文
- application/json · PlaybackRequest
- 成功したとき
- 200 再生 URL · VodPlayback
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 415
録画を再生するための、期限付きの URL を返します。本文は省略できます。今のところ playback.mp4 は常に null です(MP4 は GET /recordings/{id}/export.mp4 で取得します)。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| ttl_secs | integer | null | 有効期間(秒)。既定は 300 で、上限はノードの設定 --max-playback-ttl で決まります |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /recordings/{id}/thumbnail 録画のサムネイル recording:read
- パス
- GET /api/v1/recordings/{id}/thumbnail
- 認証・権限
- Bearer トークン・recording:read
- 成功したとき
- 200 JPEG の画像
- 返す状態コード
- 200 · 401 · 403 · 404
録画のサムネイル(JPEG)を返します。サムネイルは録画が確定した後に作るため、まだ無ければ 404 です。
GET /recordings/{id}/export.mp4 MP4 へのエクスポート recording:read
- パス
- GET /api/v1/recordings/{id}/export.mp4
- 認証・権限
- Bearer トークン・recording:read
- 成功したとき
- 200 MP4 ファイル
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 413 · 500
録画を MP4 ファイルとしてダウンロードします。応答には Content-Disposition: attachment が付きます。
start・end(RFC 3339)で範囲を指定して切り出せます。予約で録画したものでは、予約の範囲と重なる部分が対象です。切り出しの始まりは、直前のキーフレームまで前に広がります。
主なエラー:
- 録画中の録画、空の録画: 409
- 大きすぎる録画: 413(
PAYLOAD_TOO_LARGE) - 時刻の形式の誤り、
endがstartと同じかそれより前、知らないクエリパラメーター: 400 - 指定した範囲に録画が無い: 409
クエリパラメーター
- start — エクスポートする範囲の始まり(RFC 3339)
- end — エクスポートする範囲の終わり(RFC 3339)
予約
schedules · 7 個の操作決まった時刻に録画・配信・静止画の撮影を行うよう、予約しておけます。毎日や毎週の繰り返しも指定できます。
POST /api/v1/schedules
{
"stream": "<stream id>",
"name": "monday-wednesday-lecture",
"action": "record",
"start_at": "2026-11-04T00:50:00Z",
"end_at": "2026-11-04T02:30:00Z",
"pre_roll_ms": 60000,
"post_roll_ms": 120000,
"recurrence": {"freq": "weekly", "weekdays": [1, 3], "timezone": "Asia/Tokyo", "count": 30},
"retention_days": 365
} POST /schedules 予約の作成 stream:write
- パス
- POST /api/v1/schedules
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · ScheduleCreate
- 成功したとき
- 201 作成しました · Schedule
- 返す状態コード
- 201 · 400 · 401 · 403 · 404 · 409 · 415 · 422 · 500
ストリームの録画・配信・静止画の撮影を、指定した時間に行うよう予約します。作成の前に、POST /schedules/check と同じ検査を行います。
1 回の期間は 24 時間までで、end_at は未来の時刻にしてください。
主なエラー:
- 同じストリームで同時に行う録画の予約が 4 本を超える: 409(重なる予約が
details.overlapsに入ります) - ストリームが無い: 404
- 予約がテナントあたり 1000 件を超える: 403(
QUOTA_EXCEEDED)
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| stream* | string | 対象のストリームの ID |
| name | string | null | 予約の名前(省略できます) |
| action* | ScheduleAction | 予約の内容。record は期間中に録画し、live は期間中だけ配信を受け付け、snapshot は期間中に一定の間隔で静止画を撮ります |
| start_at* | string | 開始時刻(RFC 3339) |
| end_at* | string | 終了時刻(RFC 3339)。start_at より後の、未来の時刻にします。期間は 24 時間までです |
| pre_roll_ms | integer | null | 開始時刻より前に広げる長さ(ミリ秒。0〜300000、既定 0) |
| post_roll_ms | integer | null | 終了時刻より後に広げる長さ(ミリ秒。0〜300000、既定 0) |
| grace_ms | integer | null | 実際の開始時刻(start_at - pre_roll_ms)を過ぎても、この時間内なら途中から実行します(ミリ秒。0〜3600000、既定 60000)。過ぎると missed になります |
| snapshot_interval_secs | integer | null | 静止画を撮る間隔(秒。1〜3600)。action が snapshot のときだけ指定し、そのときは必須です |
| recurrence | Recurrence | null | 繰り返しの設定。freq(daily か weekly)、weekdays(weekly の曜日。0 が日曜)、timezone(IANA のタイムゾーン名。例: Asia/Tokyo。現地時刻で繰り返します)、until_ms(繰り返しの終わり。この時刻を含まない、UTC のミリ秒)、count(回数) |
| retention_days | integer | null | 録画の保持日数(0 以上) |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /schedules 予約の一覧 stream:read
- パス
- GET /api/v1/schedules
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 予約の一覧 · ScheduleList
- 返す状態コード
- 200 · 400 · 401 · 403
予約を ID の昇順で返します。state クエリパラメーターは受け付けますが、今は絞り込みに使いません。
クエリパラメーター
- limit — 1 回に返す件数(1〜1000、既定 100)
- cursor — 前の応答の
next_cursorの値(最後に返した ID)。これより大きい ID から返します - stream — ストリームの ID で絞り込みます
- state — 受け付けますが、今は無視します(絞り込みません)
POST /schedules/check 予約を作る前の確認(何も保存しません) stream:read
- パス
- POST /api/v1/schedules/check
- 認証・権限
- Bearer トークン・stream:read
- リクエストの本文
- application/json · ScheduleCreate
- 成功したとき
- 200 検査の結果 · ScheduleCheck
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 415 · 500
予約を作る前に、ほかの予約と重ならないか、資源が足りるか、競合が無いかを確かめます。本文は作成と同じものを送ってください。何も保存しません。問題が無ければ 200、問題があれば作成と同じ 400・404・409 を返します。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| stream* | string | 対象のストリームの ID |
| name | string | null | 予約の名前(省略できます) |
| action* | ScheduleAction | 予約の内容。record は期間中に録画し、live は期間中だけ配信を受け付け、snapshot は期間中に一定の間隔で静止画を撮ります |
| start_at* | string | 開始時刻(RFC 3339) |
| end_at* | string | 終了時刻(RFC 3339)。start_at より後の、未来の時刻にします。期間は 24 時間までです |
| pre_roll_ms | integer | null | 開始時刻より前に広げる長さ(ミリ秒。0〜300000、既定 0) |
| post_roll_ms | integer | null | 終了時刻より後に広げる長さ(ミリ秒。0〜300000、既定 0) |
| grace_ms | integer | null | 実際の開始時刻(start_at - pre_roll_ms)を過ぎても、この時間内なら途中から実行します(ミリ秒。0〜3600000、既定 60000)。過ぎると missed になります |
| snapshot_interval_secs | integer | null | 静止画を撮る間隔(秒。1〜3600)。action が snapshot のときだけ指定し、そのときは必須です |
| recurrence | Recurrence | null | 繰り返しの設定。freq(daily か weekly)、weekdays(weekly の曜日。0 が日曜)、timezone(IANA のタイムゾーン名。例: Asia/Tokyo。現地時刻で繰り返します)、until_ms(繰り返しの終わり。この時刻を含まない、UTC のミリ秒)、count(回数) |
| retention_days | integer | null | 録画の保持日数(0 以上) |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /schedules/{id} 予約の取得 stream:read
- パス
- GET /api/v1/schedules/{id}
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 予約 · Schedule
- 返す状態コード
- 200 · 401 · 403 · 404
PATCH /schedules/{id} 予約の変更・取り消し stream:write
- パス
- PATCH /api/v1/schedules/{id}
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · SchedulePatch
- 成功したとき
- 200 変更後の予約 · Schedule
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 412 · 415 · 428 · 500
予約の内容を変更するか、取り消します。If-Match が必須です。取り消すには state: canceled を指定します(state に指定できるのは canceled だけです)。取り消し以外の変更では、作成と同じ検査を行います。
実行中の予約の start_at は変更できません(409)。recurrence・action・stream も変更できません。
snapshot_interval_secs・retention_days は削除できません。各項目の null は「変更しない」という意味です。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| name | string | null | 新しい名前 |
| start_at | string | null | 新しい開始時刻(RFC 3339)。実行中の予約では変更できません |
| end_at | string | null | 新しい終了時刻(RFC 3339) |
| pre_roll_ms | integer | null | 開始時刻より前に広げる長さ(ミリ秒。0〜300000) |
| post_roll_ms | integer | null | 終了時刻より後に広げる長さ(ミリ秒。0〜300000) |
| grace_ms | integer | null | 開始時刻を過ぎても途中から実行できる時間(ミリ秒。0〜3600000) |
| snapshot_interval_secs | integer | null | 静止画を撮る間隔(秒。1〜3600) |
| retention_days | integer | null | 録画の保持日数(0 以上) |
| state | "canceled" | null | canceled を指定すると、予約を取り消します |
* は必須の項目です。ここに無い項目を送ると 400 になります。
DELETE /schedules/{id} 予約の削除 stream:write
- パス
- DELETE /api/v1/schedules/{id}
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404 · 412 · 500
GET /schedules/{id}/runs 予約の実行履歴と結果 stream:read
- パス
- GET /api/v1/schedules/{id}/runs
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 実行履歴 · ScheduleRunList
- 返す状態コード
- 200 · 401 · 403 · 404
予約が実行された記録と結果を、直近の 100 件まで返します。ページングはなく、items だけを返します。
入力と出力
io · 10 個の操作入力は、SENCA が外部のサーバーへ映像を取りに行く設定です(pull)。出力はその逆で、SENCA から外部へ映像を送ります(push、または配信サービスとの連携)。
定義を保存すると、ノードが順に実行します。うまく動いているかは、応答の status(IoStatus)で確かめてください。
接続先の IP アドレスは、保存のときではなく実際に接続するときに検査します。内部のネットワークへの不正な接続(SSRF)を防ぐためです。そのため、許可されていない接続先でも作成は 201 で成功し、拒否の理由が後から status.last_error に表示されます。
POST /api/v1/streams/{id}/outputs
{"protocol":"rtmp_push","url":"rtmps://live.example.com:443/app","credential_ref":"secret:yt-key"} POST /api/v1/streams/{id}/outputs
{"protocol":"paas","provider":"cloudflare_stream","credential_ref":"secret:cf","options":{"recording":"automatic"}} POST /streams/{id}/inputs 入力(外部からの取り込み)の追加 stream:write
- パス
- POST /api/v1/streams/{id}/inputs
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · InputCreate
- 成功したとき
- 201 作成しました · Input
- 返す状態コード
- 201 · 400 · 401 · 403 · 404 · 409 · 415 · 500
ストリームに入力を追加します。入力には 2 種類あります。外部のサーバーから映像を取りに行くもの(rtmp_pull・rtsp_pull・srt_pull・hls_pull)と、このノードにつないだキャプチャ機器(device)です。device の url は device:{機器 ID} で、機器は GET /devices の capture で調べられます。
配信者から送られてくる入力(push)は、ストリームキーで受信するため、ここでは扱いません。
enabled: true の入力はグリッドのワークロード(input:{id})になり、スケジューラーが割り当てたノードが実行します(結果は placement_status)。placement.node にはノードの ID か名前を指定でき、応答では ID に変換されます。placement.degrade はパイプライン専用のため、指定すると 400 です。
リンクローカルやプライベートの IP アドレスなど、--egress-allow で許可していない接続先は、接続のときに拒否されます。このときも作成は 201 で成功し、status.state が error か backoff になって、理由が status.last_error に表示されます。
1 つのストリームに追加できる入力は 4 つまでです(超えると 403 QUOTA_EXCEEDED)。enabled: true の入力は、すぐに動き始めます(応答の status は null か starting のことがあります)。
主なエラー(この順に検査します):
- 本文の形式の誤り: 400・415
- ストリームが無い: 404
protocolの誤り: 400urlのスキームや形式の誤り: 400。資格情報(user:pass@)を含む URL も拒否するので、credential_refを使ってくださいcredential_refの形式の誤り、シークレットが無い: 400optionsの誤り: 400placementの誤り: 400(PlacementSpecを参照)
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| protocol* | "rtmp_pull" | "rtsp_pull" | "srt_pull" | "hls_pull" | "device" | 入力の種類。rtmp_pull・rtsp_pull・srt_pull・hls_pull・device |
| url* | string | 取得元の URL。使えるスキームは protocol で決まります(rtmp_pull: rtmp・rtmps、rtsp_pull: rtsp・rtsps、srt_pull: srt、hls_pull: http・https、device: device:{機器 ID}(300 文字まで))。ホスト名が必要で、空白や制御文字は使えません。資格情報(user:pass@)は含められないので、credential_ref を使ってください |
| credential_ref | CredentialRef | 認証に使うシークレットの参照。secret:{name} の形で、POST /secrets で登録した名前を書きます。存在しないシークレットや形式の誤りは 400 です |
| enabled | boolean | null | false にすると実行しません(既定 true) |
| options | IoOptions | プロトコルごとの設定。例: rtsp_pull の allow_basic: "true"、tls_spki_sha256(rtsps で証明書の公開鍵を固定します。SHA-256 の base64 か 16 進)、device の width・height・fps・codec・bitrate_bps・audio_device・audio_codec。16 個まで、キーは 64 文字・値は 256 文字までです。RTSP は TCP interleaved で接続します |
| placement | PlacementSpec | null | 配置の指定(PlacementSpec。degrade は使えません) |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /streams/{id}/inputs ストリームの入力の一覧 stream:read
- パス
- GET /api/v1/streams/{id}/inputs
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 入力の一覧 · InputList
- 返す状態コード
- 200 · 400 · 401 · 403 · 404
クエリパラメーター
- limit — 1 回に返す件数(1〜1000、既定 100)
- cursor — 前の応答の
next_cursorの値(最後に返した ID)。これより大きい ID から返します
GET /inputs/{id} 入力の取得(定義と実行の状態) stream:read
- パス
- GET /api/v1/inputs/{id}
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 入力 · Input
- 返す状態コード
- 200 · 401 · 403 · 404
PATCH /inputs/{id} 入力の変更 stream:write
- パス
- PATCH /api/v1/inputs/{id}
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · IoPatch
- 成功したとき
- 200 変更後の入力 · Input
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 412 · 415 · 428 · 500
入力の url・credential_ref・enabled・options・placement を置き換えます。If-Match が必須です。credential_ref と placement は null で削除できます(placement を削除すると、配置はスケジューラーに任せます)。それ以外の項目の null は「変更しない」という意味です。
protocol と stream は変更できません。作成と同じ検査を行います。
変更すると、実行中の接続を作り直します。placement を変更すると配置を決め直すため、別のノードへ移ることがあります。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| url | string | null | 新しい取得元の URL(スキームの決まりは作成と同じです) |
| credential_ref | CredentialRef | 認証に使うシークレットの参照。secret:{name} の形で、POST /secrets で登録した名前を書きます。存在しないシークレットや形式の誤りは 400 です。null で削除します |
| enabled | boolean | null | false で止め、true で動かします |
| options | IoOptions | null | プロトコルごとの設定。例: rtsp_pull の allow_basic: "true"、tls_spki_sha256(rtsps で証明書の公開鍵を固定します。SHA-256 の base64 か 16 進)、device の width・height・fps・codec・bitrate_bps・audio_device・audio_codec。16 個まで、キーは 64 文字・値は 256 文字までです。RTSP は TCP interleaved で接続します |
| placement | PlacementSpec | null | 配置の指定の全体を置き換えます(一部だけは変更できません。degrade は使えません)。null で削除します |
* は必須の項目です。ここに無い項目を送ると 400 になります。
DELETE /inputs/{id} 入力の削除 stream:write
- パス
- DELETE /api/v1/inputs/{id}
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404 · 500
入力の接続を止めて、定義を削除します。If-Match は検査しません。
POST /streams/{id}/outputs 出力(外部への送信)の追加 stream:write
- パス
- POST /api/v1/streams/{id}/outputs
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · OutputCreate
- 成功したとき
- 201 作成しました · Output
- 返す状態コード
- 201 · 400 · 401 · 403 · 404 · 409 · 415 · 500
ストリームを外部へ送る出力を追加します。配信が始まるまでは status.state: waiting_input です。
rtmp_push・srt_push: 送信先のurlが必要です。スキームの検査と、資格情報(user:pass@)を含む URL の拒否は、入力と同じです。RTMP のストリームキーは、urlの末尾かcredential_refで指定します。paas(配信サービスとの連携):provider(cloudflare_stream・aws_ivs・aws_medialive)と、そのサービスの API の資格情報を指すcredential_refが必要です。urlは使いません。SENCA が連携先に作ったリソースはprovider_resourceに記録され、出力を削除すると SENCA が後片付けします。
1 つのストリームに追加できる出力は 16 個までです(超えると 403 QUOTA_EXCEEDED)。
enabled: true の出力はグリッドのワークロード(output:{id})になり、スケジューラーが割り当てたノードが送信します(結果は placement_status)。指定が無ければ、配信を受信しているノードを優先します。placement の検査は入力と同じです(degrade は 400)。
外部の WHIP サーバーへの送信(whip_push)には対応していません(400)。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| protocol* | "rtmp_push" | "srt_push" | "paas" | 出力の種類。rtmp_push・srt_push・paas |
| url | string | null | 送信先の URL。paas 以外では必須です。使えるスキームは、rtmp_push が rtmp・rtmps、srt_push が srt です。資格情報は含められません |
| credential_ref | CredentialRef | 認証に使うシークレットの参照。secret:{name} の形で、POST /secrets で登録した名前を書きます。存在しないシークレットや形式の誤りは 400 です |
| enabled | boolean | null | false にすると送信しません(既定 true) |
| provider | "cloudflare_stream" | "aws_ivs" | "aws_medialive" | null | 連携する配信サービス(cloudflare_stream・aws_ivs・aws_medialive)。paas では必須で、credential_ref も必要です |
| options | IoOptions | プロトコルごとの設定。例: rtsp_pull の allow_basic: "true"、tls_spki_sha256(rtsps で証明書の公開鍵を固定します。SHA-256 の base64 か 16 進)、device の width・height・fps・codec・bitrate_bps・audio_device・audio_codec。16 個まで、キーは 64 文字・値は 256 文字までです。RTSP は TCP interleaved で接続します |
| placement | PlacementSpec | null | 配置の指定(PlacementSpec。degrade は使えません)。指定が無ければ、配信を受信しているノードを優先します |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /streams/{id}/outputs ストリームの出力の一覧 stream:read
- パス
- GET /api/v1/streams/{id}/outputs
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 出力の一覧 · OutputList
- 返す状態コード
- 200 · 400 · 401 · 403 · 404
クエリパラメーター
- limit — 1 回に返す件数(1〜1000、既定 100)
- cursor — 前の応答の
next_cursorの値(最後に返した ID)。これより大きい ID から返します
GET /outputs/{id} 出力の取得(定義と実行の状態) stream:read
- パス
- GET /api/v1/outputs/{id}
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 出力 · Output
- 返す状態コード
- 200 · 401 · 403 · 404
PATCH /outputs/{id} 出力の変更 stream:write
- パス
- PATCH /api/v1/outputs/{id}
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · IoPatch
- 成功したとき
- 200 変更後の出力 · Output
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 412 · 415 · 428 · 500
出力の url・credential_ref・enabled・options・placement を置き換えます。If-Match が必須です。credential_ref と placement は null で削除できます。それ以外の項目の null は「変更しない」という意味です。
protocol・provider・stream は変更できません。paas の出力には url を指定できません(400)。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| url | string | null | 新しい送信先の URL(paas では指定できません) |
| credential_ref | CredentialRef | 認証に使うシークレットの参照。secret:{name} の形で、POST /secrets で登録した名前を書きます。存在しないシークレットや形式の誤りは 400 です。null で削除します |
| enabled | boolean | null | false で止め、true で動かします |
| options | IoOptions | null | プロトコルごとの設定。例: rtsp_pull の allow_basic: "true"、tls_spki_sha256(rtsps で証明書の公開鍵を固定します。SHA-256 の base64 か 16 進)、device の width・height・fps・codec・bitrate_bps・audio_device・audio_codec。16 個まで、キーは 64 文字・値は 256 文字までです。RTSP は TCP interleaved で接続します |
| placement | PlacementSpec | null | 配置の指定の全体を置き換えます(一部だけは変更できません。degrade は使えません)。null で削除します |
* は必須の項目です。ここに無い項目を送ると 400 になります。
DELETE /outputs/{id} 出力の削除 stream:write
- パス
- DELETE /api/v1/outputs/{id}
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404 · 500
送信を止めて、定義を削除します。paas の場合は、SENCA が連携先に作ったリソースも後片付けします。後片付けに失敗してもログに記録するだけで、定義は削除します。If-Match は検査しません。
シークレット
secrets · 3 個の操作配信先のストリームキーや外部サービスの資格情報は、設定に直接書く代わりにシークレットとして登録しておきます。値はノードの鍵で暗号化して保存され、API から読み出すことはできません。入力・出力などからは credential_ref: "secret:{name}" の形で参照します。
POST /api/v1/secrets
{"name":"youtube-key","value":"xxxx-xxxx"}
{"id": "...", "name": "youtube-key", "ref": "secret:youtube-key", "created_at": "..."} POST /secrets シークレットの登録 tenant:admin
- パス
- POST /api/v1/secrets
- 認証・権限
- Bearer トークン・tenant:admin
- リクエストの本文
- application/json · SecretCreate
- 成功したとき
- 201 登録しました(ETag は付きません) · Secret
- 返す状態コード
- 201 · 400 · 401 · 403 · 409 · 415 · 500
配信先のストリームキーや外部サービスの資格情報などを、シークレットとして登録します。値はノードの鍵(AES-256-GCM)で暗号化して保存し、応答にも一覧にも含めません。入力・出力などからは、応答の ref(secret:{name})で参照します。
name はテナント内で一意です(重複すると 409)。登録できるのは 500 個までです(超えると 403 QUOTA_EXCEEDED)。値は 1〜8192 バイトです。
値を変えるには、いったん削除してから登録し直してください(変更の API はありません)。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| name* | StreamName | シークレットの名前。1〜64 文字の英数字と _・-・.(. で始めることはできません)。テナント内で一意です |
| value* | string | 秘密にする値(UTF-8 で 1〜8192 バイト)。応答には含まれません |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /secrets シークレットの一覧(値は含みません) tenant:admin
- パス
- GET /api/v1/secrets
- 認証・権限
- Bearer トークン・tenant:admin
- 成功したとき
- 200 シークレットの一覧 · SecretList
- 返す状態コード
- 200 · 401 · 403
登録したシークレットの名前などを返します。値は含みません。ページングはなく、すべてを返します。next_cursor は常に null です。クエリパラメーターは無視します(ほかの一覧と違い、limit・cursor や知らないクエリパラメーターを付けても 400 になりません)。
DELETE /secrets/{id} シークレットの削除 tenant:admin
- パス
- DELETE /api/v1/secrets/{id}
- 認証・権限
- Bearer トークン・tenant:admin
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404 · 409 · 500
シークレットを削除します。入力・出力の credential_ref、ストリームの captions.asr_credential_ref・translate_credential_ref から参照されているシークレットは削除できません(409)。If-Match は検査しません。
パイプライン
pipelines · 10 個の操作パイプラインは、映像・音声を加工する処理を組み合わせたものです。処理の流れは JSON のグラフで書きます(書き方は「パイプライン」のドキュメントにあります)。
グラフは作成・更新のたびに検証されます。参照するストリームが自分のテナントのものか、コーデックの方針に合っているか、必要なデバイスがあるか、といった点です。desired_state: running にすると、コーデックワーカー(変換を担当する別プロセス)が実行します。
POST /api/v1/pipelines/{id}/control
{"op":"take","node":"prod"}
{"op":"switch_program","node":"prod","scene":"pinp","transition":{"kind":"wipe_left","duration_ms":500}}
{"op":"set_audio","node":"mix","input":"mic","gain_db":-6} POST /pipelines パイプラインの作成 stream:write
- パス
- POST /api/v1/pipelines
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · PipelineCreate
- 成功したとき
- 201 作成しました · Pipeline
- 返す状態コード
- 201 · 400 · 401 · 403 · 409 · 415 · 422 · 500 · 503
グラフを検証してから、パイプラインを保存します。desired_state の既定は stopped なので、作成しただけでは動きません。
name はテナント内で一意です(重複すると 409)。パイプラインは 100 個まで作成できます(超えると 403 QUOTA_EXCEEDED)。
使えるコーデックは、このノードのコーデックワーカー(変換を担当する別プロセス)が報告した能力で決まります。コーデックワーカー が無い場合、エンコードやデコードを含むグラフは 503 になります。
検証に失敗したとき:
- グラフを解釈できない、処理ノードの設定が不正、参照の誤り、方針違反(
royalty_freeのストリームに H.264 を使うなど)、対応していないコーデック: 400(INVALID_CONFIG。details.issuesにPipelineIssueの配列が入ります) source・sinkのストリームがテナントに無い: 400(INVALID_CONFIG。titleにストリームの ID が入ります)- デバイスが無い(H.264・H.265 のハードウェアが無い、セッション数が上限に達している): 503(
CAPACITY_UNAVAILABLE、retryable: false。Retry-Afterは付きません) placementの誤り: 400(INVALID_CONFIG。グラフの検証の後に検査します)
desired_state: running のパイプラインはグリッドのワークロード(pipeline:{id})になり、スケジューラーが割り当てたノードが実行します(結果は placement_status)。入力のストリームを受信しているノードを優先します。
placement.degrade にデグレードレベルを書いておけば、CPU や GPU のセッションが足りないときも、段階を下げて動き続けます。下げた段階では、その段階で指定した処理ノード(と、入力がすべて止まった下流の処理ノード)を外したグラフで実行します(placement_status.state: degraded)。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| name* | StreamName | パイプラインの名前。1〜64 文字の英数字と _・-・.(. で始めることはできません)。テナント内で一意です |
| graph* | PipelineGraph | パイプラインの定義(有向非巡回グラフ)。処理ノード(nodes の各要素)の種類は type で指定します。知らない項目は拒否します。サイズは 16 MiB までですが、その前に HTTP の本文の上限 1 MiB が適用されます |
| desired_state | "running" | "stopped" | null | running か stopped(既定 stopped) |
| placement | PlacementSpec | null | 配置の指定と、デグレードレベル(degrade) |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /pipelines パイプラインの一覧 stream:read
- パス
- GET /api/v1/pipelines
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 パイプラインの一覧 · PipelineList
- 返す状態コード
- 200 · 400 · 401 · 403
クエリパラメーター
- limit — 1 回に返す件数(1〜1000、既定 100)
- cursor — 前の応答の
next_cursorの値(最後に返した ID)。これより大きい ID から返します
GET /pipelines/{id} パイプラインの取得(定義と実行の状態) stream:read
- パス
- GET /api/v1/pipelines/{id}
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 パイプライン · Pipeline
- 返す状態コード
- 200 · 401 · 403 · 404
PATCH /pipelines/{id} パイプラインの変更・開始・停止 stream:write
- パス
- PATCH /api/v1/pipelines/{id}
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · PipelinePatch
- 成功したとき
- 200 変更後のパイプライン · Pipeline
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 412 · 415 · 422 · 428 · 500 · 503
name・graph・desired_state・placement を置き換えます。If-Match が必須です。desired_state: running で開始し、stopped で停止します。placement は null で削除できます。ほかの項目の null は「変更しない」という意味です。
graph には、作成と同じ検証を行います(400・503)。placement を指定しなかった場合も、今のデグレードレベルを新しい graph で検査し直します(止める処理ノードが新しいグラフに無ければ 400)。
変更すると generation が増え、実行中なら新しいグラフで作り直します。セッションを開き直すため、切れ目なく切り替わるわけではありません。
name はテナント内で一意です(重複すると 409)。本文の検査は If-Match の比較より先に行います。そのため、古い If-Match と不正な本文を同時に送ると、400 が返ります。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| name | StreamName | null | 新しい名前。1〜64 文字の英数字と _・-・.(. で始めることはできません) |
| graph | PipelineGraph | null | 新しいグラフ(作成と同じ検証を行います) |
| desired_state | "running" | "stopped" | null | running で開始、stopped で停止します |
| placement | PlacementSpec | null | 配置の指定の全体を置き換えます(一部だけは変更できません)。null で削除します。省略した場合は、今の指定を新しい graph で検査し直します(デグレードレベルの disable にある処理ノードが新しいグラフに無ければ 400) |
* は必須の項目です。ここに無い項目を送ると 400 になります。
DELETE /pipelines/{id} パイプラインの削除 stream:write
- パス
- DELETE /api/v1/pipelines/{id}
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404 · 500
実行中であれば止めてから削除します。If-Match は検査しません。
POST /pipelines/{id}/validate グラフの検証と計画の確認(何も変更しません) stream:read
- パス
- POST /api/v1/pipelines/{id}/validate
- 認証・権限
- Bearer トークン・stream:read
- リクエストの本文
- application/json · PipelineGraph
- 成功したとき
- 200 検証に成功しました · PipelineValidation
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 415 · 422 · 503
グラフを検証し、実行の計画を返します。本文が空なら保存済みのグラフを、本文があればそのグラフ(PipelineGraph)を検証します。本文のグラフは保存しません。
失敗したときの応答は、作成と同じ 400・503 です。何も変更しないため、必要な権限は stream:read です。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| version* | integer | グラフの形式の版。1 だけを指定できます |
| options | PipelineOptions | 実行の設定(clock・overflow・latency_ms など)。省略すると既定値です |
| nodes* | PipelineNode[] | 処理ノードの配列。各要素の type で種類を指定します(source・decode・board・scale・crop・compose・audio_mix・encode・snapshot_on_change・sink) |
* は必須の項目です。ここに無い項目を送ると 400 になります。
POST /pipelines/{id}/control 実行中のパイプラインの操作(シーンの切り替え・トランジション・フェーダーなど) stream:write
- パス
- POST /api/v1/pipelines/{id}/control
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · PipelineControl
- 成功したとき
- 200 反映しました · PipelineControlResult
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 415 · 500
実行中のパイプラインに操作(PipelineControl)を送り、結果を待ちます(最長 15 秒)。配信しながらシーンを切り替えたり、音量を変えたりするときに使います。合成やミキサーへの操作は、次に出力するフレームから反映されます。
主なエラー:
- 本文の形式の誤り(知らない
opや項目): 400(INVALID_REQUEST)。prepare・commit・rollback(世代の操作)も 400 です。グラフを変えるにはPATCHを使ってください - パイプラインが実行中でない(
stopped、起動中、コーデックワーカー が無い): 409(CONFLICT) - 実行中に操作が拒否された(知らない処理ノード・シーン・レイヤーなど): 409(
CONFLICT。titleにエラーの内容が入ります)
GET /pipelines/{id}/snapshots 板書の変化で撮った静止画の一覧 stream:read
- パス
- GET /api/v1/pipelines/{id}/snapshots
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 静止画の一覧 · SnapshotList
- 返す状態コード
- 200 · 401 · 403 · 404
snapshot_on_change の処理ノードが、板書の変化を見つけて保存した静止画を返します(reason: board_change、node は処理ノードの ID)。撮った時刻の順に並びます。返すのは、パイプラインを動かしているノードにある静止画だけです。
GET /pipelines/{id}/snapshots/{sid} 板書の変化で撮った静止画の取得 stream:read
- パス
- GET /api/v1/pipelines/{id}/snapshots/{sid}
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 静止画
- 返す状態コード
- 200 · 401 · 403 · 404
DELETE /pipelines/{id}/snapshots/{sid} 板書の変化で撮った静止画の削除 stream:write
- パス
- DELETE /api/v1/pipelines/{id}/snapshots/{sid}
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404
リアルタイムのルーム
rooms · 12 個の操作リアルタイムのルームは、ビデオ会議のように参加者どうしが WebRTC で映像・音声を送り合う場です。映像は SFU(受け取った映像を変換せずに各参加者へ転送する仕組み)を通して届きます。
ルームの定義(作成・取得・更新・削除)は、クラスターのどのノードでも受け付けます。ルームの ID はテナントをまたいで一意なので、ほかのテナントが使っている ID で作成すると 409、ほかのテナントのルームを取得しようとすると 404 になります。
ルームは、グリッドのワークロード(room:{id})として、スケジューラーが割り当てたノード(placement_status.node)で開かれます。placement の書き方は入力・出力と同じですが、degrade は使えません(指定すると 400)。
参加者・メッセージ・統計の情報は、ルームを開いているノードだけが持っています。別のノードにリクエストが届いたときは、同じ認証情報のままルームのあるノードの /api/v1 へ転送し、その応答(状態コード・本文・ETag)をそのまま返します。転送は 1 回だけで、転送先でさらに転送が必要なら 503 です。
ほかに、作成した直後で配置先がまだ決まっていなければ 503(retryable: true)、そのノードで WebRTC(--webrtc-udp)が動いていなければ 503(retryable: false)、ルームがまだ開かれていなければ 404 が返ります。
参加トークン(POST /rooms/{id}/tokens)は、どのノードでも発行できます。署名の鍵が全ノードで共通だからです。存在しないルームを指定すると、そのルームが自動で作られます(auto: true)。
シグナリング(接続のための情報のやりとり)には、/api/v1 の外にある GET /signaling を使います。WebSocket(RFC 6455)でつなぎ、subprotocol senca.rooms.v1 の指定が必須です。接続先の URL は、ルームやトークン発行の応答の signaling_url に入っています。--public-http-url の http を ws に(https なら wss に)替えて /signaling を付けたもので、ルームが別のノードにあればそのノードの URL になります。
接続したら、最初のメッセージ connect {version: 1, room_id, token, role, ...} で参加トークンを渡します。HTTP の Authorization ヘッダーは使いません。ルームが別のノードにある場合、サーバーは redirect {location} を送って切断します(close code 4300)。
WebRTC が動いていないノードは 503(text/plain)を返します。subprotocol が無いなど、WebSocket の接続の手順に誤りがあれば 4xx です。メッセージの形式は「シグナリングの仕様」のページにまとめてあります。
ルームでの出来事(参加・退出・トラック・スポットライト)は、GET /events に room.* のイベントとして届きます。
POST /api/v1/rooms
{"id":"demo","settings":{"max_participants":10,"video_codec":"vp8","spotlight":{"number":2}},"metadata":{"title":"standup"}}
POST /api/v1/rooms/demo/tokens
{"role":"sendrecv","client_id":"alice","metadata":{"name":"Alice"},"ttl_secs":600} POST /api/v1/rooms/demo/messages
{"label":"#chat","data":"hello"} POST /rooms ルームの作成 stream:write
- パス
- POST /api/v1/rooms
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · RoomCreate
- 成功したとき
- 201 作成しました · Room
- 返す状態コード
- 201 · 400 · 401 · 403 · 409 · 415 · 422 · 500
ルームを作成します。id を省略すると、24 文字の 16 進数を生成します。作成したルームはグリッドのワークロード(room:{id})になり、スケジューラーが割り当てたノードで開かれます。
ルームはテナントあたり 10000 個まで作成できます(超えると 403 QUOTA_EXCEEDED)。
settings には、ルームを開くときと同じ検査(形式と値の範囲)を行います。違反すると 400 で、details.errors に項目ごとの理由が入ります。
主なエラー(この順に検査します):
- 本文の形式の誤り: 400(
INVALID_REQUEST)・415 idの誤り(使えるのは 1〜128 文字の英数字と-_.:@): 400settingsの誤り: 400metadataが大きすぎる(JSON で 8 KiB まで): 400placementの誤り: 400(PlacementSpec。nodeにはノードの ID か名前を指定でき、応答では ID に変換されます。degradeは使えません)- 同じ ID のルームがある(ほかのテナントのルームであっても): 409
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| id | RoomId | ルームの ID(1〜128 文字の英数字と -_.:@)。省略すると 24 文字の 16 進数を生成します |
| settings | RoomSettings | null | ルームの設定。省略または null で既定値になります |
| metadata | RoomMetadata | ルームの metadata(任意の JSON。JSON にして 8 KiB まで) |
| placement | PlacementSpec | null | 配置の指定(PlacementSpec。degrade は使えません) |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /rooms ルームの一覧 stream:read
- パス
- GET /api/v1/rooms
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 ルームの一覧 · RoomList
- 返す状態コード
- 200 · 400 · 401 · 403
テナントのルームを、ID の昇順で返します。参加トークンの発行で自動作成されたルームも含みます。
クエリパラメーター
- limit — 1 回に返す件数(1〜1000、既定 100)
- cursor — 前の応答の
next_cursorの値(最後に返した ID)。これより大きい ID から返します
GET /rooms/{id} ルームの取得(定義と配置先) stream:read
- パス
- GET /api/v1/rooms/{id}
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 ルーム · Room
- 返す状態コード
- 200 · 401 · 403 · 404
ルームの定義、配置の結果(placement_status)、シグナリングの接続先(signaling_url)を返します。参加者などの今の状態は、GET /rooms/{id}/participants・/stats で取得します。ほかのテナントのルームは 404 です。
PATCH /rooms/{id} ルームの変更 stream:write
- パス
- PATCH /api/v1/rooms/{id}
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · RoomPatch
- 成功したとき
- 200 変更後のルーム · Room
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 412 · 415 · 422 · 428 · 500
ルームの settings・metadata・placement を変更します。If-Match が必須です。
settings は JSON Merge Patch(RFC 7396)で変更します。書いた項目だけが変わり、値を null にした項目は既定値に戻ります。spotlight などの入れ子の項目も同じです。settings・metadata そのものを null にすると「変更しない」という意味になります。placement は null で削除できます。変更後の設定は、作成と同じ決まりで検査します。
settings.recording を per_participant か composite にすると、ルームを録画するためのメディアパイプライン(ID は room-rec.{ルームの ID}、managed: true)を作成・更新します。none に戻すと、そのメディアパイプラインを削除します(エクスポートしたストリームと録画は残ります)。
合成や文字起こしのメディアパイプラインがあるルームは、E2EE(e2ee: true)にできません(422、details.reason: "e2ee")。
ルームに参加者がいる間は、e2ee・video_codec・audio_codec を変更できません(409)。この確認は、リクエストを受けたノードがルームを開いているノードの場合にだけ行います。
変更は、ルームを開いているノードへ少し遅れて伝わります。スポットライトの変更は、参加者側の指定にも反映されます。
主なエラー(この順に検査します): If-Match が無い・誤っている(428・412)、本文の形式の誤り(400・415)、ルームが無い(404)、世代が古い(412)、作成と同じ検査(400)。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| settings | RoomSettings | null | 変更する設定の項目だけを書きます(JSON Merge Patch)。書かない項目はそのまま残り、値を null にした項目は既定値に戻ります |
| metadata | RoomMetadata | ルームの metadata(任意の JSON。JSON にして 8 KiB まで)。null は「変更しない」という意味です |
| placement | PlacementSpec | null | 配置の指定の全体を置き換えます(degrade は使えません)。null で削除します |
* は必須の項目です。ここに無い項目を送ると 400 になります。
DELETE /rooms/{id} ルームの削除 stream:write
- パス
- DELETE /api/v1/rooms/{id}
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404 · 500
ルームを削除します。参加者には room_deleted を送って切断します(切断は少し遅れて行われます)。If-Match は検査しません。
ルームのメディアパイプライン(media-pipelines)も削除され、それが作った合成のパイプラインと外部配信の出力も削除されます。エクスポートしたストリームと録画は残ります。
このとき、メディアパイプラインの media_pipeline.deleted イベントは届きません(届くのは room.deleted だけです)。
POST /rooms/{id}/tokens 参加トークンの発行 stream:write
- パス
- POST /api/v1/rooms/{id}/tokens
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · RoomTokenRequest
- 成功したとき
- 201 発行しました · RoomToken
- 返す状態コード
- 201 · 400 · 401 · 403 · 404 · 409 · 415 · 500 · 503
参加者がルームに入るための参加トークンを発行します。シグナリングの connect で token として渡します。
トークンは EdDSA(Ed25519)で署名した JWT です。claim には room・role・client_id・bundle_id・metadata・permissions と、exp・iat・jti が入ります。署名の鍵は全ノードで同じなので、どのノードで発行したトークンも、すべてのノードで使えます。
ルームが無ければ、既定の設定で自動的に作成します(auto: true)。自動で作ったルームは、誰もいない状態が empty_timeout_secs 続くと削除されます。このときの room.updated イベントでは data.auto: true です。
有効期間 ttl_secs の既定は 600 秒で、expires_at は RFC 3339 の形式です。同じ Idempotency-Key で再送したときの応答では、token を伏せます(token: null・token_redacted: true)。
主なエラー:
- ほかのテナントのルームの ID を指定した、ルームの ID の形式が誤っている: 404
- 本文の形式の誤り: 400・415
ttl_secsが 10〜86400 の範囲外: 400client_id・bundle_idが 1〜255 文字でない、または制御文字を含む: 400metadataが 8 KiB を超える: 400- 起動した直後で、署名の鍵がまだ無い: 503(
retryable: true)
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| role* | "sendrecv" | "sendonly" | "recvonly" | 許す役割の上限。sendrecv(送受信)・sendonly(送信だけ)・recvonly(受信だけ)。sendrecv のトークンなら、どの役割でも参加できます |
| client_id | string | null | 参加者の識別子(1〜255 文字)。指定すると、connect の client_id はこれと同じ値でなければなりません(転送フィルターの条件に使われます) |
| bundle_id | string | null | 同じ値を持つ接続どうしは、互いのトラックを受信しません(1〜255 文字) |
| metadata | RoomMetadata | 参加者の metadata(任意の JSON。8 KiB まで)。ほかの参加者にも見えます |
| permissions | RoomPermissions | null | 参加者に許す操作。省略するとすべて許します。publish(送信してよいトラックの種類。既定 ["audio", "video"])、subscribe(ほかの参加者のトラックを受信してよいか。既定 true)、data(使ってよい DataChannel のラベルのパターン。既定 ["#*"] ですべて) |
| ttl_secs | integer | null | 有効期間(秒。10〜86400、既定 600) |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /rooms/{id}/participants 参加者の一覧 stream:read
- パス
- GET /api/v1/rooms/{id}/participants
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 参加者の一覧 · ParticipantList
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 500 · 503
ルームの参加者を、connection_id の昇順で返します。このノードに接続している参加者のほか、カスケードで別のノードにいる参加者(signaling: remote)も含みます。
リクエストは、ルームを開いているノードへ転送されます(rooms の説明を参照)。配置先が決まっていない、または WebRTC が動いていなければ 503、ルームがまだ開かれていなければ 404 です。
next_cursor は、返した件数が limit と同じときだけ入ります(続きが無くても入ることがあります)。返した件数が limit より少なければ、next_cursor の項目そのものがありません。
クエリパラメーター
- limit — 1 回に返す件数(1〜1000、既定 100)
- cursor — 前の応答の
next_cursorの値(最後に返した ID)。これより大きい ID から返します
GET /rooms/{id}/participants/{c} 参加者の取得 stream:read
- パス
- GET /api/v1/rooms/{id}/participants/{c}
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 参加者 · Participant
- 返す状態コード
- 200 · 401 · 403 · 404 · 500 · 503
参加者 1 人の情報を返します(subscriptions は受信の枠です)。リクエストは、ルームを開いているノードへ転送されます。参加していない接続を指定すると 404 です。
PATCH /rooms/{id}/participants/{c} 参加者の metadata の変更 stream:write
- パス
- PATCH /api/v1/rooms/{id}/participants/{c}
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · ParticipantPatch
- 成功したとき
- 200 変更後の参加者 · Participant
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 415 · 500 · 503
参加者の metadata を置き換え、ルームの全員に notify {event: connection.updated} を送ります(SSE では room.connection.updated)。
参加者には世代が無いため、If-Match は検査しません。どのノードで受けても、参加者が接続しているノード(カスケードでつながった edge のノードを含む)へ転送して変更します。転送は、ルームを開いているノード、参加者のノードの順に、2 段までです。参加していない接続を指定すると 404 です。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| metadata* | RoomMetadata | 参加者の metadata(任意の JSON。JSON にして 8 KiB まで)。ほかの参加者にも見えます |
* は必須の項目です。ここに無い項目を送ると 400 になります。
DELETE /rooms/{id}/participants/{c} 参加者の切断 stream:write
- パス
- DELETE /api/v1/rooms/{id}/participants/{c}
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404 · 500 · 503
参加者をルームから退出させます(シグナリングでは disconnect {reason: kicked} が届きます)。トークンは無効にならないため、同じトークンで再び入室できます。どのノードで受けても、参加者が接続しているノード(カスケードでつながった edge のノードを含む)へ転送して切断します。参加していない接続を指定すると 404 です。
POST /rooms/{id}/messages ルーム・参加者へのメッセージの送信 stream:write
- パス
- POST /api/v1/rooms/{id}/messages
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · RoomMessage
- 成功したとき
- 200 送信しました · RoomMessageResult
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 415 · 500 · 503
ルームの参加者へメッセージを送ります。label が無ければ、シグナリングの push {data} で JSON のまま送ります。label があれば、そのラベルの DataChannel を開いている参加者へ、DataChannel で送ります(このとき data は文字列です)。
to(connection_id の配列)が空なら全員に送ります。ルームにいない接続が to に含まれていれば 404 です。data は JSON で 64 KiB まで、label は # で始めてください(違反すると 400)。
応答の delivered は、送った相手の数です(誰もいなければ 0)。リクエストは、ルームを開いているノードへ転送されます。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| to | string[] | 送信先の connection_id の配列(空なら全員) |
| label | string | null | DataChannel のラベル(# で始めます)。省略すると、シグナリングの push で送ります |
| data* | object | 送る内容(JSON で 64 KiB まで)。label があるときは文字列にします |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /rooms/{id}/stats ルームの統計 stream:read
- パス
- GET /api/v1/rooms/{id}/stats
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 統計 · RoomStats
- 返す状態コード
- 200 · 401 · 403 · 404 · 500 · 503
ルームを開いているノードに接続している参加者ごとに、次の値を返します: RTT(往復の遅延)、推定帯域、送受信の量、送信している層(サイマルキャストで画質ごとに分けて送る映像)ごとのビットレート、受信している層、クライアントの getStats の要約。
カスケードで別のノードにいる参加者は含みません。リクエストは、ルームを開いているノードへ転送されます。
メディアパイプライン
media-pipelines · 5 個の操作会議を録画したい、会議を 1 つの画面に合成して外部へ配信したい、といったときに使います(AWS の Chime SDK Media Pipelines に当たります)。参加者の映像を SENCA のストリームとしてエクスポートし、それを録画・合成・外部への配信・文字起こしのどれに回すかを、1 つの定義にまとめて書きます。定義はクラスターのどのノードでも受け付けます。
| AWS(Chime SDK Media Pipelines) | SENCA |
|---|---|
| Media stream pipeline(Kinesis Video Streams へ送る) | 参加者ごとのストリーム(export_participants)。エクスポートした後は、通常のストリームと同じく HLS・録画・出力・パイプラインで扱えます |
| Media capture pipeline(会議を録画する) | recording(参加者ごとのストリームと、合成したストリームを自動で録画します。保存先はノードのデータディレクトリです) |
| Media concatenation pipeline | 録画の断片を 1 本にまとめるには、通常の録画の API(GET /recordings/{id}/export.mp4・VOD の HLS)を使います |
| Media live connector pipeline(会議を RTMP へ送る) | egress(合成したストリームの出力。RTMP・SRT・配信サービスとの連携。composite が必要です) |
| Media insights pipeline(文字起こし・分析) | captions(参加者ごとのストリームの字幕と翻訳。CaptionSettings。export_participants が必要です) |
実行するのは、ルームを開いているノード(GET /rooms/{id} の placement_status.node)です。毎秒参加者を確かめて、エクスポートの状態を合わせます。ルームが別のノードへ移れば、移った先のノードが引き継ぎます。実行されるのは desired_state: running のものだけです。
参加者ごとのストリームは、参加者 1 人につき 1 本作られます(参加者は client_id で、無ければ connection_id で区別します)。参加者が送った映像(最も品質の高い層)と音声は、再エンコードせずにそのまま流れます。participants が空なら全員が対象で、指定すればその client_id の参加者だけになります。カスケード(ルームを複数のノードにまたがって開く構成)で別のノードにいる参加者も、そのノードから中継してエクスポートします。
エクスポートしたストリームの metadata には media_pipeline(メディアパイプラインの ID)と room が入り、名前は {name}-{参加者}-{ID の先頭 6 文字} になります。これらのストリームには使えない鍵が設定してあるので、ストリームキーでの配信は受け付けません。ルームの video_codec が H.264・H.265 なら codec_profile: any、それ以外なら royalty_free になります。
合成(composite)を指定すると、映像のある参加者を並べ、音声はすべてミックスして 1 本のストリームにするパイプラインが作られます。このパイプラインはルームを開いているノードで動きます。参加者はその人のストリームが流れ始めた時点で画面に加わり、参加者が入れ替わると並びも変わります。映像のある参加者が 1 人もいなければ、パイプラインは stopped になります。
並べ方は grid(格子状)か speaker(話している人を大きく表示)です。speaker ではルームの話者の検出で話者を選び、話している間と、切り替えてから 2 秒間は表示を替えません。切り替えた映像はキーフレームから始まります。今の話者は status.active_speaker でわかります。
合成のパイプラインや外部配信の出力の ID は、メディアパイプラインの ID から決まるので、何度作り直しても変わりません。これらは artifacts に表示され、通常の GET /pipelines/{id}・GET /outputs/{id} でも取得できます。
メディアパイプラインやルームを削除したとき、stopped にしたとき、合成や外部配信の設定を変えたときは、合成のパイプラインと外部配信の出力が削除されます(動かし続ける場合は作り直されます)。一方、エクスポートしたストリームと録画は成果物として残ります。不要になったら DELETE /streams/{id} で削除してください。
作成・更新すると media_pipeline.updated(data: {room, desired_state})が、削除すると media_pipeline.deleted(data: {})が GET /events に届きます。
POST /api/v1/media-pipelines
{
"name": "mtg", "room": "meet",
"composite": {"layout":"grid","width":640,"height":360,"fps":30,"video_codec":"av1","bitrate_kbps":800},
"recording": {"participants":true,"composite":true},
"egress": [{"protocol":"rtmp_push","url":"rtmp://live.example.com/app/STREAMKEY"}]
} POST /media-pipelines メディアパイプラインの作成 stream:write
- パス
- POST /api/v1/media-pipelines
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · MediaPipelineCreate
- 成功したとき
- 201 作成しました · MediaPipeline
- 返す状態コード
- 201 · 400 · 401 · 403 · 409 · 415 · 422 · 500
ルームのメディアパイプラインを作成します。desired_state の既定は running なので、作成するとすぐ、ルームを開いているノードが実行を始めます。
メディアパイプラインはルームあたり 8 つまでです(超えると 403 QUOTA_EXCEEDED)。name はテナント内で一意です(重複すると 409)。
H.264・H.265 で合成するには GPU が必要ですが、作成のときには確かめません。GPU が無ければ、合成のパイプラインの配置や検証で失敗し、そのパイプラインの placement_status に表示されます。
主なエラー(この順に検査します):
- 本文の形式の誤り: 400(
INVALID_REQUEST)・415 roomがテナントのルームでない: 400(INVALID_CONFIG)- 内容の誤り(下の一覧を参照): 400(
INVALID_CONFIG) nameの重複: 409- ルームあたりの上限を超えた: 403(
QUOTA_EXCEEDED)
内容の検査(この順に行います):
name: 1〜40 文字の英数字と-_.(.で始めることはできません)。エクスポートするストリームの名前に使うため、ストリームの名前より短くしてありますdesired_state:runningかstoppedparticipants: 100 人まで。それぞれ 1〜255 バイトcomposite:layout(grid・speaker)、サイズ(幅 64〜3840・高さ 64〜2160 の偶数)、fps(1〜60)、video_codec(av1・vp9・vp8・h264・h265)、bitrate_kbps(100〜50000)recording:composite: trueにはcompositeの指定が、participants: trueにはexport_participants: trueが必要です。retention_daysは 1〜36500 です。recordingのparticipants・compositeは、省略すると true になります。compositeの無いメディアパイプラインでrecordingを指定するときは、composite: falseを明示してくださいegress:compositeが必要です(合成した 1 本を送ります)。8 個まで指定できます。各要素には、出力(OutputCreate)と同じ検査を行います(protocol、paas以外ではurl、paasではprovider、credential_refのシークレット、options)captions: ストリームのcaptionsと同じ検査を行います(CaptionSettings)。export_participants: trueが必要です
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| name* | MediaPipelineName | メディアパイプラインの名前。1〜40 文字の英数字と -_.(. で始めることはできません)。テナント内で一意です。エクスポートするストリームやパイプラインの名前の先頭に使われます |
| room* | string | ルームの ID(テナントのルーム。無ければ 400) |
| participants | MediaPipelineParticipants | エクスポートする参加者の client_id(参加トークンの client_id)の配列。空なら全員です(client_id の無い参加者は connection_id で区別します) |
| export_participants | boolean | null | 参加者ごとのストリームを成果物として残します(AWS の media stream pipeline に相当。既定 true)。false でも合成のためにエクスポートしますが、recording.participants・captions は使えません |
| composite | MediaPipelineComposite | null | 合成の設定(会議全体を 1 本の映像・音声にします)。省略または null で合成しません |
| recording | MediaPipelineRecording | null | 録画の設定。省略または null で録画しません |
| egress | MediaPipelineEgress[] | 外部への配信の設定(8 個まで。composite が必要です) |
| captions | CaptionSettings | null | 文字起こしと翻訳の設定(AWS の media insights pipeline に相当)。参加者ごとのストリームの captions として設定されます。省略または null で設定しません |
| desired_state | MediaPipelineState | null | running か stopped。省略または null で running になります |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /media-pipelines メディアパイプラインの一覧 stream:read
- パス
- GET /api/v1/media-pipelines
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 メディアパイプラインの一覧 · MediaPipelineList
- 返す状態コード
- 200 · 400 · 401 · 403
テナントのメディアパイプラインを、ID の昇順で返します。room でルームを指定して絞り込めます(値は URL デコードしてから比べます)。
クエリパラメーター
- room — ルームの ID で絞り込みます
- limit — 1 回に返す件数(1〜1000、既定 100)
- cursor — 前の応答の
next_cursorの値(最後に返した ID)。これより大きい ID から返します
GET /media-pipelines/{id} メディアパイプラインの取得(定義・成果物・状態) stream:read
- パス
- GET /api/v1/media-pipelines/{id}
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 メディアパイプライン · MediaPipeline
- 返す状態コード
- 200 · 401 · 403 · 404
定義と、作られたリソース(artifacts)、このノードでの実行の状態(status)を返します。ほかのテナントのものは 404 です。
PATCH /media-pipelines/{id} メディアパイプラインの変更・開始・停止 stream:write
- パス
- PATCH /api/v1/media-pipelines/{id}
- 認証・権限
- Bearer トークン・stream:write
- リクエストの本文
- application/json · MediaPipelinePatch
- 成功したとき
- 200 変更後のメディアパイプライン · MediaPipeline
- 返す状態コード
- 200 · 400 · 401 · 403 · 404 · 409 · 412 · 415 · 422 · 428 · 500
指定した項目だけを置き換えます(MediaPipelinePatch)。If-Match が必須です。desired_state: stopped で停止し、running で実行します。
composite・recording・captions は null で設定を削除できます。ほかの項目の null は「変更しない」という意味です。egress は配列全体を置き換えます。
room は変更できません(知らない項目として 400)。ルームの設定 recording から作られたもの(managed: true)も変更できません(409)。ルームの設定のほうを変更してください。
stopped にする、composite を外す、egress を変更する、のいずれかを行うと、それまでの定義で作った合成のパイプラインと外部配信の出力を削除します(動かし続ける場合は作り直します)。エクスポートしたストリームはそのまま残ります。participants を減らしても、対象から外れた参加者のストリームは残ります。
name を変更するときも、テナント内での重複を検査します(409)。
主なエラー(この順に検査します): If-Match が無い・誤っている(428・412)、本文の形式の誤り(400・415)、メディアパイプラインが無い(404)、世代が古い(412)、作成と同じ内容の検査(400)。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| name | MediaPipelineName | null | 新しい名前(決まりは作成と同じです) |
| participants | MediaPipelineParticipants | null | エクスポートする参加者の client_id の配列(空なら全員) |
| export_participants | boolean | null | 参加者ごとのストリームを成果物として残すかどうか |
| composite | MediaPipelineComposite | null | 合成の設定。null で合成をやめます |
| recording | MediaPipelineRecording | null | 録画の設定。null で設定を削除します |
| egress | array | null | 外部への配信の設定。配列全体を置き換えます |
| captions | CaptionSettings | null | 文字起こしと翻訳の設定。null で設定を削除します |
| desired_state | MediaPipelineState | null | running で実行、stopped で停止します |
* は必須の項目です。ここに無い項目を送ると 400 になります。
DELETE /media-pipelines/{id} メディアパイプラインの削除 stream:write
- パス
- DELETE /api/v1/media-pipelines/{id}
- 認証・権限
- Bearer トークン・stream:write
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404 · 409 · 500
メディアパイプラインと、それが作った合成のパイプラインと外部配信の出力を削除します(配信サービス側のリソースも後片付けします)。エクスポートしたストリーム(参加者ごと・合成)と録画は残ります。
managed: true のものは削除できません(409)。ルームの設定 recording を none にしてください。
参加者のエクスポートは、ルームを開いているノードが次に確かめたとき(1 秒以内)に止まります。If-Match は検査しません。
イベント(SSE)
events · 1 個の操作リソースが変わるたびに、その知らせを SSE(Server-Sent Events。HTTP の接続を開いたまま、サーバーから知らせを送り続ける仕組み)で受け取れます。
curl -sN -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8080/api/v1/events GET /events イベントの購読(SSE) stream:read
- パス
- GET /api/v1/events
- 認証・権限
- Bearer トークン・stream:read
- 成功したとき
- 200 イベントのストリーム
- 返す状態コード
- 200 · 401 · 403
接続を開いたまま、リソースの変化をイベントとして送り続けます。届くのは、自分のテナントのイベントだけです。15 秒ごとに、接続を保つためのコメント行を送ります。
テナントに属さないイベント(node.updated・stream.owner、グリッドの node.down・node.up・device.down・device.up・device.disabled・device.enabled・grid.decisions)は、node:admin の権限を持つ利用者にだけ届きます。
SSE の event はイベントの種類で、data は SseEventData の JSON です。id はイベントの通し番号(クラスターに反映した変更の数)です。クラスターではどのノードでも同じ値になるため、別のノードへ再接続しても Last-Event-ID をそのまま使えます。
届くイベントは次のとおりです。
- リソースの変更:
stream.created・stream.updated・stream.deleted・stream.owner・recording.updated・recording.deleted・schedule.created・schedule.updated・schedule.deleted・schedule.run・node.updated・input.updated・input.deleted・output.updated・output.deleted・secret.created・secret.deleted・pipeline.updated・pipeline.deleted・room.updated(ルームの作成・自動作成・更新。data: {auto})・room.deleted・media_pipeline.updated(メディアパイプラインの作成・更新。data: {room, desired_state})・media_pipeline.deleted、グリッドのnode.down・node.up・device.*・grid.decisions(resource_idは空、data: {decisions})。 - ルーム:
room.started(ルームが開かれた)・room.stopped・room.connection.created・room.connection.updated・room.connection.destroyed・room.track.published・room.track.unpublished・room.spotlight.changed。これらは、ルームを開いているノードに接続した購読者にだけ届き、クラスターの記録には残りません。 ルームのイベントには SSE のidがありません。そのためLast-Event-IDでの再開の対象にならず、受け取り損ねた分は、何の知らせもなく失われます。dataにはevent_id(イベントの ID)とnode(ノードの ID)が入り、イベントの内容はdata.dataに入ります。node:adminの権限があっても、ほかのテナントのものは届きません。 ルームを削除したとき(DELETE /rooms/{id}や、自動作成したルームの自動削除)も、room.stoppedと、そのとき切断された参加者のroom.connection.destroyedが届きます。
接続が切れたときは、Last-Event-ID を付けて再接続してください。その番号より後のイベントのうち、ノードに残っている分を先に送り、続けて新しいイベントを送ります。ノードが残すのは、直近の --events-retain 件(既定 4096 件)です。単一ノードでは、再起動した後も、保存した状態のスナップショットより後の分が残ります。
指定した番号が、残っている範囲より古いときは、最初に event: resync(id は今の番号、data: {})を送ります。状態を読み直してから、この id で続きを受け取ってください。クラスターで、接続したノードへの反映が Last-Event-ID に追いついていなければ、最大 3 秒待ちます(追いつかなければ resync を送ります)。
送信が追いつかずに知らせがあふれたときは、残っている分から続きを送ります。残っていなければ、event: resync を送って接続を閉じます。
リソースの変更のイベントの data には、event_id・generation がありません(event_id に当たるのは SSE の id です)。occurred_at は変更を反映した時刻です(再起動の後に読み直したイベントでは、読み直した時刻)。24 時間分を残して再送する仕組みはありません。
401・403 のエラーは、ほかの API と同じ problem+json で返します。
API トークン
tokens · 4 個の操作管理 API を呼び出すためのトークンを発行し、不要になったら失効させます。CI に渡すトークンには読み書きの権限だけを付ける、というように、トークンごとに権限(scope)を絞れます。
POST /api/v1/tokens
{"name":"ci","scopes":["stream:read","stream:write"],"expires_at":"2027-01-01T00:00:00Z"} POST /tokens API トークンの発行 tenant:admin
- パス
- POST /api/v1/tokens
- 認証・権限
- Bearer トークン・tenant:admin
- リクエストの本文
- application/json · TokenCreate
- 成功したとき
- 201 発行しました · Token
- 返す状態コード
- 201 · 400 · 401 · 403 · 409 · 415 · 500
管理 API を呼び出すための API トークンを発行します。トークンの値(token。senca_ で始まります)が返るのは、この応答だけです。必ず控えてください。同じ Idempotency-Key で再送したときの応答では null になり、token_redacted: true が付きます。
自分が持っていない権限を、新しいトークンに付けることはできません(403)。トークンはテナントあたり 100 個までで、超えると 403(QUOTA_EXCEEDED)です。
本文の項目
| 項目 | 型 | 説明 |
|---|---|---|
| name* | string | トークンの名前(1〜64 文字) |
| scopes* | Scope[] | 与える権限の一覧(1 つ以上)。stream:read・stream:write・publish・subscribe・recording:read・recording:delete・tenant:admin・node:admin から選びます。publish は WHIP で配信するとき(ストリームキーの代わり)に、subscribe は POST /streams/{id}/playback-url に使う権限です |
| expires_at | string | null | 有効期限(RFC 3339。未来の時刻) |
* は必須の項目です。ここに無い項目を送ると 400 になります。
GET /tokens API トークンの一覧(値は含みません) tenant:admin
- パス
- GET /api/v1/tokens
- 認証・権限
- Bearer トークン・tenant:admin
- 成功したとき
- 200 トークンの一覧 · TokenList
- 返す状態コード
- 200 · 400 · 401 · 403
トークンを ID の昇順で返します。トークンの値は含みません。
クエリパラメーター
- limit — 1 回に返す件数(1〜1000、既定 100)
- cursor — 前の応答の
next_cursorの値(最後に返した ID)。これより大きい ID から返します
GET /tokens/{id} API トークンの取得(値は含みません) tenant:admin
- パス
- GET /api/v1/tokens/{id}
- 認証・権限
- Bearer トークン・tenant:admin
- 成功したとき
- 200 トークン(`token` は常に null) · Token
- 返す状態コード
- 200 · 401 · 403 · 404
DELETE /tokens/{id} API トークンの失効 tenant:admin
- パス
- DELETE /api/v1/tokens/{id}
- 認証・権限
- Bearer トークン・tenant:admin
- 成功したとき
- 204 成功しました(本文はありません)
- 返す状態コード
- 204 · 401 · 403 · 404 · 409 · 500
トークンを削除して、使えなくします。テナントに残っている最後の tenant:admin のトークンは削除できません(409)。
ノード・グリッド
system · 9 個の操作ノードとデバイスの状態を調べたり、保守のときにノードやデバイスを新しいワークロードの配置先から外したりするための API です。
グリッドとは、クラスター内のノードとデバイス(GPU・キャプチャ機器)にワークロードを割り振る仕組みのことです。各ノードは起動時に自分の資源(CPU・メモリ・帯域・GPU・キャプチャ機器・ラベル)を登録し、その後は毎秒、動いていることをリーダーに知らせます(ハートビート)。
入力・出力・パイプラインなどの実行の単位を、ワークロードと呼びます。どのワークロードをどのノードとデバイスで動かすかはリーダーのスケジューラーが決め、割り当てられたノードだけがそれを実行します。ノードが 1 台の構成では、そのノード自身がリーダーです。
配置の指定は各リソースの placement(PlacementSpec)に書きます。結果は placement_status(PlacementStatus)に、グリッド全体の状態は GET /grid に表示されます。
GET /capabilities 対応している API の版・コーデック・機能の一覧 認証のみ
- パス
- GET /api/v1/capabilities
- 認証・権限
- Bearer トークン・権限は不要(認証だけで使えます)
- 成功したとき
- 200 対応している機能の一覧 · Capabilities
- 返す状態コード
- 200 · 401
このノードが対応している API の版、コーデック、機能を返します。
GET /nodes ノードの一覧 node:admin
- パス
- GET /api/v1/nodes
- 認証・権限
- Bearer トークン・node:admin
- 成功したとき
- 200 ノードの一覧 · NodeList
- 返す状態コード
- 200 · 401 · 403
クラスターのノードをすべて返します。ページングはなく、応答は items だけです(next_cursor はありません)。クエリパラメーターは無視します。
GET /nodes/{id} ノードの取得 node:admin
- パス
- GET /api/v1/nodes/{id}
- 認証・権限
- Bearer トークン・node:admin
- 成功したとき
- 200 ノード · Node
- 返す状態コード
- 200 · 401 · 403 · 404
ノード 1 台の情報を返します。
POST /nodes/{id}/drain ノードへの新しい割り当てを止める(drain) node:admin
- パス
- POST /api/v1/nodes/{id}/drain
- 認証・権限
- Bearer トークン・node:admin
- 成功したとき
- 202 受け付けました(変更後のノード) · Node
- 返す状態コード
- 202 · 400 · 401 · 403 · 404 · 409 · 500
保守の前などに、ノードを drain の状態(新しいワークロードを受けない状態)にします。応答は draining: true になったノードです。リクエストの本文は無視します。
グリッドに登録されたノードであれば、グリッド側の draining も変更します。このノードには新しいワークロードを配置しなくなり、配置済みのワークロードは、移せるものから別のノードへ移します(reason.code: draining)。
drain 中のノードは、新しい配信(RTMP・SRT・WHIP での送信)を拒否します。RTMP では NetStream.Publish.Rejected、SRT では拒否理由 1503 を返します。WHIP では drain 中でない別のノードの /whip/... へ 307 でリダイレクトし、そのようなノードが無ければ 503 を返します。
すでにつながっている配信者と視聴者は、切断しません。
POST /nodes/{id}/undrain drain の解除 node:admin
- パス
- POST /api/v1/nodes/{id}/undrain
- 認証・権限
- Bearer トークン・node:admin
- 成功したとき
- 202 受け付けました(変更後のノード) · Node
- 返す状態コード
- 202 · 400 · 401 · 403 · 404 · 409 · 500
drain を解除して、ノードが新しい割り当てを受けられるようにします。応答は draining: false になったノードです。グリッドに登録されたノードであれば、グリッド側の draining も元に戻します。
GET /devices ノードのデバイス(GPU・キャプチャボード)の一覧 node:admin
- パス
- GET /api/v1/devices
- 認証・権限
- Bearer トークン・node:admin
- 成功したとき
- 200 デバイスの一覧 · Devices
- 返す状態コード
- 200 · 401 · 403
今のところ、リクエストを受けたノード自身のデバイスだけを返します。コーデックワーカー(変換を担当する別プロセス)につながっていないときは、devices は空です。
GET /grid グリッドの状態(ノードの資源と予約、ワークロードの割り当て) node:admin
- パス
- GET /api/v1/grid
- 認証・権限
- Bearer トークン・node:admin
- 成功したとき
- 200 グリッドの状態 · Grid
- 返す状態コード
- 200 · 401 · 403
スケジューラーが把握しているグリッドの状態を返します。
ノードごとに、登録された内容(容量・GPU・キャプチャ機器・ラベル)と予約(割り当てたワークロードが求める資源の合計)を返します。ワークロードごとに、割り当て先・デグレードレベル・配置できない理由を返します。デグレードとは、資源が足りないときに処理の一部を止めて、品質を下げて動かし続けることです。
テナントで絞り込まずにすべてを返すため、node:admin が必要です。クエリパラメーターは無視します。
last_heartbeat は、応答したノードがスケジューラー(リーダー)の場合にだけ値が入ります。
POST /nodes/{id}/devices/{dev}/disable デバイス(GPU・キャプチャ機器)を手動で無効にする node:admin
- パス
- POST /api/v1/nodes/{id}/devices/{dev}/disable
- 認証・権限
- Bearer トークン・node:admin
- 成功したとき
- 202 受け付けました · DeviceHealth
- 返す状態コード
- 202 · 400 · 401 · 403 · 404 · 409 · 500
グリッドのデバイスを手動で無効にします(enabled: false)。デバイスの故障や保守のときに使います。これは、計測で決まる健全性(healthy)とは別の設定です。リクエストの本文は無視します。
無効にしたデバイスを使っていたワークロードは、別のデバイスやノードへ移るか、デグレードして動き続けます。ただし、placement.pin_policy: strict でそのデバイスに固定したワークロードは、止まったままになります。
無効にした状態はクラスター全体に記録され、ハートビートやノードの再登録では元に戻りません。enable で戻すまで続きます。
ノード(ID または名前)やデバイスがグリッドに無ければ 404 です。
POST /nodes/{id}/devices/{dev}/enable 無効にしたデバイスを有効に戻す node:admin
- パス
- POST /api/v1/nodes/{id}/devices/{dev}/enable
- 認証・権限
- Bearer トークン・node:admin
- 成功したとき
- 202 受け付けました · DeviceHealth
- 返す状態コード
- 202 · 400 · 401 · 403 · 404 · 409 · 500
手動で無効にしたデバイスを、有効に戻します(enabled: true)。リクエストの本文は無視します。
ほかへ移ったワークロードやデグレードしたワークロードは、クールダウン(一定の待ち時間)の後に元へ戻ります(reason.code: pin_returned・capacity_returned)。
ノード(ID または名前)やデバイスがグリッドに無ければ 404 です。
再生(署名付き URL)
playback · 4 個の操作視聴者のプレイヤーが、署名付き URL で再生するときに使うパスです。/api/v1 の外にあり、認証ヘッダーは要りません。URL は POST /streams/{id}/playback-url・POST /recordings/{id}/playback-url で発行します。
署名は、HMAC-SHA256(playback_key, "{kind}/{id}/{exp}") の先頭 16 バイトを、パディングなしの base64url にしたものです。署名が違うときや期限が切れているときは 403(text/plain)を返します。応答には Access-Control-Allow-Origin: * が付きます。
クラスターでは、署名を確かめた後、このノードにデータが無ければ(ライブなら配信を受信していない、VOD なら録画を持っていない)、データを持つノードへ 307 でリダイレクトします。リダイレクトするのは、そのノードの公開 URL(media_addr)がわかる場合です。Location は {media_addr}/s/{exp}/{sig}/...?{元のクエリ} で、本文は text/plain です。単一ノードでは 307 を返しません。
GET /s/{exp}/{sig}/live/{stream}/index.m3u8 ライブ HLS のプレイリスト(LL-HLS のブロッキング・リロードに対応) 認証なし
- パス
- GET /s/{exp}/{sig}/live/{stream}/index.m3u8
- 認証・権限
- 不要(URL の署名で確かめます)
- 成功したとき
- 200 プレイリスト(`Cache-Control: no-cache`)
- 返す状態コード
- 200 · 307 · 400 · 403 · 404 · 503
映像・音声のメディアプレイリストを返します。LL-HLS のブロッキング・リロード(新しいセグメントができるまで応答を待たせる方式)に対応しています。
ストリームに captions を設定していて字幕ができ始めると、字幕付きのマルチバリアントプレイリスト(master.m3u8)も取得できます(GET /s/.../live/{stream}/{file})。
このノードも、リダイレクト先にできるほかのノードも配信を受信していなければ 404 です。
クエリパラメーター
- _HLS_msn — 指定した Media Sequence 番号のセグメントが現れるまで待ちます(最長 6 秒)
- _HLS_part —
_HLS_msnのセグメントの中の part 番号 - _HLS_skip — 差分だけのプレイリストを求めます(Playlist Delta Update)
GET /s/{exp}/{sig}/live/{stream}/{file} ライブ HLS のセグメント・part・init・字幕 認証なし
- パス
- GET /s/{exp}/{sig}/live/{stream}/{file}
- 認証・権限
- 不要(URL の署名で確かめます)
- 成功したとき
- 200 セグメント(`Cache-Control: max-age=60`)、または字幕のプレイリストと WebVTT(`Cache-Control: no-cache`)
- 返す状態コード
- 200 · 307 · 403 · 404
ライブ HLS のファイルを、ノードのメモリから返します。
- セグメント・part・init:
video/mp2t・video/mp4・video/iso.segmentで返します。Cache-Control: max-age=60です。 - 字幕(ストリームに
captionsを設定しているとき):master.m3u8(index.m3u8と、字幕のEXT-X-MEDIA:TYPE=SUBTITLESをまとめたマルチバリアントプレイリスト)、sub_{lang}.m3u8(言語ごとの字幕のメディアプレイリスト。langはcaptions.languageとcaptions.targetsの言語)、sub_{lang}_{n}.vtt(WebVTT のセグメント。古いものから削除されます)。 どれもCache-Control: no-cacheです。字幕がまだできていなければ 404 です。
GET /s/{exp}/{sig}/vod/{recording}/index.m3u8 録画の HLS プレイリスト 認証なし
- パス
- GET /s/{exp}/{sig}/vod/{recording}/index.m3u8
- 認証・権限
- 不要(URL の署名で確かめます)
- 成功したとき
- 200 プレイリスト
- 返す状態コード
- 200 · 307 · 403 · 404
確定した録画は VOD(ENDLIST あり)として、録画中の録画は EVENT(ENDLIST なし)として返します。削除中の録画は 404 です。
GET /s/{exp}/{sig}/vod/{recording}/{file} 録画のセグメント(Range に対応) 認証なし
- パス
- GET /s/{exp}/{sig}/vod/{recording}/{file}
- 認証・権限
- 不要(URL の署名で確かめます)
- 成功したとき
- 200 セグメント(`Accept-Ranges: bytes`、`Cache-Control: max-age=3600`)
- 返す状態コード
- 200 · 206 · 307 · 403 · 404 · 416
録画のセグメントを返します。Range ヘッダーで一部だけを取得できます。
ヘルスチェック
health · 2 個の操作ノードが動いているか(/healthz)と、リクエストを受け付けられるか(/readyz)を確かめるためのパスです。/api/v1 の外にあり、認証は要りません。
GET /healthz 動いているかの確認(liveness) 認証なし
- パス
- GET /healthz
- 認証・権限
- 不要
- 成功したとき
- 200 本文は `ok`
- 返す状態コード
- 200
ノードのプロセスが動いていれば、200 と ok を返します。
GET /readyz リクエストを受け付けられるかの確認(readiness) 認証なし
- パス
- GET /readyz
- 認証・権限
- 不要
- 成功したとき
- 200 本文は `ready`
- 返す状態コード
- 200 · 503
起動の処理が終わると 200 を返します。停止の処理中(SIGTERM を受けた後)は 503 です。クラスターでは、過半数のノード(またはリーダー)との通信が 4 秒を超えて途絶えている間も 503 です。このときノードは、グリッドのワークロードを止めています。
WHIP・WHEP(WebRTC)
ブラウザなどから WebRTC で配信・再生するときは、/api/v1 の外にある次のパスを使います。使えるのは --webrtc-udp を指定して起動したノードだけです。パスにはストリームの ID を入れます。
| 操作 | リクエスト | 応答 |
|---|---|---|
| 配信の開始(WHIP) | POST /whip/{stream_id} Authorization: Bearer {stream_key} Content-Type: application/sdp(offer) | 201。answer(application/sdp)と Location を返します |
| 接続の候補の追加・接続のやり直し(trickle ICE・ICE restart) | PATCH {Location} application/trickle-ice-sdpfrag | 204、または 200 と sdpfrag を返します |
| 終了 | DELETE {Location} | 200 |
| 再生(WHEP) | POST {再生 URL の whep} (/whep/{stream_id}?exp=…&sig=…) Content-Type: application/sdp(offer) | 201。answer と Location を返します(PATCH・DELETE は WHIP と同じです)。AAC の音声は送りません |
WHIP の認証には、ストリームキーのほか、publish の権限を持つ API トークン(または JWT)も使えます。受け付けるコーデックは H.264・VP8・VP9 profile 0・AV1・Opus・PCMU・PCMA です。詳しくは 取り込みと再生 を参照してください。
ルームのシグナリング
ルームに参加するには、WebSocket で GET /signaling に接続します(subprotocol senca.rooms.v1 の指定が必須です)。1 つのテキストフレームに 1 つの JSON メッセージを入れ、最初の connect で参加トークンを渡します。offer は常にクライアントが送り、サーバーは answer を返すだけです。
client server
|-- WebSocket (senca.rooms.v1) -------->|
|-- connect {version, room_id, token} ->|
|<- connected {connection_id, participants, recv_slots}
|-- offer {sdp} ----------------------->|
|<- answer {sdp, slots, published} -----|
| ... ICE(ICE-lite)・DTLS・メディア ...
|<- notify {connection.created / track.added ...}
|<- renegotiate {audio, video} ---------|
|-- offer {sdp}(受信スロットを追加)-->|
|<- answer {sdp, slots} ----------------|
|<- ping / -- pong --> | 10 秒ごと
|-- disconnect ------------------------>| クライアント → サーバー
connect · offer · candidate · pong · layer · message · stats · disconnect
サーバー → クライアント
connected · answer · slots · renegotiate · notify · push · message · ping · switched · redirect · error · disconnect
上限
1 つのメッセージは 256 KiB まで、metadata は 8 KiB まで、アプリケーションのメッセージは 64 KiB までです。送れるのは毎秒 50 メッセージまでです。知らない type や項目を送ると、bad_message のエラーになります。