Work
An ffmpeg relay between every camera and Cloudflare
A court's stream ran only while a paid session did, through three pipelines in turn, the last one on the platform's own server.
↓
The constraint
Encoding and recording were billed per minute, and a camera fixed to a court streamed whether or not a session was in progress. A session started by QR code and ran for a set time. The stream had to start with it and stop with it.
MediaLive
- One channel per court, reconfigured inside the web request that started the session: stop, wait for idle, push encoder settings, wait again, start, wait for running.
- Each wait was allowed up to three minutes.
- A new input was created at every session start and the old one left in place; idle inputs accumulated and kept billing.
Mux
- Mux was adopted seventeen days in. It handled ingest and adaptive bitrate and reported finished recordings by webhook.
- A cron cleared sessions whose recording stayed in the processing state.
- Recordings were deleted after a retention period to limit storage cost.
Cloudflare Stream and the relay
- Cloudflare Stream replaced Mux after delivery because it priced delivery and storage lower.
- Cameras pushed RTMP to an nginx on the platform's server. The backend started an ffmpeg relay to Cloudflare only while a session ran, and switched recording on with the relay and off after it.
- No webhook event covered this flow, so finished recordings were found by polling.
- Recordings moved to R2 storage after four days.
Faults at the relay
- A camera that dropped for a second could not reconnect: the dead connection held its stream key for about two hours. A 30-second idle timeout in nginx fixed that in November.
- The same dropout killed the relay, and a relay started for a camera that was not publishing exited with no error. Reconnect flags and an ffprobe check before launch fixed both the following March.
Left open
The relay's state was a map in one process's memory. The backend ran as one process.
Up next
Liquidation that ran only when the client polled→