Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| cdn [2021/11/18 22:52] – ischluff | cdn [2025/11/03 12:23] (current) – ischluff | ||
|---|---|---|---|
| Line 2: | Line 2: | ||
| < | < | ||
| + | This documentation describes our Livestreaming CDN as of 2025. | ||
| - | Diese Doku beschreibt unser Live-Streaming | + | The File-CDN for media.ccc.de is described on [[software: |
| - | + | ||
| - | Das File-CDN wird dagegen auf der Seite [[software: | + | |
| </ | </ | ||
| - | == Architektur | ||
| - | Die CDN-Kaskade hat 5 Stufen: Master-Encoder, | ||
| - | {{:cdn_overview.png?1200|}} | + | ==== Repo Links |
| + | * Stream-api, Upload-Proxy, | ||
| + | * rtmp-auth daemon: https:// | ||
| + | * Transcoding-Script: | ||
| - | === 1. Master-Encoder | + | == Architecture |
| - | Das Master-Encoding entsteht auf dem encoder-cube im Saal aus dem Ausgabesignal des Voctomix. Das Master-Encoding enthält den Mix als 1080p25 in h264 sowie die Slides als 1080p5 in h264 mit bis zu drei Audiospuren in AAC (Native, Translated, Translated-2). Wahlweise können die Übersetzerspuren sowie die Slide-Spur weggelassen werden. Alle Spuren werden in einem Matroska-Container verpackt. | + | The CDN-Cascade has 6 stages: |
| + | {{: | ||
| - | Das Master-Encoding wird von einem Script erzeugt, welches vom ansible aus folgendem Template erzeugt wird: https:// | + | === 1. Encoder |
| + | The initial stream encoding is created near the stage on the encoder | ||
| + | The encoding usually contains a 1080p25 H264 video signal, the slides as 1080p5 and up to 3 tracks of audio encoded in AAC (Native, Translated, Translated-2). | ||
| + | The translated audio tracks and the slide video track are optional. | ||
| - | Das Master-Encoding wird auf den lokalen (= auf dem encoder-cube laufenden) Icedist (= Icecast zur internen Distribution) auf Port 7999 gepusht (http:// | + | The origin encoding is pushed as MPEG-TS via SRT to the ingest stage. |
| + | === 2. Ingest | ||
| + | The ingest machines run both [[https:// | ||
| - | ==== Debugging | + | Additionally the ingest machines run a stream-api daemon which scrapes the local stream information from both srtrelay and nginx-rtmp and publishes it to consul KV. |
| - | + | The consul KV path is /stream/<stream slug> | |
| - | http://195.54.164.164: | + | |
| ``` | ``` | ||
| - | voc@live.ber: | + | # consul kv get /stream/s96 |
| - | ● icedist.service - distribution Icecast | + | {" |
| - | | + | |
| - | | + | |
| - | Main PID: 794 (icecast2) | + | |
| - | Tasks: 25 (limit: 4915) | + | |
| - | | + | |
| - | | + | |
| - | + | ||
| - | sudo tail -f / | + | |
| ``` | ``` | ||
| - | === 1.5 Exkurs Stream-API | + | === 3. Transcoder |
| - | Die " | + | The stream transcoding transforms the mpegts stream into multiple segmented streams (one per quality) via one big ffmpeg script. Additionally it creates thumbnails and preview images. |
| - | Aktuelles Beispiel siehe https://live.ber.c3voc.de/stream_info.json (Zugang im Keepass unter stream-api). | + | The transcoding script can be found here https://github.com/voc/ |
| - | Das JSON wird periodisch auf dem Master Relay von einem Skript durch die Abfrage von Icedist/ | + | A python script runs constantly on each transcoder which fetches streams from consul and tries to claim streams which don't have a transcoder assigned yet. |
| + | The consul KV path is /stream/< | ||
| + | ``` | ||
| + | # consul kv get / | ||
| + | myloc-transcoder3 | ||
| - | === 2. Transcoder | + | # To reallocate a transcoder for a stuck stream |
| - | Das Transcoding läuft auf verschiedenen Transcodern. Aktuelle Zuordnung siehe '' | + | consul kv delete |
| + | ``` | ||
| - | Jeder Transcoder pollt regelmäßig die Stream-Api und startet/ | + | Every time a transcoder claims a stream it writes an env file and starts a systemd unit to run the transcoding script. |
| - | Abhängig von der Hardware starten diese entweder einzelne " | + | The transcode updates are also published to the #voc-wok IRC. |
| - | Die Pull/Push-Konfiguration jedes Streams wird aus der Stream-API entnommen und in ein File entsprechend "/opt/transcoder/config/sloop" | + | The transcoding outputs are directly pushed with HTTP uploads to the Origin relays. To ensure proper retries the uploads are sent over a local http-proxy (https:// |
| - | Die Quelle eines transkodierten Streams ist immer eine Icecast-URL der Form http://host:port/sX und das Ziel ist immer eine Icecast-URL der Form http://host2:port2/sX_format. | + | === 4. Origin Relays |
| - | (Beispiel: http:// | + | Origin relays run the upload server (https://github.com/voc/stream-api/tree/master/cmd/upload-server) which receives the http uploads and stores the files on local disk. |
| + | The upload server has some additional logic to rewrite the HLS playlists on the fly in order to properly handle stream restarts. | ||
| - | Die transkodierten Formate sind dabei: h264, vpx (VP9), audio (MP3, Opus) und thumbnail (MJPEG mit 0.1Hz). | + | The segmented streams, thumbnails etc. are currently served by nginx. |
| - | Dementsprechend z.B.: | + | |
| - | * http:// | + | |
| - | * http:// | + | |
| - | * http:// | + | |
| - | * http:// | + | |
| + | === 5. Edge-Relays | ||
| + | The edge relays run nginx with caching proxy config and upstream set to the active origin relay. | ||
| - | Die Scripte dazu werden vom ansible aus folgenden Templates erzeugt: https:// | + | === 6. Loadbalancer |
| + | The end-user facing domains '' | ||
| - | Da jeder Format-Stream aus einem einzelnen ffmpeg-Prozess stammt und in einem Container landet sind die darin enthaltenen Videoströme Zeitsynchron zueinander. | + | ==== streaming.media.ccc.de |
| + | The load-balancers serve the [[: | ||
| + | ==== cdn.c3voc.de | ||
| + | Requests to '' | ||
| - | ==== Verwaltung | + | The relay weight distribution is stored in consul KV and can be tweaked in real time. The haproxy configs automatically get updated by consul-template after a change. |
| - | Die Verteilung der Transcodings wird wie oben erwähnt über die Stream-API realisiert. Dadurch werden die Streams immer gleichmäßig verteilt und es gibt keine doppelten Zuweisungen. | + | |
| - | Die Maximalzahl der Streams pro Transcoder und eventuelle Stream-Bindungen an bestimmte Transcoder können über Variablen im ansible gesteuert werden. | + | ``` |
| + | # Get the current weight distribution, | ||
| + | consul kv get -recurse / | ||
| + | services/ | ||
| + | services/ | ||
| + | ``` | ||
| - | Um einen Überblick über die derzeit aktivierten Transcodings zu erhalten kann folgender Befehl verwendet werden: | + | Because |
| - | + | ||
| - | < | + | |
| - | voc@tweety.int: | + | |
| - | UNIT LOAD | + | |
| - | transcode_s1_audio.service | + | |
| - | transcode_s1_h264.service | + | |
| - | transcode_s1_vpx.service | + | |
| - | transcode_s2_audio.service | + | |
| - | … | + | |
| - | transcode_s1.target | + | |
| - | transcode_s2.target | + | |
| - | … | + | |
| - | </ | + | |
| - | + | ||
| - | Der Zustand des API-Clients ist gelegentlich sinnvoll abzufragen | + | |
| - | < | + | |
| - | sudo journalctl -afu update_transcoding | + | |
| - | </ | + | |
| - | + | ||
| - | === 3. Fanout | + | |
| - | Die Format-Streams je Raum werden von der nächsten Stufe auf dem Master-Relay ('' | + | |
| - | + | ||
| - | Dabei entstehen alle Kombinationen aus '' | + | |
| - | + | ||
| - | Die WebM- und die Audio-Streams werden gegen den Icecast auf http:// | + | |
| - | Segmente im File-System: | + | |
| - | * / | + | |
| - | * / | + | |
| - | * / | + | |
| - | * / | + | |
| - | + | ||
| - | Die Scripte dazu werden vom ansible aus folgenden Templates erzeugt werden: https:// | + | |
| - | + | ||
| - | + | ||
| - | Um einen Überblick über die laufenden Fanout Skripte zu erhalten kann folgender Befehl verwendet werden: | + | |
| - | + | ||
| - | < | + | |
| - | voc@live.ber: | + | |
| - | </ | + | |
| - | + | ||
| - | Die Pull-Quelle und das Push-Ziel sowie der Pfad unter dem die HLS/DASH-Schnipsel und Playlisten abgelegt werden ist über Group-Vars konfigurierbar: | + | |
| - | + | ||
| - | < | + | |
| - | + | ||
| - | * Youtube ist derzeit deaktiviert und wird üblicherweise nur für den Congress aktiviert. | + | |
| - | + | ||
| - | Das Transcoding und Fanout reagiert dynamisch auf die Konfiguration des Streams der vom encoder-cube gesendet wird. Fehlt die Slides-Spur oder die Translation-Spuren wird diese nicht in den Master-Playlists und Dash-Manifestd für Adaptives streaming angeboten. Dadurch kann von Event zu Event entschieden werden, ob der Einsatz der Slide-Spur bzw. von Translations sinn ergibt. Siehe dazu [[voctomix: | + | |
| - | + | ||
| - | === 4. Transport- und Master-Relays | + | |
| - | Im Non-Congress Setup ist '' | + | |
| - | + | ||
| - | === 5. Edge-Relays | + | |
| - | Die ganzjährigen Edge-Relay lauten: | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | + | ||
| - | Diese pullen alle Icecast-Streams (Port :8000) – *nicht* die Icedist-Streams – von '' | + | |
| - | Für die schlussendliche Auslieferung kommt ein nginx zum Einsatz, der abhängig von der URL Daten von einem der unterschiedlichen Backend proxied: | + | |
| - | * Für Anfragen zu einem WebM, MP3 oder Opus-Stream (z.B: http:// | + | |
| - | * Für Anfragen nach HLS oder DASH-Schnipseln, | + | |
| == Stream-URLs | == Stream-URLs | ||
| - | Die endgültigen Stream-URLs für einen Beispielstream sX sind dann wie folgt: | + | The resulting stream |
| - | + | ||
| - | MPEG-DASH | + | |
| - | * http:// | + | |
| - | HLS (h.264 Multi-Qualität | + | HLS (H.264 multi-quality |
| - | * http:// | + | * http:// |
| Moar HLS | Moar HLS | ||
| - | * http:// | + | |
| - | * http:// | + | * http:// |
| - | * http:// | + | * http:// |
| - | * http:// | + | * http:// |
| - | * http:// | + | * http:// |
| - | Legacy VPx-HD: | + | **Currently not active:** |
| - | * http:// | + | |
| - | * http:// | + | |
| - | * http:// | + | |
| - | Legacy | + | MPEG-DASH (VPx multi-quality + multi-language) |
| - | * http:// | + | * http:// |
| - | * http:// | + | |
| - | * http:// | + | |
| - | + | ||
| - | Legacy VPx-Slides: | + | |
| - | * http:// | + | |
| - | * http://cdn.c3voc.de/ | + | |
| - | * http:// | + | |
| Audio-MP3: | Audio-MP3: | ||
| - | * http:// | + | * http:// |
| - | * http:// | + | * http:// |
| - | * http:// | + | * http:// |
| Audio-Opus: | Audio-Opus: | ||
| - | * http:// | + | * http:// |
| - | * http:// | + | * http:// |
| - | * http:// | + | * http:// |
| + | == Dynamic SRT/RTMP endpoints with RTMP Auth | ||
| + | SRT and RTMP Endpoints can be created under https:// | ||
| - | == Loadbalancer | + | The RTMP-URL for the endpoint '' |
| - | Neben den Transport- und Edge-Relays gibt es noch drei Loadbalancer: | + | |
| - | * '' | + | The SRT-URL would be : '' |
| - | * '' | + | |
| - | * '' | + | |
| - | Diese sind sowohl für die Domains '' | + | == Future improvements |
| - | === streaming.media.ccc.de | + | The diagram below shows the envisioned architecture as of 2020. In the meantime many of the improvements have been integrated into the CDN. |
| - | Unter dieser Domain liefern beide LBs unabhängig von einander die [[:software: | + | Some more potential improvements are as follows: |
| + | * Dynamically adapting the streaming-website to the existence/ | ||
| + | * Building a live status dashboard which shows the current stream-> | ||
| + | * To gracefully shutdown a relay it could be instructed via consul KV to redirect all clients back to a load balancer while taking it out of the haproxy redirects. That way all clients would be redistributed to different relays. | ||
| + | * Build origin relay redundancy using dynamic upload client and relay upstream configuration. (Relay upstreams need to be sticky, because the HLS playlists generated on the origin relay are not deterministic) | ||
| + | * Use DNS rotation on ingest | ||
| + | * Finalize srtrelay meshing to allow pushed streams to be pulled from any ingest machine. | ||
| - | === cdn.c3voc.de | ||
| - | Die Domain '' | ||
| - | |||
| - | Der HAProxy verteilt dabei ausschließlich per Redirect, er proxied (entgegen seines Namens) nicht. | ||
| - | |||
| - | == RTMP Ingest | ||
| - | Für Spezialanwendungen (z.B. Cam-Only Streaming im Fritz-Studio) existieren die RTMP-Endpunkte '' | ||
| - | Die Push-Targets lauten '' | ||
| - | |||
| - | Achtung: Aufgrund der langen rtmp-Timeouts in ffmpeg kann es bis zu 40 Sekunden dauern, bis die Streams auftauchen und weitere 30 Sekunden, bis alle Formate zur Verfügung stehen. Keine Ungeduld. | ||
| - | |||
| - | === Dynamische endpunkte mit rtmp-auth | ||
| - | RTMP Endpunkte können unter https:// | ||
| - | |||
| - | Die RTMP-Url für den endpunkt '' | ||
| - | |||
| - | |||
| - | == The Future of Streaming? | ||
| - | Um die Redundanz zu erhöhen und das Management zu vereinfachen ist geplant die Streams auf dem CDN zukünftig über ein verteiltes System zu managen welches auf consul aufbaut. | ||
| - | |||
| - | Damit wäre es möglich redundante CDN-Master sowie redundante Ingest-Server zu betreiben und trotzdem ein Web-Backend mit allen relevanten Streaming-Infos bereitzustellen. Weiterhin könnte die Streaming-Webseite intelligent auf das Vorhandensein/ | ||
| - | |||
| - | Ein weiterer Vorteil des angedachten Setups sind deutlich geringere Latenz durch den fehlenden Fanout, sowie deutlich schnellere Stream-Restarts durch aktive Benachrichtigung der Transcoder. | ||
| - | |||
| - | === Übersicht | ||
| {{drawio> | {{drawio> | ||
| - | ==== Repo Links | ||
| - | * Stream-api, Upload-Daemon: | ||
| - | * rtmp-auth daemon: https:// | ||
| - | * Transcoding-Script: | ||
| - | |||
| - | === Änderungen zum Jetzt-Stand | ||
| - | ==== 1. Kein Fanout auf dem Master-Relay mehr | ||
| - | Transcoder pushen direkt die fertig gemuxten Client-Streams auf 1-N Master-Relays. Damit brauchen die Transcoder potentiell etwas mehr Bandbreite, dafür wird der Prozess vereinfacht weil der Master Format-unabhängig verteilen kann. | ||
| - | |||
| - | Weiterhin kann damit die Latenz um mindestens ein Keyframe-Intervall (3s), vermutlich sogar mehr gesenkt werden. | ||
| - | |||
| - | ==== 2. Keine WebM-Icecast Streams mehr | ||
| - | Um die Zahl der gepushten Streams zu reduzieren (siehe 1) werden die alten Icecast-Streams abgeschaltet. Seit 2 Jahren sind diese nicht mehr default in der Streaming-Webseite. Als Vorbereitung hierzu wurde Frühling 2020 der Legacy-Tab entfernt. | ||
| - | |||
| - | Audio-Only Streams über Icecast bleiben aber vermutlich erhalten genauso wie das interne Relaying über Icecast. | ||