cdn

CDN

Note: This documentation describes our Livestreaming CDN as of 2024.

The File-CDN for media.ccc.de is described on Voctoweb.

For redundancy and ease of use the CDN is managed by a distributed system built on consul.

Damit ist 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/Fehlen von Streams im CDN reagieren und zusätzliche Metadaten von Encodern verarbeiten.

Ein weiterer Vorteil des angedachten Setups sind deutlich geringere Latenz durch den fehlenden Fanout, sowie deutlich schnellere Stream-Restarts durch aktive Benachrichtigung der Transcoder.

diagram1.png

The CDN-Cascade has 5 stages: Master-Encoder, Ingest, Transcoder, Master-Relays and finally Edge-Relays.

The master stream encoding is created near the stage on the encoder PC running voctomix or on with other videoencoder for third party streams. The master encoding contains a 1080p25 video signal. 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.

Das Master-Encoding wird von einem Script erzeugt, welches vom ansible aus folgendem Template erzeugt wird: https://github.com/voc/cm/blob/master/ansible/roles/encoder/templates/voctomix-scripts/streaming-sink-mkvonly.sh.j2

Das Master-Encoding wird auf den lokalen (= auf dem encoder-cube laufenden) Icedist (= Icecast zur internen Distribution) auf Port 7999 gepusht (http://encoderX.lan.c3voc.de:7999/sX). Der Icedist auf dem Master-Relay (z.B. live.ber.c3voc.de) pullt diesen und bietet ihn seinerseits auf http://live.ber.c3voc.de:7999/sX an.

Debugging

http://195.54.164.164:7999 (oder http://live.ber.c3voc.de:7999 im Inkognito-Modus damit einen der Browser nicht zu HTTPS zwingen will)

voc@live.ber:/etc/icecast2$ systemctl status icedist                                           2019-08-20 21:52:20
● icedist.service - distribution Icecast
   Loaded: loaded (/etc/systemd/system/icedist.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2019-07-30 19:50:07 CEST; 3 weeks 0 days ago
 Main PID: 794 (icecast2)
    Tasks: 25 (limit: 4915)
   CGroup: /system.slice/icedist.service
           └─794 /usr/bin/icecast2 -c /etc/icecast2/icedist.xml

sudo tail -f /var/log/icedist/error.log

Die “Stream-API” ist aktuell ein statisches JSON-File mit Pfaden und Transcoder-Zuordnungen für aktuelle Streams. Aktuelles Beispiel siehe https://live.ber.c3voc.de/stream_info.json (Zugang im Keepass unter stream-api).

Das JSON wird periodisch auf dem Master Relay von einem Skript durch die Abfrage von Icedist/Icecast-Instanzen (lokal, ingest, etc.) erstellt. Damit enthält es alle Streams die aktuell oder kürzlich (bis zum timeout) auf dem icedist/icecast ankamen. Weiterhin wird anhand einer Config automatisiert ein (nicht-voller) Transcoder zum Stream zugeordnet. Jeder Transcoder hat in der Config eine “Kapazität” d.h. eine Maximalzahl von möglichen Streams anhand derer die Verteilung gewählt wird.

Das Transcoding läuft auf verschiedenen Transcodern. Aktuelle Zuordnung siehe event-Inventory im ansible https://github.com/voc/cm/blob/master/ansible/event#L49 “alb”.

Jeder Transcoder pollt regelmäßig die Stream-Api und startet/stoppt entsprechende Systemd-Units der Form “transcode@sX.target”. Abhängig von der Hardware starten diese entweder einzelne “transcodeh264@sX.service”, “transcodevpx@sX.service”, etc. Units oder einen einzelnen “transcode_vaapi@sX.service”.

Die Pull/Push-Konfiguration jedes Streams wird aus der Stream-API entnommen und in ein File entsprechend “/opt/transcoder/config/sloop”. Die Transcoding-Services verwenden dann diese Datei als EnvironmentFile.

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. (Beispiel: http://live.ber.c3voc.de:7999/s1http://live.ber.c3voc.de:7999/s1_h264)

Die transkodierten Formate sind dabei: h264, vpx (VP9), audio (MP3, Opus) und thumbnail (MJPEG mit 0.1Hz). Dementsprechend z.B.:

Die Scripte dazu werden vom ansible aus folgenden Templates erzeugt: https://github.com/voc/cm/tree/master/ansible/roles/transcoder/templates/transcoder

Da jeder Format-Stream aus einem einzelnen ffmpeg-Prozess stammt und in einem Container landet sind die darin enthaltenen Videoströme Zeitsynchron zueinander.

Verwaltung

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.

Um einen Überblick über die derzeit aktivierten Transcodings zu erhalten kann folgender Befehl verwendet werden:

voc@tweety.int:~$ systemctl list-units 'trans*'                                                                                                                                                 2018-01-23 0:22:42
UNIT                        LOAD   ACTIVE     SUB          DESCRIPTION                  
transcode_s1_audio.service  loaded active     running      Transcoder audio Stream s1   
transcode_s1_h264.service   loaded active     running      Transcoder h264 Stream s1    
transcode_s1_vpx.service    loaded active     running      Transcoder vpx Stream s1     
transcode_s2_audio.service  loaded active     running      Transcoder audio Stream s2   
…
transcode_s1.target         loaded active     active       All Transcoders of Stream s1 
transcode_s2.target         loaded active     active       All Transcoders of Stream s2 
…

Der Zustand des API-Clients ist gelegentlich sinnvoll abzufragen

sudo journalctl -afu update_transcoding

Die Format-Streams je Raum werden von der nächsten Stufe auf dem Master-Relay (live.ber.c3voc.de) in die finalen Streams in allen für Endnutzer angebotenen Kombinationen auseinander gemuxt (=“fanout”).

Dabei entstehen alle Kombinationen aus sX[hd|sd|slides][native|translated|translated-2] in webm, hls und dash sowie sX_[native|translated|translated-2].[mp3|opus] und die Thumbnails.

Die WebM- und die Audio-Streams werden gegen den Icecast auf http://live.ber.c3voc.de:8000/ gepusht, die HLS- und DASH-Streams werden vom nginx unter http://live.ber.c3voc.de/hls/ bzw. http://live.ber.c3voc.de/dash/ angeboten. Segmente im File-System:

  • /srv/nginx/dash/sX/[manifest.mpd|init\d.webm|segment\d\d+.webm] * /srv/nginx/hls/[sXnative[hd|sd|slides].m3u8] * /srv/nginx/hls/sX/[chunks\d.m3u8|\d+-\d+_\d.ts]
  • /srv/nginx/thumbnail/sX/[poster.jpeg|thumb.jpeg]

Die Scripte dazu werden vom ansible aus folgenden Templates erzeugt werden: https://github.com/voc/cm/tree/master/ansible/roles/relay/files/fanout.

Um einen Überblick über die laufenden Fanout Skripte zu erhalten kann folgender Befehl verwendet werden:

voc@live.ber:~$ systemctl list-units 'fanout*'  

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: https://github.com/voc/cm/blob/master/ansible/group_vars/relays#L5

Zu den Aufgaben der fanout-Scripte gehört auch das übermitteln des h264-Videostroms zu Youtube. Die Stream-Keys dazu kommen aus dem KeePass, die Scripte aus dem oben verlinkten Git-Repo.

  • 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 Audiomapping in Voctomix zu Details wie Translations de/aktiviert werden können.

Im Non-Congress Setup ist live.ber.c3voc.de das einzige (Non-Public) Transport-Relay. Die (Public) Edge-Relays ziehen ihre Daten von dort.

Die ganzjährigen Edge-Relay lauten:

  • live.bn.c3voc.de
  • live.alb.c3voc.de
  • live2.alb.c3voc.de
  • live.dus.c3voc.de
  • live.self.c3voc.de
  • live.fem.c3voc.de

Diese pullen alle Icecast-Streams (Port :8000) – nicht die Icedist-Streams – von live.ber.c3voc.de. 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://live.x.c3voc.de/sX_native_hd.webm) agiert der nginx als Proxy zu seinem eigenen Icecast. Er übernimmt in dieser Rolle das Aggregieren auf die Ports 80/443 sowie das SSL-Handling (für 443).
  • Für Anfragen nach HLS oder DASH-Schnipseln, -Playlisten und -Manifests oder Thumbnails (z.B. http://live.x.c3voc.de/hls/sX_native_hd.m3u8) agiert der nginx als Proxy zum Master-Relay live.ber.c3voc.de, von welcher er die angefragten Datein abholt und für einen genau festgelegten Zeitraum zwischenspeichert. Dieser Zeitraum muss dabei mit der Segmentlänge der Playlists abgestimmt sein, um eine fehlerfreie Wiedergabe zu ermöglichen.

Neben den Transport- und Edge-Relays gibt es noch drei Loadbalancer:

  • lb.dus.c3voc.de
  • lb.alb.c3voc.de
  • lb.dort.c3voc.de

Diese sind sowohl für die Domains streaming.media.ccc.de als auch für cdn.c3voc.de zuständig. Im DNS sind für beide Domains alle Server angegeben, so dass Clients per statistischem Round-Robin auf die Loadbalancer verteilt werden.

Unter dieser Domain liefern beide LBs unabhängig von einander die Streaming-Webseite aus. Die LBs sind dabei komplett unabhängig voneinander und haben auch je eine eigene Konfiguration. Es ist aufgabe des Website-Deployments die Konfiguration synchron zu halten. Durch dieses Setup kann bei Bedarf der jeweilige LB einfach aus der DNS-Rotation herausgenommen werden.

Die Domain cdn.c3voc.de wird auf beiden LBs von einem HAProxy bedient. Dieser sortiert eventuell zwischen DTAG und Lokalen Klienten und wählt auf dieser Basis einen des obenstehenden Relays aus. Im unterjährigen Betrieb gibt es keine Unterscheidung: Alle Anfragen werden unter den genannten Relays verteilt.

Der HAProxy verteilt dabei ausschließlich per Redirect, er proxied (entgegen seines Namens) nicht.

Für Spezialanwendungen (z.B. Cam-Only Streaming im Fritz-Studio) existieren die RTMP-Endpunkte q1 und q2 auf ingest.c3voc.de. Die Push-Targets lauten rtmp://ingest.c3voc.de/stream/q1 bzw. q2. Eine Systemd-Unit setzt diese dann auf Icecast-Ströme gleichen Namens um, von wo Transcoding und Fanout wie oben beschrieben automatisch ihren Weg nehmen.

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.

RTMP Endpunkte können unter https://ingest.c3voc.de/backend/ (passwort im keepass unter ansible/stream-api/htpasswd) erstellt werden. Nach dem Anlegen kann der Stream auf ingest gepusht werden.

Die RTMP-Url für den endpunkt stream/qtest23 mit auth token lautet z.B.: rtmp://ingest.c3voc.de/stream/qtest23?auth=token

  • cdn.txt
  • Last modified: 2024/01/29 10:45
  • by ischluff