Skip to content

feat(recording): auto-record on go-live + server-driven finalize (#169)#180

Merged
anneoneone merged 1 commit into
mainfrom
feat/auto-record-on-go-live
Jun 1, 2026
Merged

feat(recording): auto-record on go-live + server-driven finalize (#169)#180
anneoneone merged 1 commit into
mainfrom
feat/auto-record-on-go-live

Conversation

@anneoneone
Copy link
Copy Markdown
Collaborator

Closes #169 — Phase 1 of the stream rework (#164).

What

Makes show recording automatic and resilient to the browser lifecycle, and stops silently swallowing recording write failures.

Auto-record on go-live (server-driven)

  • The live WS now carries the show: /ws/stream?show_id=N. The backend starts the recording tee on connect — no separate POST /api/recording/start from the frontend.
  • Reconnects are a no-op that resume the existing archive (no file truncation, no fragmentation).

Grace-period finalize (decoupled from the tab)

  • A WS drop no longer ends the recording. A 30s grace timer (FINALIZE_GRACE) lets a reconnect resume the same archive.
  • Explicit stop ('stop' message or POST /api/stream/stop) finalizes immediately.
  • finalize_and_upload(state) + ensure_recording_started(state, show_id) are the single source of truth, reused by the HTTP stop endpoint, the WS lifecycle, and the grace task. Idempotent — exactly one upload per session (manager.stop() takes the session).

Surface write failures

  • stream_bridge::write_chunk now logs at error!, sets recording_failed on StreamStatus, drops the corrupt file handle, and the finalized DB version is marked failed with the error — instead of warn!+Ok. The live broadcast is unaffected.

Files

backend/: stream_bridge.rs, handlers/recording.rs, handlers/stream_ws.rs, main.rs (new recording_finalizer abort handle on AppState).
frontend/: useStreamSocket.ts (carries show_id across reconnects), FlowOnAir.vue / FlowWaiting.vue (drop redundant recordingApi.start()).

Verification

  • cargo build / fmt clean; clippy shows only pre-existing warnings in touched files.
  • frontend npm run lint clean; npm run typecheck fails identically on the clean base (.vue resolution — environmental), no new errors.
  • cargo test not run: pre-existing broken test target (recording.rs:440, u64 >= 0). These paths are integration-level (WS/S3/ffmpeg).

Follow-ups (not in this PR)

  • The "Record stream" toggle (flow.recordStream) is now vestigial — recording is always automatic. Worth removing/repurposing.
  • recordingApi.stop() calls remain in FlowOnAir/FlowStreaming; harmless (same idempotent finalize path) but cleanable.

…ace write failures

Make show recording automatic and resilient to the browser lifecycle, and stop
silently swallowing recording write failures. Closes #169 (Phase 1 of #164).

- Auto-start recording when a live stream goes live: the show id is passed via
  `/ws/stream?show_id=N` and the backend starts the tee on connect (no separate
  frontend call). Reconnects are a no-op that resume the existing archive.
- Grace-period finalize: a WS drop no longer ends the recording. A 30s timer
  (FINALIZE_GRACE) lets a reconnect resume the same archive instead of
  fragmenting it; explicit stop ('stop' msg / POST /api/stream/stop) finalizes
  immediately. Decouples the archive from a dropped tab.
- Extract finalize_and_upload(state) + ensure_recording_started(state, show_id)
  as the single source of truth, reused by the HTTP stop endpoint, the WS
  lifecycle, and the grace task (idempotent: one upload per session).
- Surface recording write failures: write_chunk now logs at error, sets
  recording_failed on StreamStatus, drops the corrupt file handle, and marks the
  DB recording version 'failed' — instead of warn!+Ok. Live stream is unaffected.
- Frontend: useStreamSocket.connect(force, showId) carries show_id across
  reconnects; FlowWaiting/FlowOnAir drop their recordingApi.start() calls.
@anneoneone anneoneone merged commit 6c6f61e into main Jun 1, 2026
1 check passed
@anneoneone anneoneone deleted the feat/auto-record-on-go-live branch June 1, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recording: auto-record on go-live, decouple from browser, stop swallowing write failures

1 participant