/hls/f3a9c2e17b4d80a65e2f1c8d3b7a4e08/index.m3u8/live/{username}/index.m3u8 Streamer (OBS)
│ RTMP: rtmp://localhost:1935/live + stream key
▼
Ingest server
│ Converts RTMP stream to HLS: A playlist + segments
▼
Web server (Your app)
│ HTTP: Normal GET requests for the playlist and segments
▼
Viewers (hls.js)tiangolo/nginx-rtmp imagepostgres image instead of writing a databasenginx.conf file/etc/nginx/nginx.conflivertmp://localhost:1935/liveapp is the name of your app's service in your compose file
/hls
hls_nested: Each stream gets its own directory named after its stream key
/hls/{stream_key}/index.m3u8/hls/{stream_key}/0.ts, 1.ts, ...name is the stream key the streamer enteredon_publish_done sends the same format when the stream ends
POST /api/live/start HTTP/1.1
Host: app:8080
Content-Type: application/x-www-form-urlencoded
app=live&...&call=publish&name=f3a9c2e17b4d80a65e2f1c9d3b7a4e08&type=live200 OK to allow the stream403 Forbidden to reject it. The ingest server disconnects the streamerapp: Your Go serverdb: Your databaseingest: nginx-rtmp. Write a Dockerfile in ./ingestdocker compose up must start all threeon_publish and on_publish_done when it starts
depends_on to ensure your app starts first#EXT-X-ENDLIST until the stream is overCache-Control: no-store/hls in the ingest container
docker compose up --build --force-recreate./streams and the container directory hls
./streams to a directory in your app container lets your app access the streams--renew-anon-volumes deletes anonymous volumes when testing and grading
./uploads at /app/public and your front end disappears