Problem
Going live from the dev frontend (localhost:3000 → local backend) hangs forever at "Connecting…". The panel's connect() resolves when the WebSocket opens, but the on-air cockpit only renders after the backend sends its connected frame — which it emits only once start_stream has successfully pushed to a producer target (the Icecast harbor). Locally there is no harbor, so start_stream fails or blocks and the panel sits in "Connecting…" with no error and no timeout.
Consequence: the entire Live Panel 2.0 on-air experience (spectrum analyzers, connection & upload card, RTT tile, auto-bitrate, Telegram chat card) cannot be smoke-tested locally — only the pre-air /test rehearsal and prod work today. Stale "Recording failed / N s empty" shows are a side effect of these dead local attempts.
Goal
A one-command local streaming target so a developer can exercise the full capture → MediaRecorder → WS → producer → Icecast pipeline on localhost and actually go live.
Scope
- Local Icecast (+ Liquidsoap harbor) via docker-compose mirroring the prod topology (
docs/stream-rework/prod/icecast.xml, moafunk.liq) with a dev-only password. A docker compose -f … up (or a make target) should bring up /live + /test mounts reachable at a known localhost URL.
- Dev env wiring: document/scaffold the local
.env producer target (ICECAST_* / STREAM_OUTPUT=icecast) so start_stream points at the local harbor instead of the retired NMS/RTMP target. (Agent can't read .env; provide an .env.example diff + README steps.)
- Preview URL: the stream spectrum + monitor need
VITE_STREAM_ICECAST_TEST_URL pointing at the local mount with a valid Access-Control-Allow-Origin (Icecast-KH default). Confirm CORS works over plain http://localhost.
- README /
/workflow.setup: a short "test streaming locally" section.
Sub-issue worth splitting out: go-live timeout
Independent of the harbor, the panel should not hang indefinitely. When start_stream blocks, "Connecting…" persists with no feedback. Add a go-live timeout (~15 s) that surfaces goLiveError ("still connecting — check the relay / producer target") instead of an infinite spinner. Small, self-contained frontend change in FlowOnAir.vue (handleGoLive); could ship first as a quick UX win.
Acceptance
Problem
Going live from the dev frontend (
localhost:3000→ local backend) hangs forever at "Connecting…". The panel'sconnect()resolves when the WebSocket opens, but the on-air cockpit only renders after the backend sends itsconnectedframe — which it emits only oncestart_streamhas successfully pushed to a producer target (the Icecast harbor). Locally there is no harbor, sostart_streamfails or blocks and the panel sits in "Connecting…" with no error and no timeout.Consequence: the entire Live Panel 2.0 on-air experience (spectrum analyzers, connection & upload card, RTT tile, auto-bitrate, Telegram chat card) cannot be smoke-tested locally — only the pre-air
/testrehearsal and prod work today. Stale "Recording failed / N s empty" shows are a side effect of these dead local attempts.Goal
A one-command local streaming target so a developer can exercise the full capture → MediaRecorder → WS → producer → Icecast pipeline on
localhostand actually go live.Scope
docs/stream-rework/prod/icecast.xml,moafunk.liq) with a dev-only password. Adocker compose -f … up(or a make target) should bring up/live+/testmounts reachable at a known localhost URL..envproducer target (ICECAST_*/STREAM_OUTPUT=icecast) sostart_streampoints at the local harbor instead of the retired NMS/RTMP target. (Agent can't read.env; provide an.env.examplediff + README steps.)VITE_STREAM_ICECAST_TEST_URLpointing at the local mount with a validAccess-Control-Allow-Origin(Icecast-KH default). Confirm CORS works over plainhttp://localhost./workflow.setup: a short "test streaming locally" section.Sub-issue worth splitting out: go-live timeout
Independent of the harbor, the panel should not hang indefinitely. When
start_streamblocks, "Connecting…" persists with no feedback. Add a go-live timeout (~15 s) that surfacesgoLiveError("still connecting — check the relay / producer target") instead of an infinite spinner. Small, self-contained frontend change inFlowOnAir.vue(handleGoLive); could ship first as a quick UX win.Acceptance
docker compose up(or make target) brings up a local Icecast/harbor with/live+/test.env, "Go live" onlocalhostreaches the on-air cockpit (not stuck at "Connecting…")