Routes: channel + playlist CRUD, start/stop/play/pause/skip transport, as-run log. RBAC via assertProjectAccess on channel.project_id; null project ⇒ admin-only (recorder convention). Sidecar orchestration mirrors recorders.js: Docker socket for local node, node-agent /sidecar/start for remote. Channel start passes CHANNEL_ID env so the sidecar can write HLS preview to /media/live/<id>. DeckLink port-contention guard: blocks starting a decklink channel when a recorder or another channel on the same node+device_index is active. restartChannel(id) helper picks another healthy cluster node and re-places non-decklink channels; decklink is alert-only. Exposed for the scheduler. Scheduler tick adds step 6: poll each running channel's sidecar /status, update last_heartbeat_at, and after ~3 misses trigger restartChannel + self-call /start. Reuses the existing PG advisory lock so multi-replica deploys don't double-fire failovers. |
||
|---|---|---|
| .. | ||
| src | ||
| test | ||
| .env.example | ||
| .gitignore | ||
| Dockerfile | ||
| package-lock.json | ||
| package.json | ||