Own your media: per-app S3 and recordings
Every app records to its own S3 bucket with its own credentials. How the recording-to-VOD pipeline works and why the storage boundary is per app.
Your recordings, your bucket
When StreamHub records a room, the finished MP4 does not sit on the server — it is uploaded to the app's own S3 bucket, using the app's own credentials. Each app points at whatever object storage you like: AWS S3, MinIO, Backblaze B2, Cloudflare R2, any S3-compatible endpoint. The media lives where you decide, not where a vendor decides.
The recording → S3 → VOD pipeline
The critical path is worth understanding because it is the same for a one-off recording or an always-on camera:
- Start —
recording/starttells LiveKit egress to writeapps/<app>/recordings/<slug>.mp4. A VOD row is inserted withstatus=recording. - Upload — when egress finishes, a background job uploads the local file to the app's S3, builds a public or presigned URL, and (optionally) deletes the local copy.
- Finalize — the job generates a snapshot, saves metadata (duration, resolution, codec), sets
status=ready, and fires thevod_readywebhook.
On upload failure the local file is kept and recording_failed fires — you never silently lose a recording.
Split and snapshot
Two config knobs shape the output:
split_minutescuts long recordings into parts — each part is its own MP4 and its own VOD, indexed independently. Good for 24/7 cameras.snapshot_secondscaptures a periodic JPEG thumbnail during the recording, uploaded tosnapshots/.
Configuring an app's S3
curl -X PUT $BASE/apps/live/s3 -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"provider": "aws",
"bucket": "my-live-recordings",
"region": "us-east-1",
"accessKeyId": "AKIA...",
"secretAccessKey": "..."
}'
Credentials are stored in data/secrets.json and referenced from the app's config — never in the database, never in a log.
Why per-app storage matters
A per-app bucket means clean tenancy: you can hand a customer their own bucket, meet a data-residency requirement by choosing the region, and offboard cleanly by revoking one set of credentials. The recording pipeline is identical whichever provider you point it at — StreamHub only cares that it speaks S3.