Benutzerdokumentation

Planung und Datenübertragungsprotokolle

Die Software Perfect Streamer dient der Übertragung von MPEG-TS-Streams über das öffentliche Internet mit Paketverlusten und Latenzen auf UDP-Basis.

Für jeden MPEG-TS-Stream (Stream) werden ein Sender (Sender) und ein oder mehrere Empfänger (Receiver) konfiguriert; das Paar wird als Peer bezeichnet.

Die Konfiguration von Sender und Empfänger reduziert sich auf das Einrichten einer Stream-Liste und der Einstellungen für input und output jedes Streams. Mehrere input in der Liste sorgen für Quellen-Redundanz. Mehrere output in der Liste ermöglichen die gleichzeitige Übertragung von Streams an verschiedene Empfänger.

Beim Sender ist input die Quelle der MPEG-TS-Streams, output die Übertragung an die Empfänger. Beim Empfänger ist input der Empfang der Streams vom Sender. Vier Peer-Protokolle stehen für die Übertragung zwischen Sender und Empfänger zur Verfügung:

  • Perfect-Stream-Protokoll (PS1).

  • SRT.

  • Pro-MPEG / RTP+FEC.

  • RIST.

PS1-Protokoll

Das PS1-Protokoll basiert auf Automatic Repeat reQuest (ARQ). Es ist ressourcenschonend und erlaubt die Übertragung von Streams mit hoher Bitrate.

Am Sender — wird im output konfiguriert. Pro Stream ist nur eine Instanz verfügbar. In Peer müssen die Logins der Empfänger eingetragen werden. Es wird die UDP listen port festgelegt — sie muss für jeden Stream eindeutig sein.

Am Empfänger — wird im Input konfiguriert. Host und Port des Senders sowie Login und Passwort werden angegeben.

Stream-Verschlüsselung (Crypto protection) ist verfügbar, AES-128 wird verwendet. Zum Aktivieren auf beiden Seiten Crypt Passphrase als gemeinsamen Schlüssel eintragen.

Während des Betriebs sendet der Empfänger (Client) seine Statistiken an den Sender (Server). Diese sind im Bereich Peers nach Auswahl des Clients sichtbar.

Stream-Latenz und Verlustkompensation hängen von den Empfängereinstellungen ab:

Round Trip Time — RTT in ms, Standard 300. Geschätzte Kanal-Latenz (Ping). Nach Stream-Start ist der reale RTT in der Statistik (PS1 recovery delay) sichtbar.

Client Latency (RTT multiplexor) — RTT-Multiplikator (Standard 10), der die Stream-Latenz im Sender-Puffer bestimmt. Bei Standard ergibt sich also eine Pufferverzögerung von 3000 ms.

Senderseitig gibt es die Latenz-Einstellung (Pufferlänge) Latency (ms). Sie muss größer als die clientseitigen Latenzen sein.

Die Fähigkeit des Protokolls, Verluste zu kompensieren, hängt von der Anzahl der Retransmissions-Anfragen ab und ist von Client Latency (RTT multiplexor) bestimmt. Große Verluste führen zu zusätzlichem Netzwerkverkehr. Zur Verringerung der Latenz sollten diese Parameter feiner eingestellt werden.

Korrekte Protokollarbeit zeigt sich in der Client-Statistik. Bei PS1 recovery: Not found → Sender-Buffer vergrößern; Dublicates → RTT erhöhen.

Since the connection is initiated from the side of the receiver, the transmitter requires authentication, the receivers are registered in the peers section. Login and password required.

SRT-Protokoll

Offenes Protokoll von Haivision. Basiert auf UDT, ist weit verbreitet und bietet gute Eigenschaften zur Kompensation von Paketverlusten.

Anwendungsfälle:

  • Peer between two Perfect Streamer instances. On transmitter - endpoint is configured as output, listen mode (default). For one stream only one such output can be configured. Multiple receivers can be connected in this mode. For authorization, it is required to register receivers logins in Peer. On receiver - endpoint is configured as input. The host and port of the transmitter, have to be set up as well as login and password. Streamer uses stream ID in format „login|password“ to transmit login and password in SRT.

  • Peer between Perfect Streamer and third-part SRT streamer. On transmitter you can set up srt client mode, switching off listen. SRT stream ID is entered in login field, if needed. For listen mode, the IP-address authorization is available - entered in login field in Peer. On receiver it is available to turn on listen mode, enter the SRT stream ID in the login field, also you can specify the host from which the connection is allowed.

Betrieb im Listener-Modus: Empfang und Weitergabe eines TV-Streams mit Angabe des Empfangsports.

Die Ports im Listen-Modus müssen eindeutig sein.

Stream-Verschlüsselung (Crypto protection) ist verfügbar, AES-128 wird verwendet. Zum Aktivieren auf beiden Seiten Crypt Passphrase als gemeinsamen Schlüssel eintragen.

Verwendet der Sender den listen-Modus (Standard), wird die Verbindung vom Empfänger initiiert; der Sender erfordert Authentifizierung, und die Empfänger werden in peer registriert. Login und Passwort sind erforderlich.

Die SRT-Protokolloptionen entsprechen der Beschreibung unter https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md

Reorder (SRTO_LOSSMAXTTL) - Value up to which the reordering allowance can increase. Reordering allowance is the number of packets that must follow the detected «gap» in the order numbers of incoming packets, to send a report on loss (in the hope that the gap is caused by reordering of packets, not by loss). The reordering allowance starts at 0 and increases when reordering of packets is detected. This happens when a «late» packet with a sequence number older than the last received, but without the retransmission flag is received. At such detection, the reordering allowance is set to the value of the interval between the last number and the sequence number of this packet, but not more than the value set by the SRTO_LOSSMAXTTL parameter. By default, this value is 0, which means that this mechanism is disabled. https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#SRTO_LOSSMAXTTL

Overhead (SRTO_OHEADBW, %) — Overhead zur Bandbreitenwiederherstellung über die Eingangsrate hinaus (siehe SRTO_INPUTBW), in Prozent der Eingangsrate. Wirksam nur, wenn SRTO_MAXBW auf 0 gesetzt ist. Sender: vom Benutzer konfigurierbar; Standard: 25%.

Recommendations: Overhead is intended to provide additional bandwidth capacity in case a packet has taken up some bandwidth but is then lost and needs to be retransmitted. Therefore, the effective maximum bandwidth should be sufficiently higher than the bitrate of your stream to leave room for retransmissions, while being limited so that retransmitted packets do not lead to a sharp increase in bandwidth usage when large groups of packets are lost. Do not set too low a value and avoid 0 if the SRTO_INPUTBW parameter is set to 0 (automatic). Otherwise, your stream will quickly interrupt with any increase in packet loss. https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#SRTO_OHEADBW

Max Band (SRTO_MAXBW, bps) — Diese Option ist nur wirksam, wenn SRTO_MAXBW gleich 0 ist (relativ). Sie steuert die maximale Bandbreite zusammen mit SRTO_OHEADBW nach der Formel: MAXBW = INPUTBW * (100 + OHEADBW) / 100. Ist diese Option auf 0 gesetzt (automatisch), wird der tatsächliche INPUTBW-Wert anhand der Rate des Eingangsstreams (in Fällen, in denen die Anwendung srt_send* aufruft) während der Übertragung geschätzt. Der Mindestwert der Schätzung ist durch SRTO_MININPUTBW begrenzt, d. h. INPUTBW = MAX(INPUTBW_ESTIMATE; MININPUTBW).

Empfehlungen: setzen Sie für diesen Parameter den erwarteten Bitrate Ihrer Übertragung und behalten Sie den Standardwert 25% für SRTO_OHEADBW bei. https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#srto_inputbw

Timeout (SRTO_CONNTIMEO, ms) - Value of the connection timeout in milliseconds. This is the time during which the connecting object will try to connect and wait for a response from the remote endpoint, before terminating the connection with an error code. https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#SRTO_CONNTIMEO

Pro-MPEG / RTP+FEC Protokoll (COP3 / SMPTE 2022-1/2)

Lieferung von MPEG-TS über RTP mit vorwärts gerichteter Fehlerkorrektur (FEC, Forward Error Correction). Dasselbe Protokoll erscheint in Literatur und Geräten unter unterschiedlichen Namen:

  • Pro-MPEG / Pro-MPEG COP3 — Code of Practice #3 des Pro-MPEG-Forums, beschrieben im IEEE-Standard (https://ieeexplore.ieee.org/document/6738329);

  • RTP + FEC — funktionaler Name (RTP-Stream plus FEC-Kanäle);

  • SMPTE 2022-1 — Column FEC (dasselbe Schema, als SMPTE-Standard veröffentlicht);

  • SMPTE 2022-2 — Row + Column FEC (zweidimensionale Matrix, in PSS implementiert).

Достоинства — низкая задержка. Его недостаток — высокий дополнительный трафик (overhead), и он плохо работает при больших потерях пакетов (более 0.2%).

Этот протокол основан на RTP с добавлением 2-х каналов для FEC (кода коррекции ошибок). Два канала FEC используют порты port+2 и port+4, что надо учитывать при добавлении нескольких потоков на один хост или мультикаст группу.

Beim Sender werden RTP-Pakete in einer Matrix mit Cols Spalten und Rows Zeilen gruppiert. Beispiel für cols=8 und rows=4 (Standard):

RTP01

RTP02

RTP03

RTP04

RTP05

RTP06

RTP07

RTP08

R1

RTP11

RTP12

RTP13

RTP14

RTP15

RTP16

RTP17

RTP18

R2

RTP21

RTP22

RTP23

RTP24

RTP25

RTP26

RTP27

RTP28

R3

RTP31

RTP32

RTP33

RTP34

RTP35

RTP36

RTP37

RTP38

R4

C1

C2

C3

C4

C5

C6

C7

C8

Die Pakete Rx und Cx bilden FEC-Daten zeilen- und spaltenweise. Je kleiner die Matrix, desto besser die Korrekturfähigkeit, aber desto höher der zusätzliche Verkehr. In diesem Beispiel kommen auf 32 RTP-Pakete des Streams 12 FEC-Pakete.

Доступно шифрование потоков (Crypto protection), используется AES-128, но это не включено в стандарт, поэтому не гарантируется совместимость со сторонним ПО или оборудованием.

Es gibt nicht-standardisierte Protokollerweiterungen:

Multiplexing — мультиплексирование RTP каналов через один UDP порт. Может упростить настройку сети. Header XOR — обфускация RTP заголовка. Усложнит определение типа трафика в сети.

RIST-Protokoll

Neues offenes Protokoll auf Basis von RTP/RTCP. Arbeitet nach Automatic Repeat reQuest (ARQ) ohne ACK, nur NACK — das garantiert hohe Effizienz.

Verwendet Unicast und Multicast.

Es sind die Profile Simple und Main implementiert. Simple nutzt zwei aufeinanderfolgende UDP-Ports — der konfigurierte Port muss gerade sein. Main verwendet einen einzigen RTP-Port mit Datenmultiplexing.

On the transmitter - configured in output. For unicast, the address and port of the receiver are set. For multicast, the network interface through which the data will be transmitted must be set. Also, for multicast, authorization of receivers via IP address can be set if login is written in Peer.

Am Empfänger — in input konfigurieren. Für Unicast werden Empfangsport (listen) und zwingend die Netzwerkschnittstelle festgelegt. Für Multicast wird nur die Multicast-Gruppe samt Port angegeben.

RIST unterstützt mehrere separate Peers (Adressen). Mit einem Gewicht > 1 lässt sich Lastverteilung zwischen den Peers entsprechend dem Gewicht aktivieren.

If the transmitter uses multicast, there may be many receivers. In this case, authentication of receivers by IP address is possible. To do this, enable authentication in the transmitter settings (by default disabled) and add the client to the peer list, in the login field write the IP address.

Andere Protokolle

Neben den peer-Protokollen stehen für Empfang und Senden von Streams weitere zur Verfügung:

Protocol

Input

Output

UDP

Yes

Yes

RTP

Yes

Yes

TCP

Yes

No

HLS

Yes

Yes

UDP (Unicast oder Multicast) — Empfangen und Senden von MPEG-TS im UDP-Paket, bis zu 7 TS-Pakete pro UDP-Paket.

RTP (Unicast oder Multicast) — RFC-basiertes Standardprotokoll. Reordering-Wiederherstellung wird unterstützt.

TCP — Empfang von MPEG-TS über eine TCP-Verbindung im TCP-Client-Modus.

HLS — Empfang und Senden von MPEG-TS over HTTP oder das HLS-Standardprotokoll von Apple. Beim Empfang adaptiver Playlists wird der Stream mit der höchsten Bitrate gewählt.

Streams mit Dateien und Geräten

Für input und output steht das Protokoll file/device für Dateien und Geräte zur Verfügung.

output file/device — Aufzeichnung in eine Datei oder Ausgabe an ein Gerät. Eine Datei-Aufzeichnung kann zur ts-Datei-Aufnahme und nachfolgenden Diagnose mit anderen Analyzern erforderlich sein. Geräte-Ausgabe — beliebiges Gerät (auch SDI), das in /dev registriert ist.

input file/device — Loop-Wiedergabe von Video aus einer TS-Datei.

Bei Arbeit mit Dateien wird der vollständige Dateipfad im Feld File Path angegeben:

/catalog/stream.ts.

Bei Geräten wird zusätzlich das Flag Is Device aktiviert.

Liste erlaubter Streams und Peer-Beschränkung

Zur Einschränkung des Zugriffs auf TV-Streams seitens des Clients (Peer) in den Modi SRT Listen, PS1, HLS und HTTP ist im Programm die Funktionalität einer Liste erlaubter Streams implementiert. In den Peer-Einstellungen am Sender wird die Liste der verfügbaren Sender festgelegt. Dazu im Feld Stream Access aus der allgemeinen Senderliste des Servers nur diejenigen Sender hinzufügen, die diesem Peer ausgegeben werden sollen. Standardmäßig sind bei leerer Liste alle Sender verfügbar.

Für Peer lassen sich Zeit- und Verbindungslimits pro Transportprotokoll setzen.

Anonymous peer

Standardmäßig hat das Peer-Login den Wert anonymous. Ein anonymer Peer erlaubt die Stream-Verteilung ohne Bindung an IP oder Login/Passwort. Es gelten Einschränkungen hinsichtlich der Anzahl ausgegebener Streams je Transportprotokoll, des Ablaufdatums und der Liste erlaubter Streams.

Es ist möglich, einen individuellen Peer per Login (Name) und Passwort anzulegen.

Für die Peer-Autorisierung per IP muss die Option „Login Is IP“ aktiviert werden.

Autorisierungsoptionen:

  • Nach einzelner IP

  • Nach IP-Bereich, z. B. „192.168.1.10-192.168.1.20“

  • Kombinierte Variante, Syntax der IP-Listen: ip[-ip2][,…]

Anbindung von Drittanwendungen

Zur Unterstützung anderer Protokolle, die mit den eingebauten Mitteln nicht abgedeckt sind, lassen sich Streams über externe Konsolenanwendungen empfangen und übertragen. Dafür gibt es ein eigenes std-Protokoll für input und output. Der MPEG-TS-Stream wird über die Standardein-/-ausgabe des Betriebssystems empfangen und übertragen.

In den Einstellungen werden die Konsolenanwendung (absoluter Pfad) und die Kommandozeile angegeben; Umgebungsvariablen sind ebenfalls möglich.

Bei input mit externer Anwendung müssen Meldungen auf stdout vermieden werden — Ausgabe nur auf stderr.

Für den output lässt sich Paketierung von bis zu 7 MPEG-TS-Paketen einstellen.

Anforderungen an den Eingangsstream

Konformität mit ISO 13818-1, Single Program (SPTS) oder Multi Program Transport Stream (MPTS). MPTS-Besonderheiten unten; die folgenden Einstellungen beziehen sich auf SPTS.

Mindestens eine Tonspur ist erforderlich.

Streams ohne Video werden unterstützt, aktiviert über den Radio-Modus.

Verschlüsselte Streams werden unterstützt; dafür muss Scrambled Stream aktiviert werden.

Für die Synchronisation muss der Stream gültige PCR-Marken enthalten.

Stream-Einstellungen

Einen eindeutigen Stream-Namen vergeben (lateinische Buchstaben, Ziffern, „_“, „-“). Zusätzlich kann ein Anzeigename gesetzt werden, der Kyrillisch und andere Sprachen unterstützt.

Stream Timeout — globales Stream-Timeout. Liefert kein gültiger Input innerhalb dieser Zeit, erfolgt ein vollständiger Neustart.

Pause — versetzt stream sowie alle input und output in den inaktiven Zustand. Neu hinzugefügte streams sowie inputs/outputs sind standardmäßig pausiert und inaktiv.

Das Programm prüft den Eingangsstream am input auf Gültigkeit. Schlägt die Prüfung fehl, gilt der input als fehlerhaft.

Check Interval — Intervall für erneute Stream-Prüfung.

MPEG-TS-Filtereinstellungen:

Remove All Unnecessary Data — entfernt alle nicht notwendigen Daten außer PAT/PMT, Video und Audio, mit Ausnahme der in den separaten Filtern festgelegten Elemente (siehe unten)

Remove SDT — SDT-Daten entfernen (Kanalname, Anbieter usw.).

Remove EIT/EPG — EPG-Daten entfernen.

Remove Teletext — Teletext entfernen.

Remove Subtitles — Untertitel entfernen.

Bitratensteuerung des Streams:

Bitrate mode — Bitratensteuerungsmodus.

  1. Origin (default) — der Stream wird unverändert weitergegeben.

  2. VBR — entfernt NULL-Pakete und minimiert so den Bitrate. Nur für OTT-Distribution aktivieren.

  3. CBR auto — aktiviert Bitratenausgleich durch NULL-Pakete (Stuffing). Die Ziel-Bitrate richtet sich nach der maximalen Eingangsbitrate.

  4. CBR set stuffing bitrate — die gewünschte Bitrate explizit setzen. Liegt sie unter der Eingangsbitrate, wird wie im CBR-Auto-Modus angeglichen.

Bei aktivem CBR entspricht die PCR Accuracy der TR 101 290; das PCR-Intervall bleibt wie im Originalstream.

Stream-Korrekturen:

Fix PAT/PMT interval — passt den Intervall an TR 101 290 an, indem zusätzliche PAT/PMT eingefügt werden.

Quellenredundanz

Mehrere inputs können als Liste angegeben werden, aber nur einer ist aktiv. Fällt der aktive input aus, wird der nächste der Liste versucht — zyklisch.

Wird im stream Fallback Check aktiviert, erfolgt während des Betriebs eines Backup-input (nicht des ersten in der Liste) eine erneute Prüfung der höher gelisteten Einträge im Intervall Check Interval. Ist der Stream bei der Wiederholungsprüfung gültig, schaltet stream auf ihn um.

Da die Reihenfolge der inputs relevant ist, kann sie geändert werden. Ein pausierter input wird im Betrieb nicht berücksichtigt.

Filtern und Modifizieren von MPEG-TS

Standardmäßig wird der MPEG-TS-Stream unverändert weitergegeben.

Für jeden input stehen folgende Filteroptionen für den MPEG-TS-Stream zur Verfügung:

PID Accept — Liste erlaubter PIDs. Bei leerer Liste ist alles erlaubt außer PID Reject.

PID Reject — Liste verbotener PIDs. Hat Vorrang vor PID Accept.

PIDs können geändert werden. Dafür werden die Listen PID Old und PID New befüllt.

Mapping PID and Languages — Neuzuordnung der Sprache von Audiospuren.

Default Language — Standardsprache festlegen, falls die Tonspur keine Sprache hat.

Für den stream können neue MPEG-TS-Daten (SDT-Tabelle) gesetzt werden:

  • MPEG-TS Network ID

  • Service Name

  • Provider Name

  • Language

MPTS-Streams

MPTS-Stream — ein MPEG-TS-Stream mit mehreren Streams (Services); jeder Service hat eine eindeutige Nummer (PNR). Wird für DVB-Übertragung genutzt.

Für MPTS-Streams stehen keine Filteroptionen zur Verfügung. Die Streams werden unverändert weitergegeben.

Die Mosaic-Funktion ist standardmäßig aus. Auf schwachen CPUs nicht aktivieren — kann zusätzlichen Jitter erzeugen.

In der Stream-Diagnose werden Daten für jedes Programm separat sowie eine Gesamtstatistik angezeigt.

Demultiplexer

Extracts individual streams from MTPS stream. To do this, add input of demux type to the SPTS stream, select a source and a PNR service. If the source MPTS is active, then a list will be available when selecting the PNR, otherwise you need to set the PNR manually.

Multiplexer

Stellt aus einzelnen SPTS-Streams einen MPTS-Stream zusammen. So konfigurieren Sie ihn:

  • MPTS-Stream erstellen.

  • Einen Input vom Typ muxer hinzufügen. Bitrate für CBR-Stream-Alignment setzen (Stuffing, TR-101-290- und T-STD-Konformität).

    Wird 0 (Standard) gesetzt, findet kein Alignment statt — die Bitrate entspricht den Eingangsstreams. Dort können auch einige MPEG-TS-Parameter angegeben werden; für die meisten Anwendungen sind die Standardwerte ausreichend.

  • Im Quell-Stream einen Output vom Typ muxer hinzufügen. Servicename und ggf. Providername eintragen. Bei Nicht-Latein-Schrift in den MPEG-TS-Stream-Einstellungen die Sprache wählen.

  • Für alle Quellen wiederholen.

Der Multiplexer erzeugt für den Stream SDT, NIT und TDT/TOT (Zeitmarken). EIT (EPG) stammt aus den Quellströmen. PIDs werden neu vergeben.

Teststreams

Test Stream generator - test stream (test card). It allows to create generated video streams as plugs for broadcasting or failures on main streams. It is possible to set the type of image, sound, overlay text and time.

Die Konfiguration erfolgt durch Aktivieren des passenden Input-Typs am Stream. Videoformat, Auflösung, Bitrate, Lautstärke und Audiofrequenz u. a. lassen sich einstellen.

Die Liste der verfügbaren Test Streams findet sich im linken Seitenmenü der Anwendung.

OTT-Dienst

Liefert Streams über HTTP-basierte Protokolle — HLS, MPEG-DASH (ab Version 1.12) und MPEG-TS over HTTP. HTTPS (SSL) wird unterstützt. Die Ausgabe wird im Tab OTT der Stream-Einstellungen aktiviert.

Die Verbindungs-URLs haben das Format:

host und port werden in den http server-Einstellungen festgelegt.

streamID des Streams. Nicht zu verwechseln mit der Reihenfolge in der Stream-Liste. Die ID wird im Kopf der Stream-Statistikseite und in der Spalte ID der Stream-Liste angezeigt; sie wird bei der Stream-Erstellung festgelegt und ändert sich nie.

Analog für HLS und DASH:

Auf der Stream-Statistik-Seite werden die URLs der verbundenen Protokolle (als Vorlage) und ihr aktueller Status angezeigt. Nicht autorisierter Zugriff ist verboten — Clients müssen in Peers eingetragen sein.

Für HLS sind in der URL zusätzliche Parameter verfügbar (optional):

[URL]?a=1&s=40&m=40&v=5

  • a: 1 — absolute Pfade in der Playlist (Standard), 0 — relative Pfade.

  • s: Länge der dynamischen Playlist (Sekunden), Standard 40 s.

  • m: Mindestlänge der dynamischen Playlist (s); Standard 40 s. Maximale Länge der dynamischen Playlist 60 s. Liegt die aktuelle Chunk-Buffer-Größe unterhalb des im Request angeforderten Minimums, wird Fehler 404 zurückgegeben. Damit wird sichergestellt, dass HLS aus einem gefüllten Chunk-Buffer auf dem Server startet.

  • v: in der Playlist angegebene HLS-Protokollversion. Standard 5; bei einigen HLS-Clients muss die Version geändert werden.

Für die Kompatibilität mit einigen HLS-Clients kann der Dateiname index.m3u8 an die URL angehängt werden, z. B. http://host:port/hls/stream/login/password/index.m3u8.

Der HLS-Server hat zwei Modi — Peer mode und OTT mode.

Peer mode — Modus mit einfacher Segment-(Chunk-)Aufteilung. Empfohlen für Peering / Stream-Verteilung.

OTT mode — Modus mit für OTT-Streaming optimierter Segmentierung für schnellen Player-Start. Höhere CPU-Last; empfohlen fürs Broadcasting.

Für den HTTP-Server kann SSL (HTTPS) aktiviert werden — in den Server-Einstellungen.

Chunk Min Interval und Chunk Max Interval

In OTT mode, the stream is analyzed on PAT/PMT/SPS/PPS/IFrame and chunks are cut by the fast start players criterion. Analysis starts with min interval and if for some reason the data is not found, the chunk is forcibly cut by max interval.

HLS Adaptive Multistream

Ab Version 1.10 wird HLS Adaptive Multistream unterstützt, ab Version 1.12 zusätzlich DASH Adaptive Multistream

Für adaptive Streams wird eine separate HLS-Playlist konfiguriert. Dafür sind folgende Schritte nötig:

  • Bei den Streams, die in die adaptive Playlist aufgenommen werden, HLS mit OTT-Modus aktivieren.

  • Im Hauptmenü erscheint der Bereich für adaptive Streams. Dort einen Stream anlegen und alle in die Playlist einzubindenden Streams eintragen.

  • Streams kann ein Bitrate-Parameter gesetzt werden. Standard 0 bedeutet, dass die gemessene Bitrate verwendet wird; andernfalls lässt sie sich explizit festlegen.

Für adaptive Playlists gilt eine andere URL:

Peers (Clients) können — wie bei normalen Streams — Zugriffsbeschränkungen auf adaptive Streams haben. Eine Berechtigung für einen adaptiven Stream schließt die Berechtigung für alle enthaltenen Substreams ein.

Caching-Modell für OTT HLS und DASH.

Der Server liefert Antworten in drei Kategorien, die sich in Inhaltslebensdauer und Cache-Eignung in Zwischenknoten (Reverse Proxy, CDN, Client-Cache) unterscheiden.

1. Caching-Modell

1.1. Ressourcen und HTTP-Header

Ressource

URL

Content-Type

Cache-Control

TS-Segment

/h<sess>/<keyID>.ts, /h<sess>/<subID>/<keyID>.ts

video/mp2t

public, max-age=60, immutable

DASH MPD

/h<sess>/index.mpd

application/dash+xml; charset=utf-8

public, max-age=1

HLS master

/hls/<stream>/<login>/<pass>/index.m3u8

application/vnd.apple.mpegurl

public, max-age=1

HLS media

/h<sess>/index.m3u8, /h<sess>/<subID>/index.m3u8

application/vnd.apple.mpegurl

public, max-age=1

302 Redirect

/dash/<stream>/<login>/<pass>/index.mpd

no-cache, no-store

Raw TS

/http/<stream>/<login>/<pass>

video/mp2t

nicht gesetzt; nicht gecacht

1.2. Eigenschaften von TS-Segmenten

Der Identifier keyID wird als CRC64(startTime || streamID) gebildet und ist global eindeutig. Eine Segment-URL adressiert unveränderliche Inhalte — bei wiederholten Anfragen derselben URL wird identischer Byte-Stream zurückgegeben (solange das Segment innerhalb des gleitenden Fensters liegt).

Die Direktive immutable unterdrückt die bedingte Revalidierung durch den Client (If-None-Match, If-Modified-Since). max-age=60 ist mit dem typischen timeShiftBufferDepth=40s kompatibel.

1.3. Eigenschaften der Manifeste

max-age=1 begrenzt die obere Schranke der Inhalts-Veralterung im Cache auf eine Sekunde. Zusammen mit proxy_cache_lock on (nginx) werden Anfragenspitzen am Manifest zu einer einzigen Origin-Anfrage pro Sekunde zusammengefasst.

1.4. Inhaltsvariabilität

Bei absPath=0 (Standard; ohne URL-Parameter „a“) enthalten HLS-media- und DASH-MPD-Manifeste keine Sitzungs-Identifier im Body. Der Manifest-Inhalt ist zwischen Sitzungen mit derselben (stream, param)-Kombination identisch. So kann der Reverse-Proxy-Cache einen Eintrag bei normalisiertem Cache-Key über Sitzungen hinweg wiederverwenden.

Bei absPath=1 (URL-Parameter „a=1“) enthält der Manifest-Body absolute URLs einschließlich Schema, Host und Sitzungs-Identifier. Der Inhalt wird sitzungsspezifisch — eine sitzungsübergreifende Cache-Wiederverwendung ist nicht möglich.

2. Client-Verhalten

Klient

Manifest-Refresh-URL

Auswirkung auf die Sitzungszahl

VLC 3.x HLS

/h<sess>/index.m3u8

Eine Sitzung pro Wiedergabe

VLC 3.x DASH

/dash/<stream>/.../index.mpd

Wird per Session-Reuse behandelt (siehe 3.3)

ffmpeg 5.x HLS

/h<sess>/index.m3u8

Eine Sitzung pro Wiedergabe

ffmpeg 5.x DASH

/dash/<stream>/.../index.mpd (Wiederholungsschleife)

Wird per Session-Reuse behandelt (siehe 3.3)

dash.js, hls.js

/h<sess>/... über <Location> / Session-URL

Eine Sitzung pro Wiedergabe

3. Spezielle Mechanismen

3.1. HTTP 302 Redirect für DASH

Eine Anfrage der Form /dash/<stream>/<login>/<pass>/index.mpd liefert die Antwort 302 Found mit dem Header Location: /h<sess>/index.mpd. Der Antwort-Body ist leer. Authentifizierung und Sitzungs-Allokation finden in der Phase der Redirect-Verarbeitung statt.

Clients, die Redirect-Caching unterstützen, greifen in nachfolgenden Anfragen direkt auf die Sitzungs-URL zu. Clients ohne Unterstützung wiederholen die Redirect-Anfrage. Die Kosten der Redirect-Wiederverarbeitung beschränken sich auf Authentifizierungsprüfung und Session-Reuse-Operationen.

3.2. Session reuse für DASH

Bei der Verarbeitung der Anfrage /dash/.../index.mpd unter login-id L für stream-id S und Flag adaptive=A: existiert in _ottClientList bereits eine DASH-Sitzung mit denselben (L, S, A), wird deren sessID zurückgegeben. Es wird keine neue Sitzung angelegt, kein maxConn-Slot verbraucht.

Gilt nur für DASH. Für HLS ist kein eigener Reuse-Mechanismus nötig: HLS-Clients aktualisieren die Media-Playlist über die Session-URL und lösen bei jedem Refresh kein applyNewOTTSess aus.

3.3. Segmentwiederverwendung zwischen Sitzungen

Der Pfad /h<sess>/<keyID>.ts ist beim Auflösen von keyID auf Inhalt sess-unabhängig: keyID identifiziert das Segment innerhalb der registrierten ChunkList eindeutig (siehe _ottStreamList). Nginx mit normalisiertem Cache-Key (Entfernung des Präfixes /h<sess>/) bedient alle Anfragen derselben keyID aus einem einzigen Cache-Eintrag.

4. Anfrageparameter

Parameter

Standardwert

Auswirkung

a

0

1 — absolute URLs in den Manifesten; 0 — relative

s

40

timeShiftBufferDepth in Sekunden

m

40

Mindestfensterlänge für die Manifest-Ausgabe

v

3

#EXT-X-VERSION in HLS (von DASH ignoriert)

Das Ändern des Parameters via Query-String aktualisiert die in der Sitzung gespeicherten Werte beim nächsten applyNewOTTSess-Aufruf.

5. Lasteigenschaften

Die Origin-Last skaliert mit der Anzahl gleichzeitig beobachteter unterschiedlicher Streams. Die Erhöhung der Anzahl gleichzeitig denselben Stream beobachtender Clients erhöht die Anzahl der Origin-Anfragen nicht, sofern ein Reverse-Proxy-Cache mit normalisiertem Cache-Key vorhanden ist.

Szenario

Origin-Request-Rate (Ref.)

1 Client pro Stream X

MPD: 0.4 req/s, segment: 0.2 req/s

N Clients auf einem Stream X (Cache aktiv)

MPD: 1 req/s, segment: 0.2 req/s

N ffmpeg-Clients im Replay-Modus auf einem Stream

MPD: 1 req/s (mit proxy_cache_lock)

N Clients auf N verschiedene Streams

MPD: 0.4·N req/s, segment: 0.2·N req/s

6. Nginx als zwischenspeichernder Reverse Proxy

6.1. Basiskonfiguration

proxy_cache_path /var/cache/nginx/pss_segments
    levels=1:2 keys_zone=pss_segments:100m
    max_size=20g inactive=30m use_temp_path=off;

proxy_cache_path /var/cache/nginx/pss_manifests
    levels=1:2 keys_zone=pss_manifests:10m
    max_size=256m inactive=5m use_temp_path=off;

upstream pss_backend {
    server 127.0.0.1:41972;
    keepalive 64;
}

map $uri $pss_cache_key {
    ~^/h[0-9a-f]{16}(?<tail>/.+\.(ts|m3u8))$  "stream:$tail";
    default                                     $uri;
}

server {
    listen 80;
    server_name stream.example.com;

    location ~* "^/h[0-9a-f]{16}(/[0-9]+)?/[0-9a-f]+\.ts$" {
        proxy_cache               pss_segments;
        proxy_cache_key           $pss_cache_key;
        proxy_cache_valid         200 60s;
        proxy_cache_valid         404 403 0s;
        proxy_cache_lock          on;
        proxy_cache_use_stale     updating error timeout;
        proxy_cache_revalidate    on;
        add_header                X-Cache-Status $upstream_cache_status;

        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
        proxy_buffering           on;
    }

    location ~* "(^/h[0-9a-f]{16}(/[0-9]+)?/index\.(m3u8|mpd)$|^/(hls|dash)/.*\.(m3u8|mpd)$)" {
        proxy_cache               pss_manifests;
        proxy_cache_key           $pss_cache_key;
        proxy_cache_valid         200 1s;
        proxy_cache_valid         404 403 0s;
        proxy_cache_lock          on;
        proxy_cache_lock_timeout  2s;
        proxy_cache_use_stale     updating;
        add_header                X-Cache-Status $upstream_cache_status;

        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
    }

    location / {
        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
        proxy_set_header          X-Forwarded-Proto $scheme;
        proxy_set_header          X-Forwarded-Host  $host;
        proxy_buffering           off;
        proxy_read_timeout        3600s;
    }
}

6.2. Zweck der Direktiven

Direktive

Zweck

proxy_cache_lock on

Serialisiert Upstream-Anfragen bei parallelen Cache-Misses auf denselben Schlüssel

proxy_cache_use_stale updating

Liefert die veraltete Kopie an parallele Anfragen während der Cache-Aktualisierung

proxy_cache_revalidate on

Nutzt If-Modified-Since bei Cache Miss mit vorhandener Kopie

proxy_cache_valid 404 403 0s

Verbietet das Caching von Authorization-Fehlern und 404

keepalive 64 im Upstream

Verwaltet einen Pool persistenter Verbindungen zum Origin

proxy_buffering on

Für Segmente; aktiviert die Antwortpufferung in nginx

proxy_buffering off

Für den Bereich /; deaktiviert Buffering (Raw Streaming)

6.3. Berechnung von max_size für den Segment-Cache

Richtwert: bitrate × timeShiftBufferDepth × distinct_streams × 2

Beispiel: 10 Streams × 8 Mbps × 40 s × 2 ≈ 800 MB. Es wird empfohlen, einen 10-fachen Sicherheitsfaktor für Bitratenschwankungen einzuplanen.

6.4. TLS-Terminierung

Der Perfect-Streamer-Server akzeptiert Verbindungen auf HTTP- und HTTPS-Ports. Bei TLS-Terminierung am nginx verwendet das Upstream den HTTP-Port. Die Weiterleitung der Header X-Forwarded-Proto und X-Forwarded-Host ist erforderlich für die korrekte Bildung absoluter URLs bei absPath=1.

server {
    listen 443 ssl http2;
    server_name stream.example.com;

    ssl_certificate           /etc/letsencrypt/live/stream.example.com/fullchain.pem;
    ssl_certificate_key       /etc/letsencrypt/live/stream.example.com/privkey.pem;
    ssl_protocols             TLSv1.2 TLSv1.3;
    ssl_session_cache         shared:SSL:10m;
    ssl_session_timeout       1d;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    location ... {
        proxy_pass                http://pss_backend;
        proxy_set_header          X-Forwarded-Proto https;
        proxy_set_header          X-Forwarded-Host  $host;
        proxy_set_header          Host              $host;
        # + директивы кеширования из 6.1
    }
}

server {
    listen 80;
    server_name stream.example.com;
    return 301 https://$host$request_uri;
}

Bei HTTPS zwischen nginx und Origin gelten proxy_ssl_verify und proxy_ssl_trusted_certificate. Bei Loopback-Verbindungen ist Verschlüsselung überflüssig.

6.5. Multi-host

Wenn ein nginx-Prozess mehrere server_name bedient, wird $host zum Cache-Schlüssel hinzugefügt, um Inhalte zu isolieren:

map $uri $pss_cache_key {
    ~^/h[0-9a-f]{16}(?<tail>/.+\.(ts|m3u8))$  "$host:stream:$tail";
    default                                     "$host:$uri";
}

Die keys_zone-Größe wird mit 8000 Keys/MB berechnet. Für Multi-Host-Installationen mit Tausenden von Streams werden keys_zone=...:300m oder mehr empfohlen.

7. Client-seitiges Caching

Cache-Control: immutable wird von den Browsern Chrome/Firefox/Safari berücksichtigt. Der Client-Cache liefert das Segment bei wiederholtem Zugriff ohne bedingte Anfrage zurück (auch bei Rückwärts-Seek innerhalb des Player-Buffers).

Service Workers können basierend auf dem Cache-Control-Inhalt eine cache-first-Strategie anwenden. DASH-Player (dash.js, Shaka) nutzen MSE über SourceBuffer; ein in den Buffer eingelegtes Segment bleibt ohne erneute HTTP-Anfrage verfügbar, bis es das Schiebe-Fenster verlässt.

Für Cross-Domain-Anfragen erlaubt der Header Access-Control-Allow-Origin: * Caching in shared caches ohne Vary: Origin. Beim Wechsel des ACAO-Werts auf einen konkreten Origin wird Vary: Origin erforderlich, was die Effizienz des shared cache reduziert.

8. Bereitstellung über CDN

Perfect Streamer ist mit Pull-from-Origin-CDNs kompatibel (Cloudflare, Akamai, Fastly, BunnyCDN, Amazon CloudFront).

Origin shield. Empfohlen werden ein oder mehrere Shield-Knoten zwischen CDN-Edge und Origin, um die Origin-Anfragerate bei global verteilten Clients zu senken.

Purge. Content-addressed Segmente erfordern keinen Purge. Bei Stream-Metadaten-Änderungen (Codec, Auflösung) aktualisieren sich Manifeste innerhalb von max-age=1 ohne expliziten Purge.

Cache Warming. Bei erwartetem Lastanstieg auf einen Stream darf das CDN von mehreren Standorten aus vor Sendebeginn vorgeheizt werden.

Geo-Verteilung. Segmente (max-age=60) eignen sich gut für geografisch verteiltes Caching. Manifeste (max-age=1) tolerieren bis zu eine Sekunde Lieferverzögerung — akzeptabel für non-low-latency live.

9. Überwachung

9.1. X-Cache-Status

add_header X-Cache-Status $upstream_cache_status; in jeder gecachten Location ergänzen. Werte:

Wert

Beschreibung

HIT

Antwort aus Cache

MISS

War nicht im Cache; vom Origin geholt und gespeichert

EXPIRED

Abgelaufen, erneuert

UPDATING

Stale-Kopie an parallele Anfrage während der Aktualisierung ausgeliefert

STALE

use_stale lieferte die abgelaufene Kopie (Origin nicht erreichbar)

REVALIDATED

Origin lieferte 304 Not Modified

BYPASS

proxy_cache_bypass wurde ausgelöst

9.2. Format des access-log

log_format pss_cache '$remote_addr $status $request_method "$request" '
                     '$body_bytes_sent rt=$request_time ut=$upstream_response_time '
                     'cache=$upstream_cache_status key=$pss_cache_key';

server {
    access_log /var/log/nginx/pss.log pss_cache;
}

9.3. Metriken

Das Modul nginx-vts exportiert Per-Zone-Metriken im Prometheus-Format:

GET /status/format/prometheus

Empfohlene Schwellwerte für Alerts:

Metrik

Schwelle

Mögliche Ursache

Segment HIT rate

< 90 % über 5 Minuten

Cache-Key-Normalisierung defekt; max_size zu klein

Manifest MISS rate

> 50 % über 1 Minute

proxy_cache_lock serialisiert die Anfragen nicht

Upstream response time p95

> 500 ms über 1 Minute

Origin-Überlastung

Cache zone fill

> 90 % über 10 Minuten

Annäherung an max_size; LRU-Eviction wird geplant

10. Diagnose

Symptom

Wahrscheinliche Ursache

Lösung

Niedrige Segment-HIT-Rate

Vary: Origin mit hoher Origin-Variabilität; defekte Normalisierung in map

Header und Regex in der map-Direktive prüfen

404 bei Segmenten nach Verlassen des Fensters

Gecachter 404 bei Segment, das aus dem Sliding Window gefallen ist

proxy_cache_valid 404 0s in der Segments-Location ergänzen

Playback-Start-Verzögerung 2–5 s

proxy_cache_lock_timeout überschreitet die Ziel-Latenz

Auf 1–2 s senken; proxy_cache_use_stale updating aktivieren

Manifest aktualisiert nicht

proxy_cache_valid überschreibt max-age

proxy_cache_valid 200 1s explizit setzen

Wachsendes TIME_WAIT am Upstream

keepalive fehlt im Upstream-Block

keepalive 64, proxy_http_version 1.1 und proxy_set_header Connection "" hinzufügen

403 auf /dash/.../<segment>.ts von ffmpeg

Der Client löst relative URLs gegen die Pre-Redirect-URL auf

Der Server gibt <BaseURL>/h<sess>/</BaseURL> aus (absolute Pfade); im aktuellen Build kompatibel

11. Sicherheit

11.1. Session URL

Eine URL der Form /h<sess>/... erfüllt die Funktion eines Sitzungs-Tokens — eine erneute Authentifizierung ist nicht nötig. Die Lebensdauer ist durch das idle timeout begrenzt (Wert 30 s). Bei Inaktivität wird die Sitzung von der cleaner-Aufgabe entfernt.

Anforderungen:

  • HTTPS für alle OTT-Pfade (/hls/, /dash/, /h<sess>/) in Produktion

  • Die Session-ID im Location-Header der 302 wird nicht gecacht (no-cache, no-store)

11.2. Rate limiting

limit_req_zone $binary_remote_addr zone=dash_top:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=hls_top:10m  rate=5r/s;

server {
    location /dash/ {
        limit_req zone=dash_top burst=20 nodelay;
        proxy_pass http://pss_backend;
    }
    location /hls/ {
        limit_req zone=hls_top burst=20 nodelay;
        proxy_pass http://pss_backend;
    }
}

Session-URLs (/h<sess>/) benötigen kein Rate Limiting — die Verarbeitung ist günstig, Antworten werden gecacht.

11.3. Caching von Fehlerantworten

proxy_cache_valid 200 60s;
proxy_cache_valid 301 302 0s;
proxy_cache_valid 404 403 0s;
proxy_cache_valid any 1s;

Verbietet das Caching von Redirects (eindeutiges sess in Location) und von Antworten mit Auth- oder Not-Found-Fehlern.

11.4. Einschränkung des Netzwerkzugriffs auf den Origin

Port 41972 (41982 für HTTPS) muss für externen Verkehr geschlossen sein. Zulässige Konfigurationen:

  1. Perfect Streamer an 127.0.0.1 binden (bei lokalem nginx)

  2. Firewall-Regel:

iptables -A INPUT -p tcp --dport 41972 ! -s 10.0.0.0/8 -j DROP

12. Integration mit Middleware

12.1. Das prefix-login-Modell

Perfect Streamer kann die Nutzeridentifikation über Prefix-Login an Middleware/Billing-Systeme delegieren. Ein externer Connector zum Billing-System ist im aktuellen Release nicht enthalten.

Konfiguration des Embedded-Benutzers:

{
  "id": 9,
  "login": "sub",
  "password": "xxx",
  "is-prefix": true,
  "max-conn-http-hls": 1,
  "accept-stream": [ ... ]
}

Mit is-prefix: true akzeptiert der Server URLs mit Logins der Form <prefix><billing_user_id>:

/dash/test1/sub42/xxx/index.mpd
/hls/test1/sub43/xxx/index.m3u8

12.2. Statistikformat

<clients>
  <client login-id="-1974387287" login="sub" match-login="sub42"
          sess-id="11331..." ott-type="dash" stream-id="10000" .../>
  <client login-id="-2147031294" login="sub" match-login="sub43"
          sess-id="11132..." ott-type="dash" stream-id="10000" .../>
</clients>

Das Feld login-id enthält den Hash des URL-Logins. login ist der konfigurierte Wert. match-login ist der vom Client genutzte URL-Login.

12.3. Einschränkungen von prefix-login

  • Gemeinsames Passwort. Alle Subscriber des Prefix-Pools nutzen ein einziges Passwort. Eine Kompromittierung gewährt Zugriff auf jedes <prefix><string>.

  • ACL-Granularität. accept-stream gilt für den gesamten Prefix-Pool; eine subscriber-spezifische ACL gibt es ohne externes Billing nicht.

  • Passwort-Rotation. Eine Änderung trennt alle aktiven Subscriber. Für eine schrittweise Ablösung sind vorübergehend zwei Prefix-Logins nötig.

13. WebVTT-Untertitel

Die Untertitelquelle ist DVB Teletext / DVB Subtitling aus dem Eingangs-MPEG-TS. In den Abschnitten Media Information oder Original Media Information müssen Teletext-Untertitel-Spuren vorhanden sein. Im Abschnitt Analyzer kann zusätzlich überprüft werden, dass Pakete der entsprechenden PIDs aktiv sind.

Für OTT HLS/DASH muss der OTT-Modus aktiviert sein (im Peer mode sind WebVTT-Untertitel nicht verfügbar). Im Abschnitt Output # OTT muss der Chunk-Zähler OTT WebVTT buffer chunk count einen Wert ungleich null aufweisen.

Zur Diagnose der Untertitel Analyze und Trace am Stream aktivieren. Beim Stream-Start sollte im Stream-Log Folgendes erscheinen:

Start Teletext subtitle decoder
[ttxsubdec] ttx: pid=331 magazine=8 page=0x88 lang=***

Im Folgenden wird der dekodierte Untertiteltext in das Log geschrieben.

13.1. URL der VTT-Segmente

Schema

URL

Inhalt

HLS master

/hls/.../index.m3u8

#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",...,URI="/h<sess>/sub/<pid>/index.m3u8"

HLS subtitle playlist

/h<sess>/sub/<pid>/index.m3u8

Liste <keyHex>.vtt mit #EXTINF

HLS-VTT-Segment

/h<sess>/sub/<pid>/<keyHex>.vtt

VTT mit HLS-spezifischer X-TIMESTAMP-MAP

DASH MPD AdaptationSet

in index.mpd

contentType="text" mimeType="text/vtt" + <SegmentTemplate media="$Number$.vtt">

DASH-VTT-Segment

/h<sess>/sub/<pid>/<seq>.vtt

VTT mit DASH-spezifischer X-TIMESTAMP-MAP

<keyHex> ist der 16-stellige Hex-Wert aus CRC64(startTime, streamID, pid). <seq> ist die dezimale Chunk-Nummer im Subtitle-Storage (eigener Zähler getrennt vom Video-Storage).

DVR / Archiv

Ab Version 1.13 bietet Perfect Streamer einen integrierten DVR — ein persistentes Stream-Archiv auf der Platte, das parallel zur normalen OTT-Ausgabe (HLS / DASH) läuft. Das Archiv wird automatisch geschrieben, ohne separaten Prozess, und über dieselben OTT-URLs wie Live wiedergegeben — Unterschied ist nur der Query-Parameter.

Funktionen:

  • Aufzeichnung jedes OTT-Streams ins Archiv auf dem gewählten Speicher.

  • HLS- und DASH-Archivwiedergabe (VOD) auf denselben URLs wie Live.

  • Untertitel-Unterstützung (WebVTT) — neben TS-Chunks geschrieben.

  • Mehrere Speicher — ein Stream wird an einen gebunden; verschiedene Streams können auf verschiedene Platten schreiben.

  • Automatische Bereinigung nach Aufbewahrungszeit und Speicherauslastung.

  • EPG-aligned VOD — Archivausgabe per EPG-Ereignis-Bezug.

  • Adaptives VOD — wird für adaptive Gruppen unterstützt.

DVR erfordert keine separate Lizenz. Aktivierung pro Stream durch Hinzufügen einer Speicherbindung.

DVR ersetzt nicht das Live-Broadcasting. Hat ein Stream ein Archiv, erhält der Client eine Live-Playlist mit identischem Verhalten wie ohne DVR. Das Archiv läuft erst, wenn der Client den VOD-Modus explizit per URL-Query-Parameter anfordert (siehe unten).

Speicher-Konfiguration

Ein Speicher ist ein Eintrag im Abschnitt Configuration / DVR Storage. Jeder Eintrag beschreibt ein Verzeichnis auf der Platte, in das PSS Archivdateien schreibt. Ein Stream nutzt einen Speicher.

Beim Hinzufügen eines Speichers werden konfiguriert:

Name — Anzeigename.

Dir Path — Pfad zum Verzeichnis auf der Platte. Nach Erstellung des Eintrags ist der Pfad nicht änderbar — um das Archiv zu verschieben, Eintrag löschen und neuen mit neuem Pfad anlegen. Bestehende Dateien werden beim Löschen auf der Platte nicht angerührt.

Max Usage, % — Schwellenwert der Auslastung (Standard 90 %). Bei Überschreitung startet die size-based Bereinigung (siehe unten). Minimum 1 %, Maximum 100 %.

Cleanup Interval, Sek — Periode der Bereinigungsaufgabe (Standard 10 Sek). Bei jedem Tick wird zunächst alles älter als die Aufbewahrungstiefe entfernt; danach — bei Max Usage-Überschreitung — alte Chunks.

Disk Pressure Grace, Sek — wie lange Used % Max Usage durchgehend überschreiten muss, bevor Size-based cleanup startet (Standard 60 Sek). Filtert kurze Spitzen.

Disk Pressure Cut, Sek — Obergrenze pro Bereinigungs-Tick: wie viele Videosekunden pro Stream auf einmal gelöscht werden dürfen (Standard 300 Sek). Der Rest geht in den nächsten Tick.

Disk Emergency Bytes — Schwellenwert für freien Speicher, unter dem der Speicher in Error übergeht und Aufzeichnung stoppt (Standard 2 GiB). Auto-Wiederherstellung bei freiem Platz ≥ 2 × diesem Wert.

Alarm Disk-Full Hysteresis, % — Breite des Hysteresebandes beim Verlassen von DiskFullDegraded (Standard 2 %).

Die meisten Standardwerte passen für typische Installationen; Anpassungen sind meist nur für Max Usage und Dir Path nötig.

Pro Platte ist ein Speicher sinnvoll. Mehrere Einträge auf derselben Platte mit verschiedenen Unterordnern konkurrieren um freien Platz — statvfs zeigt das Gesamtbild, die Bereinigung läuft je Eintrag.

Stream an Speicher binden

In den Stream / OTT-Einstellungen erscheint ein DVR-Abschnitt:

Storage — Dropdown verfügbarer Speicher; 0 bedeutet „Archiv für diesen Stream deaktiviert“.

Storage Hours — Archivtiefe für diesen Stream, in Stunden. Chunks älter als dieser Wert werden bei jedem Tick gelöscht. 0 deaktiviert Rolling cleanup (nur Size-based cleanup per Max Usage läuft).

Storage Min Hour — untere Schutzschwelle (Stunden). Die Bereinigung löscht nie Chunks jünger als dieser Wert, auch nicht unter Max Usage-Druck. Verwenden, wenn die Geschäftslogik eine garantierte frische Aufzeichnung verlangt, z. B. „letzte 2 Stunden immer vorhanden“.

Storage zur Laufzeit ändern:

  • 0 setzen — deaktiviert das Archiv; vorhandene Chunks bleiben erhalten, neue werden nicht geschrieben. VOD-Sitzungen liefern fortan 404;

  • Auswahl eines anderen Speichers — der Stream wird vom alten gelöst und schreibt in den neuen. Dateien vom alten Speicher werden nicht migriert.

Änderungen an Storage Hours und Storage Min Hour wirken sofort — beim nächsten Tick verwendet die Bereinigung den neuen Wert.

Nach Konfiguration schreibt der Stream automatisch das Archiv, sobald er in den Zustand Running wechselt.

VOD: Archivwiedergabe

Das Archiv wird über dieselben URLs wie Live HLS / DASH wiedergegeben (siehe Abschnitt OTT-Service) — nur der Query-Parameter unterscheidet sich.

URLs und Parameter

URLs für HLS und DASH:

Ohne Query-Parameter — normales Live mit Sliding Window. Mit t-Parameter — VOD-Modus.

Parameter

Zweck

t=<epoch>

VOD-Startzeit (Unix epoch, Sek). t=0 — ab Archivanfang. Das Vorhandensein von t (auch t=0) aktiviert den VOD-Modus.

d=<sec>

VOD-Fensterdauer, Sek. d=0 oder Parameter fehlt — „bis zum aktuellen Moment“. Nur sinnvoll zusammen mit t.

epg=<epoch>

EPG-aligned VOD: Der Server findet selbst das zum angegebenen Moment aktive EPG-Ereignis und nimmt dessen start und duration als Fenstergrenzen. Inkompatibel mit t und d (server-seitige Ersetzung). Siehe unten.

a, s, m, v

Standardparameter für Live (siehe OTT-Service); s und m werden im VOD-Modus ignoriert.

Verhalten nach t und d:

t

d

Fenster

404-Bedingung

nein

live (Sliding Window)

0

keiner / 0

[Archivanfang, jetzt]

DVR nicht gebunden

0

> 0

[Archivanfang, +d]

DVR nicht gebunden

> 0

keiner / 0

[t, jetzt]

DVR nicht gebunden

> 0

> 0

[t, t+d]

DVR nicht gebunden

Grenzen-Normalisierung:

  • t vor Archivanfang — start wird automatisch auf den ersten verfügbaren Chunk gezogen (Cleanup könnte schon getrimmt haben). Das ist kein 404 — der Rest wird ausgeliefert.

  • t in der Zukunft oder Fenster komplett vor dem Archiv — leere, aber gültige Playlist (HLS: nur Header + EXT-X-ENDLIST; DASH: @type="static", mediaPresentationDuration="PT0S").

  • Chunks werden strikt nach startTime ∈ [t, t+d) gewählt — keine Teilsegmente.

VOD auf einem Stream ohne Archiv (oder dessen Speicher in Error ist) — 404 sofort auf Master-Playlist / MPD. Keine Sitzung wird angelegt.

Fehlertexte im 404-Body (in Server-Logs und HTTP-Body sichtbar):

  • VOD: stream not running — Stream ist im Konfig, aber nicht in Running.

  • VOD: no DVR archive — kein Speicher am Stream eingestellt oder Speicher in Error.

  • VOD: DVR detached — Stream wurde zwischen Anfragen vom Speicher gelöst.

  • VOD: EPG event not found — kein Ereignis für ?epg= gefunden.

VOD-HLS-Playlist — geschlossen (Player sieht Dauer und kann spulen):

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.000,
...
#EXT-X-ENDLIST

In der Live-Playlist fehlen diese Marker — das ist der einzige Unterschied.

VOD-DASH-MPD — statisch: @type="static", festes mediaPresentationDuration, explizite <SegmentURL>. Live-DASH bleibt @type="dynamic".

Hat das gewählte Intervall Lücken im Archiv (z. B. durch Aufzeichnungs-Neustart oder mittendrin getrimmten Cleanup), wird das DASH-MPD automatisch in mehrere <Period> aufgeteilt — eines pro durchgehende Spur. Player (VLC, dashjs, Shaka) spulen über die Periodengrenze ohne Sonderkonfiguration.

EPG-aligned VOD

Ist der Stream mit einer EPG-Quelle verbunden (Felder EPG Source und EPG Channel in den Stream-Einstellungen), kann der Client das Archiv anhand eines Zeitpunkts innerhalb eines EPG-Ereignisses anfordern:

Der Server findet das beim angegebenen epoch aktive EPG-Ereignis und setzt dessen start und duration als VOD-Fenstergrenzen ein. Nützlich für Programmkataloge: Die UI kennt die Ereigniszeit, muss aber keine genauen Sek-/ms-Grenzen berechnen.

Ist der Stream nicht an EPG gebunden oder gibt es zu diesem Moment kein Ereignis — 404 ``VOD: EPG event not found``. t und d werden bei vorhandenem epg ignoriert.

Adaptive Streams

Adaptive Gruppen (siehe HLS Adaptive Multistream) unterstützen dieselben VOD-Parameter:

In die Master-Playlist (HLS) gelangen nur Varianten mit konfiguriertem DVR-Speicher. Varianten ohne DVR werden übersprungen (im Log VOD: variant N has no DVR); der Aufbau aus den verbleibenden Varianten läuft weiter.

In der DASH-Variante wird jede Qualität zu einem eigenen <Representation> innerhalb gemeinsamer <Period>; der Player kann zwischen Qualitäten ohne Manifest-Reopen wechseln.

Player-Verhalten

VOD-HLS / DASH aus dem Archiv läuft in Standard-Playern: VLC, hls.js, dashjs, Shaka, ffmpeg. Timeline-Spulen funktioniert.

Fordert der Player ein Segment an, das der Cleanup bereits entfernt hat, gibt der Server 404 für dieses Segment zurück (nicht 500). VLC, hls.js, dashjs überspringen das Segment und spielen vom nächsten weiter.

Zusätzliche Möglichkeiten:

  • Schutz aktiver Sitzungen: Solange eine VOD-Sitzung offen ist, löscht der Cleanup keine Chunks im Fenster (siehe unten).

  • Live-edge bridge: Fordert ein Client in einer VOD-Sitzung ein Segment jenseits vodEnd an — z. B. nach Erreichen des Archivendes vorwärts in der Timeline — liefert der Server das Segment automatisch aus dem Live-Speicher. Keine Weiterleitungen oder Re-Auth.

  • Playlist-Cache: Auf wiederholte Anfragen derselben VOD index.m3u8 / index.mpd liefert der Server eine byteidentische Antwort — ohne Neuaufbau. Geeignet für CDN vor PSS.

Untertitel im Archiv

Trägt der Stream Untertitel (DVB Subtitling, Teletext oder WebVTT) und ist die Option OTT WebVTT aktiviert, werden Untertitel parallel zu den TS-Chunks archiviert — als .vtt-Dateien neben .ts.

Im Live-Modus enthält die Master-Playlist EXT-X-MEDIA:TYPE=SUBTITLES; im VOD-Modus liefert der Server eine VOD-Untertitel-Playlist (mit ENDLIST) und .vtt-Segmente unter denselben URLs.

Hinweise:

  • HLS: Der X-TIMESTAMP-MAP-Header bleibt am Anfang jeder .vtt (per HLS-Spezifikation erforderlich).

  • DASH: Der X-TIMESTAMP-MAP-Header wird im Flug entfernt (an absolute PCR gebunden, kollidiert mit dem DASH-Anker; sonst zeigt VLC leere Untertitel).

  • In adaptiver Gruppe: Schreibt der aktive Sub-Stream keine Untertitel, liefern VTT-Segmente 404. Auf der nächsten Variante kann der Player wieder Untertitel erhalten.

Untertitel lassen sich entweder per OTT WebVTT-Option am Stream deaktivieren oder indem HLS im OTT-Modus gar nicht aktiviert wird.

Bereinigung und Retention

PSS verwendet zwei Bereinigungsstrategien, die bei jedem Tick der Bereinigung laufen (Standard alle 10 Sek):

  1. Rolling cleanup (pro Stream): Pro Stream werden Chunks älter als Storage Hours gelöscht. Läuft immer, auch bei halbleerer Platte.

  2. Size-based cleanup (speicherweit): Wenn Used % durchgehend für Disk Pressure Grace Sek Max Usage überschreitet, werden die ältesten Chunks proportional über alle Streams des Speichers getrimmt. Pro Tick Disk Pressure Cut Sek Video je Stream. Nie Chunks jünger als Storage Min Hour.

  3. Emergency disk-full cut: Fällt der freie Speicher unter Disk Emergency Bytes, läuft die Bereinigung aggressiv und kann auch sitzungsgeschützte Chunks löschen. Aufzeichnung stoppt, bis der freie Platz mit Hysterese × 2 wiederhergestellt ist.

  4. Orphan scan (stündlich): Dateien ohne Indexeintrag können auf der Platte verbleiben (nach unerwartetem PSS-Stopp). Stündlich durchläuft der Scanner die Stream-Unterverzeichnisse und entfernt solche „vergessenen“ Dateien. Race-Schutz gegen den Writer — Dateien jünger als 60 Sek werden übersprungen.

Hinweis. Bereinigungsaufgaben laufen im Hintergrund; in der Regel ist kein Eingreifen nötig. Wächst das Archiv schneller als es getrimmt wird, Storage Hours auf den Streams senken oder Disk Pressure Cut erhöhen.

Schutz aktiver VOD-Sitzungen

Wenn ein Client eine VOD-Sitzung öffnet, wird auf jedem beteiligten Speicher ein „Schutzslot“ mit Fenster-Startzeit registriert. Rolling- und size-based-Cleanup berühren Chunks im Fenster offener Sitzung nicht. Der Slot wird beim Schließen (FIN, Timeout) automatisch freigegeben.

Das heißt:

  • Hält ein Client eine VOD-Sitzung lange, kann er garantiert zu jedem Moment im Fenster spulen — Chunks „verschwinden nicht unter ihm“.

  • Die Bereinigung per Max Usage kann Used % vorübergehend nicht auf die Schwelle drücken, solange eine Sitzung aktiv ist; verlässt der Client den Stream, holt die Bereinigung auf.

  • Emergency disk-full cut und Storage Min Hour umgehen den Schutz: Ist die Platte fast leer, werden Chunks gelöscht und der Client erhält 404 für die betroffenen Segmente (der Player überspringt).

  • Nach PSS-Neustart verschwinden Schutzslots — Bereinigung läuft sofort weiter.

Mehrere Speicher

Beliebig viele DVR Storage-Einträge sind möglich — je Verzeichnis / Platte einer. Streams werden unabhängig an verschiedene Speicher gebunden. Bereinigung und Schwellen (Max Usage, Disk Pressure) wirken per-storage.

Anwendungsfälle:

  • Tiering nach Wert: SSD-Speicher für Premium-Kanäle mit großer Tiefe, HDD-Speicher hoher Kapazität für den Rest.

  • Eigene Platte für das Archiv: damit die DVR-Aufzeichnung nicht mit Systemplatte oder Temp-Dateien konkurriert.

  • Projekttrennung: eine Platte für Kanalpaket Nr. 1, eine andere für Nr. 2 — vereinfacht Migration und Audit.

Das Ändern der Stream-Bindung (Feld Storage in Stream / OTT) schaltet die Aufzeichnung im Betrieb um. Alte Dateien bleiben auf der bisherigen Platte unangetastet — sie lassen sich manuell löschen oder durch Rückumstellung wieder anbinden.

Speicherzustand und Monitoring

Im Abschnitt Data / DVR Storage List (sowie über API GET /data/dvr-storage-list) werden pro Speicher angezeigt:

  • StateReady / DiskFullDegraded / Error.

  • Total / Free / Used Bytes — Disk-Statistik (statvfs).

  • Used % — aktueller Auslastungsanteil.

  • Archived Bytes — Gesamtgröße der im Index aller gebundenen Streams erfassten Chunks (ohne Orphan-Dateien).

  • Attached Streams — Anzahl der an diesen Speicher gebundenen Streams.

  • Pressure Since Sec — Moment (epoch), zu dem Used % im aktuellen Druckepisode erstmals Max Usage überschritten hat; 0 heißt „kein Druck jetzt“.

Zustände:

  • Ready — Normalbetrieb.

  • DiskFullDegraded — freier Speicher < (Disk Emergency Bytes × 2); Aufzeichnung läuft noch, kann aber jederzeit in Error übergehen.

  • Error — freier Speicher < Disk Emergency Bytes; Aufzeichnung gestoppt; Restart per Hysterese.

Ist der Speicher in Error, prüfe den freien Platz auf der Platte; PSS verlässt diesen Zustand nicht von selbst, bis physisch mehr Platz vorhanden ist.

Schutz vor versehentlichem Datenverlust

Mehrere Operationen der Admin-Oberfläche führen zum Verlust des aufgezeichneten Archivs oder Ende der VOD-Auslieferung. Vor der Ausführung zeigt die Admin-UI eine modale Bestätigung:

  • DVR-Storage löschen — alle gebundenen Streams verlieren VOD-Zugriff; Dateien bleiben auf der Platte, sind aber ohne Eintrag über PSS nicht erreichbar.

  • Stream auf anderen Speicher umstellen — VOD über das alte Archiv funktioniert nicht mehr.

  • Stream vom Speicher lösen (Storage = 0) — gleicher Effekt.

  • Max Usage senken — kann size-based Bereinigung auslösen und alte Chunks löschen.

  • Storage Hours / Storage Min Hour senken — kann Teile des Archivs aus dem Rolling-Fenster drängen.

Dies ist eine bewusste Produktentscheidung: Die Operation ist möglich, aber mit Bestätigung, und gelöschte Dateien bleiben auf der Platte (Restore aus Backup möglich). Das Archiv auf separatem Fileserver / RAID senkt das Risiko irreversiblen Verlusts deutlich.

Einschränkungen der aktuellen Version

  • Eine vom Client geöffnete VOD-Sitzung verfolgt die Live-Edge nicht — wenn während der Sitzung neue Chunks ins Archiv kamen, muss der Client die Playlist neu anfordern (Standard aller HLS / DASH Player).

  • Pro Platte ist ein Speicher sinnvoll — mehrere Einträge mit verschiedenen Unterordnern konkurrieren um freien Platz.

  • Segmente werden per Hash (HLS) oder über $Number$.ts-Template (live DASH) / explizite <SegmentURL> (VOD DASH) adressiert. Chunk-Größenwechsel zwischen Live und VOD erfordert kein Reopen der URL.

  • Der Orphan-Scanner läuft stündlich; zur Beschleunigung PSS neu starten.

Stream-Operationen

Löschen. Zum Entfernen eines Streams in seine Einstellungen gehen und auf Delete stream klicken.

Klonen. Zum Klonen eines Streams in seine Einstellungen gehen und auf Clone stream klicken.

Sortierung. Klicken Sie auf die Schaltfläche Sort im Stream-Listen-Fenster, um die Stream-Sortierung zu konfigurieren. Geben Sie anschließend die gewünschte Reihenfolge an, indem Sie die Streams in der Liste nach oben oder unten ziehen. Klicken Sie auf Save order, um die festgelegte Sortierreihenfolge zu speichern, oder auf Cancel, um die Änderungen zu verwerfen.

Listenfilterung. Klicken Sie auf das Such-Symbol und geben Sie den Filter ein, um die Stream-Liste zu filtern. Mit dem Zurück-Pfeil heben Sie den Filter auf.

Gruppen-Operationen. Im Filter-Modus der Stream-Liste lassen sich mehrere Streams durch Aktivieren der Kontrollkästchen in der linken Spalte auswählen. Sind Streams ausgewählt, werden die Schaltflächen Löschen und Klonen für die ausgewählten Streams verfügbar.

Export und Import von Streams per Python-Skript

Konfigurations-Export/-Import läuft über eine .m3u-Playlist und ein Python-Skript.

Python 3 muss unter /usr/bin/python3 verfügbar sein.

Stream-Export und -Import über die Weboberfläche

Beim Klick auf die Schaltfläche Playlist in der Stream-Liste öffnet sich der Dialog zum Export der Streams in eine m3u8-Playlist. Exportiert werden nur die unter Berücksichtigung der angewandten Filter aktuell angezeigten Streams.

Einstellungen:

  • Host / IP — Servername oder -adresse, die zum Aufbau der Stream-URLs verwendet wird.

  • Protocols — Auswahl der Protokolltypen für den Export.

  • Login — Auswahl des Kontos, das zur Bildung der Stream-URLs verwendet wird.

  • Use Display NamesDisplay name des Streams anstelle des Stream name in der m3u8-Datei verwenden.

Die Playlist wird beim Klick auf Download als m3u8-Datei heruntergeladen.

Beim Klick auf die Schaltfläche Import Playlist wechselt der Dialog in den Modus zum Importieren von Streams aus einer m3u8-Playlist. Beim Import werden bestehende Streams nicht entfernt. Bei allen importierten Streams wird die Importzeit im Feld Note vermerkt.

Einstellungen:

  • Playlist — Auswahl der Playlist-Datei für den Import.

  • Create Outputs — Protokollauswahl für die automatische Erstellung von Ausgängen für importierte Streams.

  • Output Ports From — Startportnummer für die Generierung der Ausgänge.

  • Output IP — Auswahl der Schnittstelle, an die die Ausgangsstreams gebunden werden.

  • Tags — Tags, mit denen importierte Streams markiert werden. Nützlich für Gruppenoperationen, z. B. das Löschen aller importierten Streams.

Ist im Feld Playlist eine zu importierende Datei angegeben, wird die Schaltfläche Load Playlist aktiv. Beim Klick auf Load Playlist wird die Playlist vorab geladen und das Parsing-Ergebnis in einer Tabelle angezeigt. Nach dem Parsing wird die Schaltfläche Import Streams aktiv — bei deren Klick werden die Streams importiert und Outputs für sie generiert.

Berichte und Diagnose

Im Bereich Streams werden alle streams als Tabelle angezeigt. Die Pause-Aktion steht den Rollen admin und restricted admin zur Verfügung.

Für jeden stream stehen detaillierte Statistiken und Berichte zur Verfügung.

Peers — Liste aktiver Empfänger (Clients). Für jeden gibt es separate Statistiken.

Stream-Analyse

Der Streamer-Analyzer misst und analysiert verschiedene Parameter des MPEG-TS-Streams, was eine Qualitätsbewertung ermöglicht.

Input speed — Stream-Rate (Bitrate) in kbps. Ändert sich nach der Filterung anhand der PCR-Marken. Wird als Diagramm dargestellt, das auch die Ausgangsbitrate nach dem Synchronisierer zeigt.

Raw data speed — Empfangsrate der Daten über das gewählte Protokoll. Overhead — Aufschlag in % für den Protokoll-Overhead.

CC errors — Paketverluste (CC, Discontinuity). Angezeigt werden periodische Zähler und ein kumulativer Zähler über die Stream-Uptime; zusätzlich wird die Historie als Diagramm dargestellt.

Scrambled — Zähler verschlüsselter MPEG-TS-ES-Pakete. Werte ≠ 0 bedeuten Ausfälle beim Entschlüsseln verschlüsselter Kanäle.

Sync by — Synchronisationsquelle, Standard PCR. Ist der PCR fehlerhaft, kann der Video-PTS/DTS verwendet werden (siehe Input-Einstellung Force Sync by PTS).

PCR interval — Intervall zwischen PCR-Marken. Empfohlen: nicht mehr als 50 ms.

PCR jitter — Maß für die Synchronisationsgenauigkeit des Ausgangsstreams; gemessen als Differenz zwischen PCR und Echtzeit.

Analyze PCR PMT Gap — wird über eine separate Einstellung aktiviert. Es wird die Streuung zwischen PCR und PTS/DTS für jedes ES analysiert. Die Historie wird als Diagramm angezeigt. Eine zu große Streuung kann bei Playern mit kleinem Sync-Buffer Probleme verursachen. Die Analyse wird über die Einstellung Analyze PAT/PMT/KF aktiviert.

PAT interval und PMT interval — Intervall zwischen PAT-(PMT-)Tabellen. Empfohlen: nicht mehr als 500 ms. Aktivierung der Analyse über Analyze PAT/PMT/KF.

Key Frame interval — misst das Intervall zwischen Keyframes (KF). Für Player, die zufällig in den Stream einsteigen, werden maximal 1 s empfohlen. Die Analyse wird über die Einstellung Analyze PAT/PMT/KF aktiviert.

PAT/KF interval — misst das durchschnittliche Intervall zwischen Anfang und Ende der Sequenz PAT/PMT/SPS/PPS/KF. Davon hängt die Startgeschwindigkeit der Wiedergabe bei Playern ab, die zufällig in den Stream einsteigen. Gemessen wird ab dem Anfang des KF im Stream — die reale Player-Startzeit ist daher länger. Die Analyse wird über die Einstellung Analyze PAT/PMT/KF aktiviert.

Aktivieren von Analyze PAT/PMT/KF schaltet den Stream-Analyzer dauerhaft ein, was die CPU-Last erhöht.

Jitter-Steuerung

Für die Jitter-Steuerung gibt es im Stream mehrere Einstellungen:

  • Jitter Compensation Delay (ms) — Funktion zur Kompensation des Netzwerk-Jitters; legt die Buffergröße fest. Ausführliche Beschreibung: https://forum.pstreamer.tv/viewtopic.php?t=25

  • Jitter Auto sync — setzt 2000 ms für TCP-basierte Protokolle (HTTP, HLS); für UDP-Protokolle bleibt der Wert bei 500 ms.

  • Limit PCR gap (ms) — prüft, wie weit der PCR springen darf; bei Überschreitung erfolgt eine Resynchronisation.

If PCR Accuracy errors appear after the transcoder, you need to set an even bitrate using stuffing for the encoded stream along the followingpath: „input - transcoder - Align Total Bitrate“. The speed must be guaranteed to be greater than the bitrate of video and audio.

System Monitor

Überwachung der wichtigsten Systemparameter.

Mosaic

Funktion zur Screenshot-Aufnahme aus dem Eingangsstream. Wird pro stream einzeln aktiviert.

Falls nicht benötigt, kann sie zur Ressourcenschonung im Bereich Settings/Server Settings vollständig deaktiviert werden.

Verwaltung

Im Bereich Configuration/Administration/Administrators List werden Benutzer für den Zugriff auf die Weboberfläche (eingebauter HTTP-Server) angelegt.

Benutzern werden Rollen zugewiesen:

admin — Vollzugriff.

restricted admin — Einstellungen sind nicht verfügbar; es kann nur pause geändert werden.

viewer — Zugriff nur im Lesemodus.

Sicherung der Einstellungen

Für ein Backup der Einstellungen den Inhalt des Ordners /opt/pss/config sichern.

Zur Wiederherstellung den Dienst stoppen und den Inhalt von /opt/pss/config ersetzen.

Anbindung externer Monitoring-Systeme

pss-metrics — universeller Metriken-Exporter für Perfect Streamer

Ein einzelnes Python-3-CLI-Skript, das Statistiken über die HTTP-API des PSS-Webservers abruft und die Ausgabe für die gängigsten Monitoring-Systeme formatiert:

  • Zabbix (UserParameter, Low-Level Discovery, zabbix_sender trapper)

  • Prometheus (Text-Expositionsformat für den textfile collector)

  • InfluxDB / Telegraf (Line Protocol oder JSON für den exec-Input)

  • Universelles JSON für beliebige Skripte und Nagios-artige Statusprüfungen

Der Exporter ist eine einzelne, in sich geschlossene Datei ohne Drittanbieter-Abhängigkeiten und nutzt ausschließlich die Standardbibliothek von Python 3.6+ (urllib, xml.etree, json, argparse).

Dateien

pss-metrics.py                    основной CLI (исполняемый)
userparameter_pss.conf.example    шаблон UserParameter для Zabbix

Einrichtung

Der Exporter wird unter /opt/pss/monitoring/pss-metrics.py ausgeliefert. Stellen Sie sicher, dass Python 3.6 oder neuer installiert ist:

# RHEL / Rocky / AlmaLinux
yum install -y python3

# Debian / Ubuntu
apt-get install -y python3

Es werden keine zusätzlichen Pakete benötigt.

Konfiguration

Standardmäßig verbindet sich pss-metrics mit http://127.0.0.1:43971 und ermittelt den Port automatisch aus /opt/pss/config/pss.json (oder /opt/pss/config/pss_default.json). Parameter können über Umgebungsvariablen, die Datei /etc/pss-metrics.conf (Format Schlüssel=Wert) oder Kommandozeilen-Flags überschrieben werden. Reihenfolge: CLI > env > Datei > Standardwerte.

Unterstützte Variablen:

PSS_URL          полный URL, например http://10.0.0.1:43971  (по умолчанию авто)
PSS_USER         логин веб-сервера (если включена авторизация)
PSS_PASS         пароль веб-сервера
PSS_TIMEOUT      таймаут HTTP, в секундах                    (по умолчанию 5)
PSS_CACHE_DIR    каталог кеша                                (по умолчанию /run/pss-metrics)
PSS_CACHE_TTL    время жизни кеша, в секундах                (по умолчанию 10)
PSS_CA_BUNDLE    путь к CA bundle для HTTPS
PSS_INSECURE     1 — отключить проверку TLS-сертификата
PSS_VERBOSE      1 — логировать запросы в stderr

Cache: jeder Lauf führt höchstens einen HTTP-GET pro Endpoint innerhalb des TTL-Fensters aus. Bei TTL=10 s erzeugen selbst hunderte UserParameter-Abfragen pro Minute nur ~6 HTTP-Anfragen pro Minute an PSS.

Schnellstart

Statusprüfung (Nagios-Exit-Codes):

pss-metrics.py health
# OK: total=42 running=15 stopped=27 unhealthy=0 version=1.12.2.430d

Zabbix-LLD-Erkennung:

pss-metrics.py discover streams
pss-metrics.py discover inputs --running-only
pss-metrics.py discover outputs

Eine einzelne Metrik abrufen (für Zabbix UserParameter):

pss-metrics.py get summary.running
pss-metrics.py get stream.10031.bitrate
pss-metrics.py get input.10031.1.speed1
pss-metrics.py get output.10031.1.speed
pss-metrics.py get sysmon.cpu.self-usage
pss-metrics.py get server.server-version

Vollständiger Export:

pss-metrics.py dump --format=json
pss-metrics.py dump --format=prometheus
pss-metrics.py dump --format=influx
pss-metrics.py dump --format=zabbix-trapper --zabbix-host=streamer-01

Metrik-Pfade

pss-metrics get akzeptiert einen mit Punkten getrennten Pfad. Leere Ausgabe bedeutet „Wert fehlt“ (zum Beispiel existiert die Metrik nur für laufende Streams).

server.<attr>                например server.server-version, server.uptime
summary.<key>                total | running | stopped | unhealthy |
                             input_bitrate_kbps | output_bitrate_kbps
sysmon.cpu.<attr>            self-usage | total-usage | cores
sysmon.memory.<attr>         self-usage-kb | available-kb | total-kb
sysmon.netbw.<iface>.<attr>  rx-bw | tx-bw  (имя интерфейса как в XML)
stream.<id>.<attr>           любой атрибут <stream>
input.<sid>.<iid>.<attr>     любой атрибут <input>
output.<sid>.<oid>.<attr>    любой атрибут <output>

Nützliche Stream-Attribute (aus /data/stream/detail):

stream:  state, state-str, bitrate, thread-usage, mpts
input:   speed1, recv-bytes, recv-packets, recv-err,
         stat-disc, stat-disc1, stat-scrambled, stat-scrambled1,
         health-state-good, health-status, check-status
output:  speed, sent-bytes, sent-packets, sent-err, uri, type

Integration mit Zabbix

Zwei Szenarien werden unterstützt — wählen Sie das für Ihre Umgebung passende.

  1. Statischer UserParameter + LLD (Zabbix-Agent v1 / v2)

    Kopieren Sie userparameter_pss.conf.example nach /etc/zabbix/zabbix_agentd.d/pss.conf, starten Sie zabbix-agent neu und importieren Sie auf dem Server ein Template mit LLD-Prototypen, die die pss.discover-Schlüssel verwenden. Beispielbindungen:

    UserParameter=pss.discover[*],/opt/pss/monitoring/pss-metrics.py discover $1
    UserParameter=pss.get[*],/opt/pss/monitoring/pss-metrics.py get $1
    UserParameter=pss.health,/opt/pss/monitoring/pss-metrics.py health
    

    Auf dem Zabbix-Server:

    Ключ правила обнаружения:  pss.discover[streams]
    Ключи прототипов элементов: pss.get[input.{#STREAM_ID}.1.speed1]
                                pss.get[stream.{#STREAM_ID}.bitrate]
                                pss.get[summary.unhealthy]
    
  2. Trapper (Push) über zabbix_sender

    Per Timer (cron / systemd) ausführen und die Ausgabe in eine Pipe leiten:

    /opt/pss/monitoring/pss-metrics.py dump --format=zabbix-trapper \
        --zabbix-host="$(hostname)" \
      | zabbix_sender -z zabbix.example.com -i -
    

Integration mit Prometheus

Zwei Varianten.

  1. Textfile collector (empfohlen für One-Shot-Umgebungen).

    Periodischen Export per systemd-timer oder cron ausführen:

    */1 * * * * /opt/pss/monitoring/pss-metrics.py dump --format=prometheus \
        > /var/lib/node_exporter/textfile_collector/pss.prom.$$ \
        && mv /var/lib/node_exporter/textfile_collector/pss.prom.$$ \
              /var/lib/node_exporter/textfile_collector/pss.prom
    

    node_exporter stellt die Datei über –collector.textfile.directory bereit.

  2. Direkter Scrape über einen kleinen Wrapper (z. B. socat + pss-metrics dump) oder einen beliebigen HTTP-Proxy eines Drittanbieters.

Integration mit Telegraf / InfluxDB

Telegraf inputs.exec:

[[inputs.exec]]
  commands = ["/opt/pss/monitoring/pss-metrics.py dump --format=influx"]
  interval = "10s"
  timeout  = "5s"
  data_format = "influx"

Für den JSON-Parser verwenden Sie –format=json und konfigurieren data_format = „json“ mit Feldpfaden.

HTTPS und Authentifizierung

Wenn der PSS-Webserver hinter HTTPS läuft oder durch ein Passwort geschützt ist:

PSS_URL=https://streamer.example.com:8443 \
PSS_USER=monitor PSS_PASS=secret \
pss-metrics.py health

Selbstsignierte Zertifikate: setzen Sie PSS_INSECURE=1 (nicht empfohlen) oder geben Sie PSS_CA_BUNDLE=/path/to/ca.pem an.

Rückgabewerte

pss-metrics folgt der Nagios-Konvention:

0  OK
1  WARNING       (например, у запущенных потоков unhealthy)
2  CRITICAL      (PSS недоступен)
3  UNKNOWN       (неверные аргументы / внутренняя ошибка)

get und dump geben eine leere Zeile aus und beenden mit Code 0, wenn die angeforderte Entität fehlt — dies entspricht der Erwartung von Zabbix, dass ein leerer Wert als „NOT_SUPPORTED“ und nicht als Agent-Fehler interpretiert wird.

Diagnose

pss-metrics.py -v health        # логировать каждый HTTP-запрос в stderr
pss-metrics.py --cache-ttl=0   # обойти кеш при отладке
rm -rf /run/pss-metrics         # очистить кеш

Let’s Encrypt und certbot für HTTPS

Ab Version 1.9.2.340 unterstützt Perfect Streamer die automatische Erneuerung von Let’s-Encrypt-Zertifikaten für HTTPS in Web Server, HTTP Server und EPG Server.

certbot für RHEL einrichten.

Einschränkung:

  • Der TCP-Port 80 muss frei sein und es muss eine öffentliche IP mit Public-Domain-Name vergeben sein.

  • Alle HTTPS-Server nutzen denselben Hostnamen (Web Server, HTTP Server, EPG Server).

Installation von certbot (https://certbot.eff.org/instructions?ws=other&os=snap):

sudo yum install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap
sudo snap install certbot --classic

certbot konfigurieren:

sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot certonly --standalone

certbot-Prüfung:

sudo certbot renew --dry-run

certbot-Timer prüfen:

systemctl list-timers | grep certbot

In der Perfect-Streamer-Adminoberfläche HTTPS für Web Server, HTTP Server und EPG Server aktivieren.

Hook-Skript erstellen (https://pstreamer.tv/distrib/scripts/cert_update.zip) und es unter folgendem Pfad ablegen:

/opt/pss/scripts/cert_update.sh

Dort kann bei Bedarf der Hostname eingetragen werden; standardmäßig wird er aus /etc/hostname übernommen.

Datei ausführbar machen.

chmod +x /opt/pss/scripts/cert_update.sh

Skriptausführung prüfen, es sollten keine Fehler auftreten:

/opt/conf/scripts/cert_update.sh

Die HTTPS-Einstellungen sollten greifen; die Statusänderung wird in den Logs angezeigt.

Hook-Datei in certbot hinzufügen:

certbot renew --deploy-hook "/opt/conf/scripts/cert_update.sh"

certbot erneut prüfen:

sudo certbot renew --dry-run

certbot für Debian/Ubuntu einrichten.

Die Einrichtung unter Debian läuft analog zu RHEL; kurze Beschreibung am Beispiel Ubuntu 24.04.2 LTS.

certbot installieren:

apt install certbot
certbot certonly

Skript ausführbar machen:

chmod +x /opt/pss/scripts/cert_update.sh

Skript ausführen:

/opt/pss/scripts/cert_update.sh

Ausgabe:

Select domain name (your domain name)

Prüfen, ob die Zertifikate erneuert wurden:

ls -lat /opt/pss/config/cert/
total 44
-rw------- 1 root root  241 May 26 07:52 epgserver.key
-rw------- 1 root root  241 May 26 07:52 httpserver.key
-rw------- 1 root root  241 May 26 07:52 webserver.key
-rw-r--r-- 1 root root 1338 May 26 07:52 epgserver.crt
-rw-r--r-- 1 root root 1338 May 26 07:52 httpserver.crt
-rw-r--r-- 1 root root 1338 May 26 07:52 webserver.crt

Das Datum muss aktuell sein.

DVB-Adapter

Perfect Streamer unterstützt jeden im System installierten DVB-Adapter. Unterstützte Standards: DVB-S, DVB-S2, DVB-T, DVB-T2, DVB-C, ATSC. Zusätzlich implementiert: T2-MI-Dekapselung (ETSI TS 102 773) und BISS-1 / BISS-E-Entschlüsselung.

Die Hauptvoraussetzung ist ein korrekt installierter und funktionierender Adaptertreiber im System.

Der Bereich DVB erscheint nur, wenn im System gültige DVB-Adapter vorhanden sind. Eine Rekonfiguration zur Laufzeit wird nicht unterstützt; ein Neustart des Streamers ist erforderlich.

Adapteranbindung

Um einen neuen DVB-Adapter hinzuzufügen, wechseln Sie in den entsprechenden Abschnitt und fügen Sie den Adapter hinzu:

  • Adaptername festlegen.

  • Einen Adapter aus der Liste der im System verfügbaren auswählen.

  • Modus Stream wählen.

  • Den Typ des Übertragungssystems angeben: DVB-S, DVB-S2, DVB-T, DVB-T2, DVB-C.

  • Empfangsparameter angeben: Trägerfrequenz, Polarisation, Symbolrate, FEC, Modulation, DVB-Stream-ID, Oszillatorfrequenz, High-Band-Oszillator, High-Band-Grenze, DiSEqC-1.0-Modus sowie weitere typabhängige Parameter.

Optional kann die Aufzeichnung von EIT in die EPG-Datenbank aktiviert werden (EIT in EPG-DB schreiben).

Das Hinzufügen für jeden im System vorhandenen Adapter wiederholen.

DVB-Scan

Damit die Empfangsparameter (Frequenz, Polarisation, Symbolrate, FEC, Modulation) nicht manuell eingegeben werden müssen, enthält Perfect Streamer einen integrierten Transponder-Scanner. Der Scanner durchläuft die Transponder des ausgewählten Satelliten (DVB-S/S2) oder regionalen Bandes (DVB-C, DVB-T/T2), führt das Tuning und den Empfang jedes einzelnen durch, sammelt die PSI/SI-Tabellen (PAT, PMT, SDT) und erstellt eine abschließende Liste der Multiplexe mit ihren Programmen. Jeder gefundene Multiplex kann mit einer Schaltfläche zur DVB-Adapterliste hinzugefügt werden.

Der Scanner belegt den physischen Adapter vollständig; für den Start wird ein Adapter benötigt, der weder vom Betriebssystem-Kernel noch von einem aktiven DVB-Adaptereintrag in Perfect Streamer verwendet wird.

Свободные адаптеры

Beim Öffnen des Scan-Bildschirms in der Administrationsoberfläche wird eine Liste der physischen DVB-Adapter des Systems mit dem jeweiligen Belegungsstatus angezeigt:

  • free — der Adapter steht für das Scannen zur Verfügung.

  • kernel — das Gerät wird von einem anderen Betriebssystemprozess belegt.

  • pss-id-N — der Adapter wird bereits durch einen DVB-Adaptereintrag in Perfect Streamer mit der angegebenen Kennung verwendet. Solange dieser Eintrag aktiv ist, kann der Scanner darauf nicht gestartet werden. Um den Adapter vorübergehend freizugeben, muss der vorhandene DVB-Adaptereintrag pausiert werden (das Kennzeichen Pause in seinen Einstellungen).

Transponderlisten

Der Scanner orientiert sich an Referenzlisten im Enigma2-Format: der Satellitenliste satellites.xml und den regionalen Listen cables.xml / terrestrial.xml. Jede Datei enthält eine Reihe von Transpondern für eine bekannte Orbitalposition oder ein regionales DVB-T/C-Band (näheres auf der Projektseite oe-alliance-tuxbox-common).

Die Dateien befinden sich im Verzeichnis sat/ relativ zu pss.json (standardmäßig /etc/pss/sat/). Sie sind im Lieferumfang von Perfect Streamer enthalten und werden beim Öffnen des Scan-Bildschirms geladen. Bei Bedarf können sie durch Ersetzen der jeweiligen XML-Datei aktualisiert werden.

In der Administrationsoberfläche sind die Referenzlisten als drei Listen dargestellt:

  • Satellit — Orbitalpositionen (zum Beispiel Hot Bird 13.0°E, Astra 19.2°E).

  • Kabelregion — Land oder DVB-C-Anbieter.

  • Terrestrische Region — DVB-T/T2-Region.

Ist der benötigte Satellit oder die Region nicht in den Referenzlisten enthalten, kann das XML aktualisiert oder stattdessen der Blindscan verwendet werden (siehe unten).

Start

Im Scan-Dialog werden nacheinander folgende Angaben festgelegt:

  • Ein freier physischer Adapter.

  • Тип delivery system: DVB-S, DVB-S2, DVB-T, DVB-T2 или DVB-C.

  • Quelle:

    • für DVB-S/S2 — eine Orbitalposition aus der Satellitenliste und LNB-Parameter (Lokaloszillator-Frequenzen LO1 und LO2, Grenzfrequenz des oberen Bandes, DiSEqC-Port);

    • für DVB-C — eine Kabelregion;

    • für DVB-T/T2 — eine terrestrische Region.

Nach Drücken von Start wird der Scan im Hintergrund ausgeführt. Der Fortschritt wird in der Administrationsoberfläche angezeigt:

  • der Fortschritt in Prozent, bezogen auf die Anzahl der verarbeiteten Transponder;

  • die aktuelle Frequenz und Polarisation;

  • die Zähler Multiplexe gefunden und Programme gefunden;

  • ein Baum der bereits gefundenen Multiplexe, der bis zu den Programmen aufgeklappt werden kann.

Der Scanner ist eine streamerweite gemeinsame Ressource: Es läuft jeweils höchstens ein Scan gleichzeitig. Wird während eines laufenden Scans ein neuer gestartet, wird der vorherige automatisch abgebrochen. Die Schaltfläche Abbrechen bricht den Scan ab und leert die angesammelte Liste.

Die Scan-Dauer hängt von der Anzahl der Transponder in den ausgewählten Referenzlisten ab (typischerweise bis zu 5 Sekunden pro Transponder: bis zu 2 Sekunden für den Signal-Lock und bis zu 5 Sekunden für die Erfassung der PSI). Typische Werte:

  • DVB-S Hot Bird 13.0°E — etwa 2 Minuten (44 Transponder).

  • DVB-S Astra 19.2°E — etwa 1,5 Minuten.

  • DVB-T europäische Region — weniger als eine Minute.

Ergebnis

Das Scan-Ergebnis wird als Baum Multiplex → Programme angezeigt.

Multiplex-Parameter:

  • Frequenz, Polarisation, Symbolrate;

  • FEC, Modulation, Delivery System;

  • Transportstrom-Kennung (TSID);

  • die Frontend-Messwerte zum Zeitpunkt des Endes der PSI-Erfassung — SNR, Signal, BER;

  • die Zähler pmt-total / pmt-recv — wie viele PMT-Tabellen von der PAT angekündigt wurden und wie viele innerhalb des Timeouts tatsächlich erfasst wurden.

Параметры программы:

  • PNR (program_number) — die Service-Kennung innerhalb des Multiplexes;

  • Name und Anbieter — aus der SDT-Tabelle, in UTF-8;

  • scrambled — der Verschlüsselungs-Indikator. Seine Quelle wird in der folgenden Reihenfolge bestimmt: das Bit free_CA_mode aus der SDT (Deklaration des Broadcasters) → die Transport-Scrambling-Flags aus der PMT. Treffen weder SDT noch PMT innerhalb des Timeouts ein, ist der Standardwert 0 („unverschlüsselt“); der tatsächliche Zustand wird beim Empfangsversuch festgestellt;

  • video-pid, audio-pid, pcr-pid — die wichtigsten Elementarströme des Dienstes.

Anwendung des Ergebnisses

Der im Baum ausgewählte Multiplex wird mit einer einzigen Schaltfläche zur DVB-Adapterliste hinzugefügt. Es wird ein neuer Eintrag mit den Parametern aus dem Scan-Ergebnis (Frequenz, Polarisation, Symbolrate, FEC, Modulation, Delivery System) sowie den zu Beginn des Scans angegebenen LNB-Parametern und dem Paar adapter/device erstellt. Der Adaptername wird vom Benutzer festgelegt; zusätzliche Parameter (BISS-Schlüssel für verschlüsselte Kanäle, T2-MI, gemeinsam genutztes LNB usw.) werden nach dem Anlegen des Eintrags in dessen Einstellungen ergänzt.

Programme aus den gefundenen Multiplexen werden separat angewandt — durch Anlegen eines Streams (Stream) mit einer demuxer-Eingangsquelle, adressiert über die PNR (siehe Abschnitt Anbindung eines SPTS-Streams an einen DVB-Multiplex-Dienst).

Blindscan

Der Blindmodus wird verwendet, wenn:

  • der benötigte Satellit nicht in den Referenzlisten enthalten ist (nicht standardisierte Orbitalposition, lokaler Uplink);

  • die regionalen DVB-T/C-Referenzdaten unzureichend oder für einen bestimmten Standort veraltet sind;

  • ein Bandabschnitt unabhängig von der Liste bekannter Transponder erneut überprüft werden soll.

In diesem Modus greift der Scanner nicht auf die Referenzlisten zu, sondern erzeugt eine Liste der Transponder aus einem Frequenzraster. Standardmäßig werden die folgenden typischen Bereiche verwendet:

  • DVB-S/S2 Ku — 10700..12750 MHz, Schrittweite 4 MHz, beide Polarisationen (H und V), typische Symbolraten 22000 / 27500 / 30000 kSym/s.

  • DVB-C — 47000..862000 kHz, Schrittweite 8000 kHz, QAM-64 und QAM-256, typische Symbolraten 6875 / 6900 / 6952 kSym/s.

  • DVB-T/T2 — 174000..862000 kHz, Schrittweite 8000 kHz.

Ein vollständiger Blinddurchlauf des Ku-Bands dauert in der Größenordnung von 100 Minuten (mehrere tausend Abstimmpunkte). In der Praxis wird der Bereich in der Administrationsoberfläche manuell eingeschränkt — minimale/maximale Frequenz und Rasterschritt. Ein Durchlauf von 11700..11800 MHz mit 4 MHz Schritt für ein einzelnes LNB-Band dauert beispielsweise etwa 5 Minuten.

Das Ergebnisformat eines Blindscans ist mit dem eines normalen Scans identisch. Besonderheiten:

  • die Felder FEC und Modulation der gefundenen Multiplexe werden auf dem Wert AUTO festgesetzt — der Scanner ermittelt ihre genauen Werte nicht;

  • Das Delivery System entspricht dem angeforderten (DVB-S, DVB-S2, …). Für gemischte Netze wird empfohlen, zwei Durchläufe durchzuführen — DVB-S und DVB-S2 getrennt.

Das Anwenden eines Multiplexes aus einem Blindscan erfolgt auf dieselbe Weise wie aus einem normalen Scan — über die Schaltfläche zum Hinzufügen zur DVB-Adapterliste. Die Felder FEC und Modulation werden in der Regel auf AUTO belassen und bei Bedarf nach einem stabilen Signal-Lock auf dem jeweiligen Transponder verfeinert.

Größe des Kernel-Empfangspuffers

Der Parameter buffer-size (Ganzzahl, Standard 512) legt die Größe des Kernel-DVB-Demux-Ringpuffers in Blöcken zu 65536 Byte fest.

  • 512 (32 MB) — empfohlener Standardwert. Deckt Volltransponder-Szenarien DVB-S/S2 (>= 33 Mbit/s) mit einem oder mehreren MPTS-Verbrauchern ab. Ausgewählt anhand von Stand-Tests mit einem TBS-Adapter unter voller Transponderlast.

  • 8...64 (512 KB … 4 MB) — zulässig für eingebettete Systeme mit begrenztem RAM oder für Adapter im Scanner-/Femon-Modus mit geringem Datenverkehr.

  • 0 — Treiber-Standard beibehalten (in der Regel 8…32 KB). Geeignet nur für sehr gering belastete Szenarien. Bei Streams über 10 Mbit/s treten Verluste auf.

Wenn eine Meldung folgender Form im Protokoll erscheint:

DVB adapter X/Y dvr buffer overflow (NN so far, KK pids);
raise 'buffer-size' or reduce pid filter

buffer-size erhöhen oder die Anzahl der den Filter passierenden PIDs verringern (z. B. den MPTS-Ausgang weglassen, falls nicht benötigt).

Speicherbedarf: Wert N verbraucht N × 64 KB Kernel-Speicher pro Adapter. Bei vielen Adaptern (8 und mehr) ist dies zu berücksichtigen (8 × 32 MB = 256 MB).

SPTS-Stream an einen DVB-Multiplex-Dienst anschließen

Beim Hinzufügen eines neuen SPTS-Kanals zum input des Streams wählen Sie:

  • Typ: demuxer.

  • Quelle: DVB-Adapter.

  • Auf dem DVB-Adapter erstellter Multiplex, nach Adaptername.

  • PNR — wird aus der Popup-Liste der im Multiplex erkannten Dienste ausgewählt oder manuell eingegeben.

Zugriffsrechte für DVB-Geräte

Wenn DVB-Adapter in Perfect Streamer nicht angezeigt werden, gehen Sie wie folgt vor:

sudo nano /etc/udev/rules.d/99-dvb-permissions.rules
SUBSYSTEM=="dvb", GROUP="video", MODE="0660"

sudo usermod -aG video pss
sudo chown -R root:video /dev/dvb/*
sudo reboot

T2-MI-Dekapselung

T2-MI (T2-Modulator Interface, ETSI TS 102 773) ist ein Format für den Transport von DVB-T2-Streams über DVB-S2 multistream. Der äußere DVB-S/S2-Transponder trägt eine oder mehrere T2-MI-carrier-PIDs, von denen jede BBFRAMEs mit einem oder mehreren PLPs (Physical Layer Pipe) kapselt. Nach der Dekapselung wird aus dem BBFRAME der innere MPEG-TS mit Programmen und PSI/SI-Tabellen extrahiert.

Die Perfect-Streamer-Implementierung arbeitet im Multi-Carrier-Modus: ein einzelner physischer Adapter liefert gleichzeitig den äußeren DVB-S/S2-Multiplex und alle dekapselten T2-MI-Carrier (einen pro carrier-PID, der im PMT des äußeren Streams gefunden wurde).

Konfigurationsparameter

t2mi-mode (Int, 0..2, Standard 0) — Dekapselungsmodus:

  • 0 — Deaktiviert. Der äußere MPEG-TS wird unverändert weitergeleitet. Wenn ein T2-MI-Deskriptor (tag 0x51) im PMT erkannt wird, wird ein einmaliger Hinweis protokolliert.

  • 1 — Manuell. Die Dekapselung ist dauerhaft aktiviert. Wenn t2mi-pid ungleich 0 ist, wird beim Start ein carrier auf dieser PID vorab erstellt. Weitere carrier werden weiterhin automatisch über das PMT erkannt.

  • 2 — Auto. Carrier werden automatisch aus dem PMT des äußeren Multiplexes für alle ES erkannt, die wie T2-MI aussehen (Deskriptor 0x51 oder einzelnes ES mit stream_type=0x06 auf einem Dienst ohne andere A/V-ES). Werden keine carrier gefunden, arbeitet der Adapter als regulärer DVB-Multiplex.

t2mi-pid (Int, 0..8191, Standard 0) — PID für das Vorab-Erstellen eines carrier beim Start, vor Eintreffen des PMT:

  • 0 — keine Vorab-Erstellung. Carrier werden aus dem PMT erkannt (empfohlen für Auto-Modus 2).

  • 1..8191 — carrier auf dieser PID vorab erstellen. Zusätzliche im PMT gefundene T2-MI-ES erhalten dennoch eigene carrier.

Im Multi-Carrier-Modus ist der Parameter t2mi-pid kein Selektor für einen einzelnen carrier — jedes erkannte T2-MI-ES erhält einen eigenen carrier mit eigenem Dekapselator. Der Parameter ermöglicht eine frühe Initialisierung für eine bekannte PID.

t2mi-plp (Int, 0..255, Standard 0) — Kennung des PLP, das aus jedem T2-MI-carrier auf dem Adapter extrahiert wird. Wird auf alle carrier angewendet — eine Überschreibung pro carrier wird in der aktuellen Version nicht unterstützt. Wenn im Betrieb verschiedene carrier unterschiedliche PLPs tragen, sollte man:

  • ein für alle carrier gemeinsames PLP angeben, oder

  • separate Adapter für verschiedene PLPs mittels lnb-sharing konfigurieren.

Dies ist die Kennung des BBFRAME-Feldes plp_id, nicht der DVB-S2-multistream-ISI (der über den Parameter dvb-stream-id festgelegt wird). Es handelt sich um verschiedene Kennungen auf verschiedenen Ebenen.

Diagnose der PLP-Auswahl:

  • Fünf Sekunden nach dem Start eines carrier wird, falls für das konfigurierte PLP kein BBFrame empfangen wurde, aber andere PLPs zu sehen sind, eine Warnung mit der Liste der beobachteten plp_id protokolliert.

t2mi-tsid (Int, -1..255, Standard -1) — für zukünftige Nutzung reserviert. Selektor der T2-MI-Stream-Kennung, wenn mehrere T2-MI-Streams eine carrier-PID teilen. In der aktuellen Version ignoriert.

Zusammengesetzte PNR — SPTS-Anbindung aus T2-MI

Ein Adapter kann mehrere logische Multiplexe bereitstellen:

  • carrier-id = 0 — äußerer DVB-S/S2-Multiplex (reguläre A/V-Dienste).

  • carrier-id = 1..N — dekapselte T2-MI-carrier (einer pro äußerem T2-MI-ES).

BISS-Entschlüsselung

Die Entschlüsselung verschlüsselter DVB-Streams nach BISS-1 (Modus E1) und BISS-E (Modus E2) wird unterstützt. Anwendbar auf die Übertragungssysteme DVB-S, DVB-S2, DVB-T, DVB-T2.

Die Implementierung erlaubt es, mehrere Entschlüsseler gleichzeitig auf einem Adapter aktiv zu halten:

  • Nach PNR im äußeren Multiplex (regulärer Dienst).

  • Nach plp_id zur Entschlüsselung der T2-MI carrier-PID vor der Dekapselung (erforderlich für verschlüsselte multistream-Streams — andernfalls verwirft der Dekapselator jedes verschlüsselte Paket, siehe Zähler <t2mi scrambledDropped>).

EPG

EPG/XMLTV-Import

EPG-Daten werden aus verschiedenen Quellen in der EPG-Datenbank gesammelt:

  • EIT aus empfangenen Streams (SPTS und MPTS). Aktivierbar über Stream: Extract EIT to EPG Database.

  • Import in XMLTV format from different external sources. Set in Configuration/EPG/EPG Sources. Supported sources EPG in the form of a link to a web resource and a local file, with the full path specified.

Die EPG-Event-Aufbewahrungsdauer wird über den Parameter EPG storage period (days) gesetzt.

Auto-Clean-Datenbank — Programme ohne Events werden entfernt.

Im EPG-Bereich werden EPG-Quellen und zugehörige Daten angezeigt. Für jeden Kanal (EPG Channels List) lassen sich festlegen:

  • Channel Name — Name, der beim Export auf dem XMLTV-Server verwendet wird.

  • Time Zone — die Zeitzone kann korrigiert werden, falls beim Import keine Bindung an UTC erfolgte.

  • EPG Channel Sets — Kanal an ein Channel Set binden (siehe unten).

  • Icon — URL des Kanal-Icons (http://example.com/mychannel/myicon.png).

EIT-Generator

EIT data from EPG Database can be generated in SPTS Stream. To do this, set EPG Source ID and select EPG Channel ID in the Stream settings. In this case, SDT will be generated anyway, even if it is not in the source. Set the correct SDT Data.

Wird dieser Stream im Multiplexer eingesetzt, kann der Service Name separat in der output/muxer-Einstellung überschrieben werden.

EPG-Server (XMLTV)

Ein separater integrierter HTTP-Server in Perfect Streamer liefert das vollständige XMLTV für einen vorgegebenen Kanalsatz. Der Endpunkt ist für Middleware und Player gedacht, die das Programm lokal vorhalten und es selten aktualisieren — als ganze Datei, typischerweise ein- bis zweimal täglich.

Der Server und seine Clients werden unter Configuration/EPG/EPG Server konfiguriert.

URL und Authentifizierung

Der Dienst wird von einem separaten HTTP-Server epg-server bereitgestellt (nicht von dem für /data/*). Standardmäßig lauscht er auf den Ports 10444 (HTTP) und 10445 (HTTPS); Ports und SSL werden unter /config/epg-server konfiguriert.

Routen:

URL

Content-Type

Verhalten

GET /xmltv

text/xml

Bei Accept-Encoding: gzip wird die Antwort spontan komprimiert (Content-Encoding: gzip), sonst als unkomprimiertes XML ausgeliefert.

GET /xmltv.gz

application/octet-stream

Liefert stets einen Gzip-Stream mit Content-Disposition: inline; filename="xmltv.xml.gz" — praktisch zum Speichern als Datei.

Drei Authentifizierungsmethoden werden unterstützt:

  • HTTP Digest (bevorzugt) — Konto aus /config/epg-server/login.

  • URL-Parameter?l=<login>&p=<password> (Synonyme: login=…, password=…).

  • Loopback — eine Anfrage von 127.0.0.1 wird anonym behandelt. Praktisch für Skripte, die auf derselben Maschine laufen.

Warnung

Login und Passwort in der URL landen in den Access-Logs des Reverse-Proxys und im Browserverlauf. Für die öffentliche XMLTV-Verteilung verwenden Sie HTTP Digest oder lassen Sie Anfragen nur von privaten Adressen zu.

Zugriff per channel-set

Jedes epg-server/login-Konto ist an ein channel-set aus /config/epg-channel-set gebunden. Das EPG in der Antwort enthält nur die Kanäle des angegebenen Sets. So kann eine einzige PSS-Installation unterschiedlichen Betreibern/Middleware unterschiedliches XMLTV ausliefern.

Grundeinrichtung in der UI:

  1. Erstellen Sie unter Configuration/EPG/EPG Channel Sets eine Kanalgruppe und weisen Sie die gewünschten Kanäle bei den EPG-Quellen zu.

  2. Legen Sie unter Configuration/EPG/EPG Server Clients ein Konto an und binden Sie die erstellte Gruppe daran. Ohne Channel-Set-Bindung erhält der Client ein leeres XMLTV.

Zusätzliche Einschränkungen für einen Login:

  • ip-addr — wenn gesetzt und kein Platzhalter, erhält eine Anfrage von einer anderen IP 403 Forbidden.

  • limit-day — Unix-Epoche-Sek., nach der das Konto nicht mehr bedient wird (403 Forbidden). Praktisch für ein Abonnementmodell.

  • pause — einen Login vorübergehend deaktivieren, ohne ihn zu löschen.

Antwortformat

Der Antwortkörper ist ein XMLTV-Dokument mit der Wurzel <tv>. Die Struktur folgt dem gängigen XMLTV DTD-Schema:

<?xml version="1.0" encoding="utf-8"?>
<tv source-info-name="..." source-info-url="...">
  <channel id="ru.first">
    <display-name lang="ru">Первый</display-name>
    <icon src="https://.../first.png"/>
  </channel>
  ...
  <programme start="20260504060000 +0300"
             stop ="20260504070000 +0300"
             channel="ru.first">
    <title lang="ru">Утренние новости</title>
    <desc  lang="ru">Обзор событий за сутки</desc>
    <rating system="RU"><value>12+</value></rating>
  </programme>
  ...
</tv>

Hinweise zu Feldern:

  • Die Attribute source-info-name und source-info-url der <tv>-Wurzel werden aus den Feldern EPG Source Name und EPG Source URL unter Configuration/EPG/EPG Server gefüllt.

  • Die Attribute start und stop werden im Format YYYYMMDDhhmmss ±zone angegeben (die Zeitzone stammt aus dem Feld time_zone des Kanals).

  • Ein <programme> darf mehrere <title>/<desc> für verschiedene Sprachen enthalten. Das Attribut lang ist leer, wenn die Sprach-ID aus den EPG-Quelldaten nicht im Wörterbuch zugeordnet werden konnte (der Eintrag erscheint dennoch in der Ausgabe).

  • Kanäle mit einem konfliktbehafteten channel_id (wenn dieselbe ID aus mehreren Quellen kommt) werden einmal angezeigt, die übrigen Quellen werden mit einer Warnung im Serverlog übersprungen.

  • Nur Ereignisse mit stop_time >= now werden in die Ausgabe aufgenommen.

HTTP-Header

Der Server sendet immer:

Cache-Control: no-cache, no-store, must-revalidate
Pragma:        no-cache
Expires:       0
Connection:    close

Für /xmltv zusätzlich — Content-Encoding: gzip bei vorhandenem Accept-Encoding: gzip in der Anfrage. Für /xmltv.gzContent-Disposition: inline; filename="xmltv.xml.gz".

Das Verbot des clientseitigen Cachens ist beabsichtigt: XMLTV ändert sich bei jedem EIT-Import oder Refresh externer XMLTV-Quellen, und der Player darf veraltete Daten nicht unbegrenzt vorhalten. Ein Edge-Cache (nginx) ist hingegen voll akzeptabel — siehe Abschnitt zur Leistung weiter unten.

Server-Cache und sein Zurücksetzen

Das fertige XMLTV wird im Speicher des PSS-Prozesses gecacht:

  • Ein Eintrag pro channel-set; intern werden beide Körpervarianten (raw und gzip) vorgehalten — wiederholte Anfragen mit Accept-Encoding: gzip oder /xmltv.gz komprimieren die Daten nicht erneut.

  • Jeder Eintrag erhält einen update-time-Zähler. Jede EPG-Aktualisierung (EIT-Import, XMLTV-Quellen-Refresh) erhöht den Zähler, und der Cache wird bei der nächsten Anfrage neu aufgebaut.

Cache erzwungen leeren:

POST /xmltv/reset-cache

Die Route wird vom Admin-Server (Port 43971/43981) bedient, nicht vom epg-server. Der Anfragekörper ist leer; die Antwort ist 200 OK mit einem JSON-Umschlag.

HTTP-Antwortcodes

Code

Bedingung

200 OK

Anfrage verarbeitet. Der Körper ist ein XMLTV-Dokument (eventuell ein leeres <tv></tv> bei einem vorübergehenden DB-Fehler).

401 Unauthorized

Weder Digest noch l/p-Parameter haben die Prüfung bestanden (für nicht-Loopback-Anfragen).

403 Forbidden

Der Login existiert, aber die Anfrage kommt nicht von einer erlaubten IP, oder limit-day ist abgelaufen.

404 Not Found

Jede URL außer /xmltv und /xmltv.gz.

405 Method Not Allowed

Methode ist nicht GET.

Der Fehlerkörper ist ein JSON-Umschlag mit festem Format:

{"status": 401, "message": "Unauthorized"}

Leistung und Skalierung

Server-Cache

Der Server-Cache bedient wiederholte Anfragen an dasselbe channel-set ohne SQLite-Zugriff — durch Kopieren des fertigen Körpers.

Der XMLTV-Aufbau „von Grund auf“ (Cache-Miss) ist teurer: pro Kanal ein eigenes SELECT über channel_name, pro Ereignis eines über event_text und event_rating. Anhaltspunkte zur Bauzeit:

Ausgabegröße

Cache hit

Cache miss (build)

100 Kanäle / Tag

einige Dutzend ms

~0,5–1 s

500 Kanäle / Tag

~50 ms

2–5 s

1000+ Kanäle / Woche

~100–300 ms

5–15 s

Für die meiste Middleware ist es akzeptabel, XMLTV alle paar Stunden oder einmal täglich abzufragen.

Wann ein externer Reverse-Proxy (nginx) nötig ist

Im Gegensatz zu /data/epg/channel (kurze JSON-Antworten) ist XMLTV ein einziges großes Dokument pro channel-set und damit ideal für einen Edge-Cache:

  • Zehn bis Hunderte Clients pro channel-set — der interne PSS-Cache reicht meist aus, wenn sie XMLTV stündlich bis täglich abfragen.

  • Tausende gleichzeitige Clients — ein cachender Reverse-Proxy wird empfohlen. Das Ausliefern einer XMLTV-Datei an Hunderte/Tausende Anfragen ist in erster Linie eine Netzwerklast (Hunderte KB – einige MB pro Antwort), die man besser von PSS fernhält.

  • Geografisch verteilte Auslieferung — ohne CDN/Edge-Cache geht es nicht, unabhängig von der Clientzahl.

PSS sendet Cache-Control: no-cache, daher muss nginx explizit angewiesen werden, den Upstream-Header zu ignorieren und einen eigenen TTL zu führen.

Beispielkonfiguration für nginx

# /etc/nginx/conf.d/pss-xmltv.conf

proxy_cache_path /var/cache/nginx/pss-xmltv
                 levels=1:2
                 keys_zone=pss_xmltv:8m
                 max_size=4g
                 inactive=2h
                 use_temp_path=off;

upstream pss_epg {
    server 127.0.0.1:10444;
    keepalive 16;
}

server {
    listen 80;
    # listen 443 ssl http2;     # SSL termination разумно держать здесь
    server_name epg-files.example.com;

    # Не включаем gzip on: /xmltv.gz уже сжат, /xmltv получит
    # gzip-encoding от PSS, повторное сжатие бесполезно.

    location ~ ^/xmltv(\.gz)?$ {
        proxy_pass http://pss_epg;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # PSS отдаёт no-cache; кешируем на edge принудительно.
        proxy_ignore_headers Cache-Control Expires Set-Cookie;
        proxy_hide_header   Cache-Control;
        proxy_hide_header   Pragma;
        proxy_hide_header   Expires;

        # Ключ кеша = весь URL включая query (login/password в /xmltv?l=...&p=...)
        # дают разные ключи для разных учёток с разным channel-set.
        proxy_cache_key     "$scheme$host$request_uri";

        proxy_cache         pss_xmltv;
        proxy_cache_valid   200      30m;       # XMLTV меняется не часто
        proxy_cache_valid   401 403  1m;
        proxy_cache_lock           on;          # коалесцируем cache miss
        proxy_cache_lock_timeout   60s;         # build XMLTV может занимать секунды
        proxy_cache_use_stale      error timeout updating
                                   http_500 http_502 http_503;

        # Большой буфер: XMLTV для крупного channel-set может
        # достигать нескольких мегабайт.
        proxy_buffering      on;
        proxy_buffers        16 256k;
        proxy_buffer_size    256k;
        proxy_busy_buffers_size 1m;

        # Клиенту разрешим закешировать на короткий срок.
        add_header Cache-Control "public, max-age=600";
        add_header X-Cache-Status $upstream_cache_status always;
    }
}

Erläuterungen und Empfehlungen

  • TTL ``proxy_cache_valid 200 30m`` — XMLTV ändert sich selten häufiger als alle halbe Stunde. Erfolgt die Synchronisation mit den Quellen stündlich oder seltener, kann der Wert auf 1 Stunde und mehr angehoben werden; ist Frische nach POST /xmltv/reset-cache wichtig, senken Sie ihn.

  • ``proxy_cache_lock_timeout 60s`` — gegenüber /data/epg/channel erhöht (dort üblich sind 5 Sekunden), weil der Aufbau eines XMLTV für ein großes channel-set länger dauert.

  • Eine dedizierte ``keys_zone`` — selbst bei einer großen Installation sind eindeutige XMLTV-Schlüssel rar (Anzahl Logins × channel-set), 8 MB reichen mit Reserve. max_size wird nach dem XMLTV-Volumen, nicht nach der Schlüsselanzahl bemessen.

  • gzip auf nginx-Seite ist unnötig: Für /xmltv.gz ist die Antwort bereits komprimiert, für /xmltv antwortet PSS selbst gzip-encoded bei vorhandenem Accept-Encoding: gzip.

  • HTTPS-Terminierung auf nginx liefert bessere Leistung bei vielen gleichzeitigen TLS-Handshakes.

Verwandte Endpunkte

  • POST /xmltv/reset-cache — erzwungenes Leeren des serverseitigen XMLTV-Caches (auf dem Admin-Server 43971/43981).

  • POST /data/epg/update?s=<src_id> — erzwungene Aktualisierung einer externen XMLTV-Quelle; nach einer erfolgreichen Aktualisierung wird der serverseitige XMLTV-Cache automatisch geleert.

  • GET /data/epg/channel?… — JSON-EPG-Ausgabe für einen Kanal pro Tag; siehe separaten Abschnitt.

Die vollständige Liste und ausführliche Beschreibung der HTTP-API finden Sie in manual/http_data_api.txt.

EPG für OTT-Middleware

Der Server liefert Programmdaten (EPG) für den gewählten Tag und einen einzigen Kanal im JSON-Format. Der Endpunkt ist für OTT-Middleware-Backends gedacht, die den Programmplan aus Perfect Streamer aggregieren, um das Programm beim Endkunden aufzubauen.

URL und Authentifizierung

Der Endpunkt wird vom integrierten Admin-Server bereitgestellt. Standardmäßig ist er unter den Ports 43971 (HTTP) und 43981 (HTTPS) erreichbar; die Ports werden unter Settings/Server Settings konfiguriert.

GET /data/epg/channel?src=<src_id>&ch=<channel_id>&lang=<lang>&t=<time>

Die Authentifizierung erfolgt per HTTP Digest, wie bei den übrigen /data/*. Für Middleware reicht ein Konto mit der Rolle viewer (nur lesen).

Bemerkung

Anfragen von der Loopback-Adresse (127.0.0.1) umgehen die HTTP-Digest-Prüfung — der Server behandelt sie als anonym. Das ist praktisch für lokale Skripte und Health-Checks von Middleware, die auf derselben Maschine wie Perfect Streamer läuft; für entfernte Zugriffe sind Zugangsdaten zwingend.

Anfrageparameter

Parameter

Typ

Pflicht

Standard

Beschreibung

src

vorzeichenlose Ganzzahl

nein

0

EPG-Quelle. 0 — aus MPEG-TS-EIT der Eingangsströme importierte Daten. 1, 2, — Eintrags-ID aus /config/epg/epg-source (externe XMLTV-Quelle).

ch

Zeichenkette

ja

Kanal-Kennung aus der EPG-Datenbank: Wert des Feldes channel_id in der Tabelle channel. Die Liste der verfügbaren Kennungen lässt sich per SQL-Abfrage über POST /data/epg/sql ermitteln.

lang

Ganzzahl oder ISO 639

nein

Systemstandardsprache

0 — Systemstandardsprache; eine Ganzzahl > 0 — interne Sprach-ID (siehe GET /schema/lang); eine Zeichenkette — zwei- oder dreibuchstabiger ISO-639-Code, z. B. eng, rus, fra.

t

vorzeichenlose Ganzzahl (Unix-Epoche, Sek.)

nein

aktuelle Serverzeit

Beliebiger Zeitpunkt innerhalb des interessierenden Tages. Der Server liefert Ereignisse für den UTC-Tag, zu dem t gehört: Intervall [t / 86400 · 86400, (t / 86400 + 1) · 86400). Für Daten des «nächsten Tages» reicht es, 86400 zur aktuellen Zeit zu addieren.

Bemerkung

Der Tag wird in UTC gerechnet, nicht in der lokalen Zeitzone. Baut die Middleware den Zeitplan nach dem lokalen Kalendertag auf, fällt die UTC-Tagesgrenze nicht zwingend auf die lokale Mitternacht; in diesem Fall sind zwei Anfragen (für zwei benachbarte UTC-Tage) nötig, deren Ergebnisse über das Feld start zusammengeführt werden.

Antwortformat

  • Content-Type: application/json.

  • Die HTTP-Header verbieten das Caching auf der Client-Seite und auf zwischengeschalteten Proxys:

    Cache-Control: no-cache, no-store, must-revalidate
    Pragma: no-cache
    Expires: 0
    
  • Der Antwortkörper ist ein JSON mit der Ereignisliste für den Tag:

{
  "event": [
    {"start": 1715000000, "end": 1715003400, "title": "Утренние новости", "desc": "Обзор событий за сутки"},
    {"start": 1715003400, "end": 1715007000, "title": "Прогноз погоды",   "desc": ""}
  ]
}

Ereignisfelder:

  • start, end — Anfang und Ende der Sendung in Unix-Epoche (Sek.), UTC.

  • title — Sendungstitel in der gewählten Sprache. Fehlt ein Titel in der angeforderten Sprache, greift der Server auf den Eintrag in der Systemstandardsprache zurück und danach auf jede andere verfügbare Sprache.

  • desc — erweiterte Beschreibung. Kann ein leerer String sein, wenn die Datenbank keine separate Beschreibung für das Ereignis enthielt.

Besonderheiten der Ausgabe:

  • Ereignisse mit leerem Titel und ohne Beschreibung sowie Ereignisse mit ungültigen Zeitstempeln werden aus der Ausgabe ausgeschlossen.

  • Duplikate nach start werden ausgesondert: Für denselben Startzeitpunkt wird ein Datensatz mit der besten Sprachpriorität zurückgegeben (angefordert → System-Default → andere).

  • Die Reihenfolge der Ereignisse im Array ist nicht garantiert — bei Bedarf sortiert die Middleware die Liste selbst nach dem Feld start.

  • Wenn der Kanal nicht gefunden wird, die Quelle nicht existiert oder am gewählten Tag keine Ereignisse vorliegen, gibt der Server 200 OK mit dem leeren Array {"event":[]} zurück — oder, im seltenen Fall einer fehlenden Quelle, mit leerem Körper. Die Middleware muss beide Varianten korrekt behandeln.

Caching auf dem Server

Das fertige JSON wird vom Server unter dem Schlüssel (channel_id, UTC-Datum, Sprache) gecacht; wiederholte Anfragen für denselben Tag und Kanal werden daher ohne Datenbankzugriff bedient. Die Middleware muss am Cache nichts steuern.

Der Cache wird automatisch zurückgesetzt:

  • beim Eintreffen neuer Ereignisse aus MPEG-TS-EIT der Eingangsströme (src=0);

  • bei einer erfolgreichen Aktualisierung einer externen XMLTV-Quelle (src > 0 — geplant oder erzwungen über POST /data/epg/update?s=<src_id>);

  • wenn ein Tag aus dem EPG-Aufbewahrungsfenster fällt.

Ein separater Endpunkt zum erzwungenen Leeren des Caches ist weder vorgesehen noch erforderlich.

HTTP-Antwortcodes

Code

Bedingung

200 OK

Anfrage verarbeitet. Der Körper ist ein JSON mit der Ereignisliste (eventuell leer).

400 Bad Request

Der Parameter ch fehlt oder ist leer; oder src, t lassen sich nicht als vorzeichenlose Ganzzahl parsen; oder ein numerischer lang verweist auf eine nicht existierende Sprach-ID.

401 Unauthorized

Die HTTP-Digest-Authentifizierung fehlt oder ist ungültig (für Anfragen nicht von einer Loopback-Adresse).

Sonstige Situationen (unbekanntes src, fehlender Kanal, keine Ereignisse am Tag) führen nicht zu 4xx — die Middleware erhält 200 OK mit dem leeren Array {"event":[]}.

Bei einem Fehler ist der Antwortkörper ein JSON-Umschlag mit festem Format:

{"status": 400, "message": "Bad Request"}

Das Feld status dupliziert den HTTP-Code; das Feld message enthält eine konkretere Fehlerursache auf Englisch (oder den Standard-HTTP-Statustext, falls keine weiteren Informationen vorliegen). Der Content-Type der Fehlerantwort ist application/json.

Beispiel

curl -u middleware:secret --digest \
  'http://pss.example.com:43971/data/epg/channel?src=0&ch=12.0.1&lang=rus&t=1715000000'

Beispielantwort:

{
  "event": [
    {"start": 1715000000, "end": 1715003400, "title": "Утренние новости", "desc": "Обзор событий за сутки"},
    {"start": 1715003400, "end": 1715007000, "title": "Прогноз погоды",   "desc": ""}
  ]
}

Leistung und Skalierung

Perfect-Streamer-Server-Cache

Im PSS-Prozess gibt es einen In-Memory-LRU-Cache der Antworten mit dem Schlüssel (channel_id, UTC-Datum, Sprache) und einem Hard-Cap von 1024 Einträgen je EPG-Quelle. Bei typischer Last (zig bis hunderte Kanäle × 1–3 Sprachen × keep-day Tage) passen alle aktuellen Einträge vollständig in den Cache; wiederholte Anfragen werden ohne SQLite-Zugriff bedient.

Größenordnung (Debug-Build, lokales Loopback, ohne HTTPS):

Szenario

Latenz (Einzelanfrage)

Durchsatz (P=8)

Cache hit

~0,3 ms

~1100 Anfragen/s

Cache miss (SQL + JSON)

~1,0–1,5 ms

~1000 Anfragen/s

In einem Release-Build und ohne Debug-Logging sind die Werte etwa 2- bis 3-mal besser. Bandbreite — etwa 14 KB pro Antwort für einen typischen Kanal pro Tag.

Wann ein externer Reverse-Proxy (nginx) nötig ist

Der Server-Cache beschleunigt wiederholte Anfragen für dasselbe (channel, Tag, Sprache), aber jede Anfrage geht weiterhin durch den eingebauten PSS-HTTP-Server und belegt einen Thread aus dessen Pool. Bei vielen Clients ist es sinnvoll, das Caching an den Rand zu verlagern:

  • bis ~1.000 Online-Clients — der interne Cache reicht meist aus, ein Reverse-Proxy ist nicht erforderlich.

  • Zehntausende und mehr — ein cachender Reverse-Proxy (z. B. nginx) wird empfohlen. Ein Edge-Cache wickelt 99 % der Anfragen ohne PSS ab, dämpft Spitzen (Middleware-Start, massenhafte Player-Aktualisierung) und erlaubt es, die SSL-Terminierung auf einen separaten Knoten zu verlagern.

  • geografisch verteilte Auslieferung — ein externes CDN/Proxy ist nötig, noch bevor die Clientzahl gezählt wird.

PSS sendet einen eigenen Header Cache-Control: no-cache, no-store, must-revalidate, damit Endclients das EPG nicht lange zwischenspeichern. Der Reverse-Proxy darf (und sollte) die Antwort selbst cachen — unten wird gezeigt, wie man nginx explizit anweist, den Upstream-Cache-Control zu ignorieren und einen eigenen TTL zu führen.

Beispielkonfiguration für nginx

Eine minimale Konfiguration für einen EPG-Edge-Cache, ausgelegt für Zehntausende Clients mit Polling-Intervall 1–5 Minuten:

# /etc/nginx/conf.d/pss-epg.conf

proxy_cache_path /var/cache/nginx/pss-epg
                 levels=1:2
                 keys_zone=pss_epg:32m
                 max_size=2g
                 inactive=30m
                 use_temp_path=off;

upstream pss_admin {
    server 127.0.0.1:43971;
    keepalive 64;
}

server {
    listen 80;
    # listen 443 ssl http2;  # рекомендовано: SSL termination здесь
    server_name epg.example.com;

    # gzip помогает: типовой EPG-JSON жмётся ~5–8x.
    gzip on;
    gzip_types application/json;
    gzip_min_length 512;
    gzip_proxied any;

    location = /data/epg/channel {
        proxy_pass http://pss_admin;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # PSS отдаёт no-cache; кешируем на edge принудительно.
        proxy_ignore_headers Cache-Control Expires Set-Cookie;
        proxy_hide_header   Cache-Control;
        proxy_hide_header   Pragma;
        proxy_hide_header   Expires;

        # Ключ кеша = весь URL с query string. Параметры src/ch/lang/t
        # уже определяют уникальность ответа.
        proxy_cache_key     "$scheme$host$request_uri";

        proxy_cache         pss_epg;
        proxy_cache_valid   200 60s;          # время устаревания
        proxy_cache_valid   400 404 10s;
        proxy_cache_lock           on;        # коалесцируем cache miss
        proxy_cache_lock_timeout   5s;
        proxy_cache_use_stale      error timeout updating
                                   http_500 http_502 http_503;

        # Отдадим клиенту результат в JSON, но с собственным TTL
        # (плеер пересмотрит EPG не раньше этого срока).
        add_header Cache-Control "public, max-age=60";
        add_header X-Cache-Status $upstream_cache_status always;
    }
}

Erläuterungen und Empfehlungen

  • TTL ``proxy_cache_valid 200 60s`` — Kompromiss zwischen EPG-Frische und Last auf dem Upstream. Das Programm ändert sich nicht in Echtzeit, daher sind 30–300 Sekunden angemessen. Nach dem Import neuer Ereignisse leert PSS seinen Cache sofort, der Edge-Cache zieht beim nächsten TTL nach.

  • ``proxy_cache_lock on`` ist bei vielen Clients zwingend: Bei einem Cache-Miss bündelt es parallele Anfragen auf denselben Schlüssel zu einer einzigen Upstream-Anfrage und schützt SQLite vor Spitzen-BUSY unter Last.

  • ``keys_zone`` und ``max_size`` werden anhand der Anzahl (Kanal × Tag × Sprache) dimensioniert: 32 MB keys_zone reichen für Hunderttausende Schlüssel; 2 GB max_size decken einen Monat Verlauf für Hunderte Kanäle mit Reserve ab.

  • gzip reduziert den Verkehr deutlich: Antworten lassen sich gut komprimieren (sich wiederholende JSON-Schlüssel, Kyrillisch in UTF-8).

  • ``X-Cache-Status`` in der Antwort erlaubt der Middleware, HIT/MISS/EXPIRED zu sehen und die Effektivität des Caches zu beurteilen.

  • Liegen nginx und PSS auf derselben Maschine, verlangt der Admin-Server für Loopback keine HTTP-Digest-Authentifizierung, daher kann der Upstream-Block ohne proxy_set_header Authorization bleiben. Bei einer Trennung über Netze legen Sie ein dediziertes viewer-Konto an und ergänzen Sie die Digest-Authentifizierung in proxy_pass.

  • HTTPS wird sinnvollerweise an nginx terminiert: PSS unterstützt HTTPS direkt, aber ein Edge-Server ist meist effizienter bei der Abwicklung von TLS-Handshakes für Tausende gleichzeitige Clients.

Verwandte Endpunkte

  • POST /data/epg/sql?s=<src_id> — beliebige SQL-Abfrage an die EPG-Datenbank (insbesondere, um eine Liste der channel_id zu erhalten).

  • POST /data/epg/update?s=<src_id> — erzwungene Aktualisierung einer externen XMLTV-Quelle.

Die vollständige Liste und ausführliche Beschreibung der HTTP-API finden Sie in manual/http_data_api.txt.

Programmoptimierung

Treten bei vielen streams Probleme mit hoher CPU-Last oder Speichermangel auf, können die Einstellungen optimiert werden.

You can disable the MPEG-TS filtering and processing features if you don’t need to.By default, the stream has the Clean All Unnecessary Data function enabled, disable it if there is no unwanted data in the stream. Disabling these features completely will remove the Original Media Information section of the Report.

Vollständige Deaktivierung oder Änderung der Mosaic-Einstellungen. Eine vollständige Deaktivierung erfolgt in den Server-Einstellungen. Sie können sie individuell für jeden stream deaktivieren oder das Aktualisierungsintervall mit der Einstellung Check Interval ändern.

Queue-Overload-Fehler für die Datenbanken DBStat und DBEPG

Treten auf, wenn die Datenbankleistung nicht ausreicht — langsame Festplatte oder überlastetes System.

Den Speicherort der Datenbanken legt der Parameter data-dir in der Konfigurationsdatei pss.properties fest

Mögliche Lösungen:

  1. Verschieben der Datenbankdateien nach /tmp. Es wird der Systemspeicher verwendet — eine Abschätzung des verfügbaren Speichers und Anpassung der Statistik-Aufbewahrungsdauer ist erforderlich (siehe Server-Einstellungen). Bei einem System-Neustart gehen die Daten verloren.

  2. Detaillierungsgrad der Statistik reduzieren — siehe Parameter dbstat-detail. Standard 5 s, lässt sich bis 20 erhöhen.

  3. Die EPG-Datenbank im Arbeitsspeicher halten — Parameter dbepg-memory=true setzen.

Transkoder

Die Transkoder sind als eigenständige Binärdateien implementiert, die von pstreamer als separate Prozesse gestartet werden.

1-zu-N-Konfigurationen werden unterstützt — von einem Decoder können mehrere Streams mit unterschiedlichen Encoder-Einstellungen erzeugt werden.

Der Quellstream muss Video und Audio enthalten; Varianten ohne Video oder ohne Ton werden nicht unterstützt.

Implementierte Codecs:

  • Video SW decoder: mpeg2, h.264, hevc (h.265)

  • Video NW decoder: mpeg2, h.264, hevc (h.265)

  • Video SW encoder: mpeg2, h.264, hevc (h.265)

  • Video NW encoder: h.264, hevc (h.265)

Interlaced Streams werden am Eingang und Ausgang unterstützt.

Für H.264- und HEVC-Decoder wird Interlace Alternate (zwei getrennte Halbbilder im Stream) unterstützt; es wird in Interlace Interleaved umgewandelt.

Der HEVC-Decoder unterstützt das Profil Main10 mit bt.709 (SDR) und bt.2020 (HDR). Der HEVC-Encoder nutzt stets das Profil Main mit bt.709.

Für die H.264- und HEVC-Decoder wird VBR (Variable Frame Rate) unterstützt; es wird in eine konstante Framerate umgewandelt.

  • Audio decoder - mpeg (layer 1,2,3), aac, ac3

  • Audio encoder - mpeg (layer 2), aac

Es gibt den Transkodierungsmodus Video Passthrough — Video wird nicht transkodiert, nur der Ton; verwendet wird der SW-Transkoder.

Bemerkung

Für die Transkodierung müssen zwei oder mehr Streams konfiguriert werden — mit output (Decoder) und input (Encoder).

Zur Konfiguration einer Transkoder-Instanz ist nötig:

  • Quelle — im Stream-Output-Transkoder (Decoder) hinzufügen. In den Einstellungen Typ wählen: SW, NV oder Video Passthrough.

  • Ausgangsstream — im Stream-Input-Transkoder (Encoder) hinzufügen; in den Einstellungen die Quelle (Decoder) wählen.

  • Wiederholen, wenn mehrere Ausgangsstreams für einen Decoder benötigt werden.

Einstellungen des Output-Transkoders (Decoder)

  • Convert colors to BT.709 — Konvertierung von SD BT.470-2 (PAL) und SMPTE 170M (NTSC) nach BT.709

  • Trace — für die Diagnose das detaillierte Transkoder-Log aktivieren.

Für den korrekten Betrieb des Transkoders muss der Quellstream bestimmte Anforderungen erfüllen; in einigen Fällen lässt sich das korrigieren. Diese Einstellungen konvertieren den Stream nicht — sie wirken als Hinweise für den korrekten Betrieb des Transkoders.

Für die Korrektur der Eingangsdaten gibt es folgende Einstellungen:

  • Fix PAR — Pixel Aspect Ratio korrigieren. Wird als Bruchzahl im Format N/D angegeben; für Wide SD z. B. 16/9.

  • Fix Framerate — Framerate explizit angeben. In manchen Streams kann die Framerate im SPS fehlen, im Transkoder-Log erscheint dann der entsprechende Fehler. In diesen Fällen ist die Framerate manuell anzugeben. Wird als Bruch im Format N/D angegeben.

Beispiele für Framerate-Werte:

  • PAL - 25/1

  • NTSC — 30/1 oder 30000/1001

  • Cinema — 24/1 oder 24000/1001

Einstellungen des Input-Transkoders (Encoder)

  • Encoder Type — Video-Codec.

  • Align Total Bitrate — Stuffing-Bitrate des Streams (Auffüllen mit null-Paketen). Wichtig, wenn der Stream für DVB-Übertragung genutzt wird. Die Bitrate muss garantiert höher sein als die Bitrate von Video und allen Audio-Spuren.

  • Video Profile — für H.264 lässt sich das Kodierungsprofil wählen.

  • Video Bitrate — Bitrate des Videostreams in kbps. Die Kodierung läuft stets in CBR; die Gesamtbitrate ist durch die Tonspuren höher.

  • Speed Preset — Voreinstellungen für die Kodierung, Werte 1–7. Niedriger = höhere Qualität und höherer Ressourcenbedarf. Standard 4.

  • GOP Interval — Intervall in Frames für die GOP (entspricht dem Key Frame Interval). Standard 25 (1 Sekunde bei 25p); empfohlen, wenn Player zufällig einsteigen.

  • BFrame — für höhere Qualität aktivieren. Empfohlener Wert: 3.

  • Lookahead — für höhere Qualität aktivieren. Empfohlen: 20–50 Frames.

  • Resize — Bildgrößenänderung.

  • Deinterlace — wandelt Interlace in Progressive um.

Einfügen eines crop (leere Ränder am Bild) wird nicht unterstützt. Beliebige Bildgrößen werden nicht zugelassen, da Seitenverhältnisse verzerrt würden.

Für resize stehen folgende Optionen zur Verfügung:

  • Größe proportional um Faktor 2 und 4 verkleinern.

  • Format Wide SD 16:9 setzen, der passende Aspect Ratio wird gewählt.

  • Upscale SD→HD. Wird auf SD-PAL/NTSC-Quellen angewandt. Interlace wird nicht unterstützt — bei Bedarf vorher deinterlacen.

  • Breite festlegen. Die Höhe wird proportional berechnet.

  • Höhe festlegen. Die Breite wird proportional berechnet.

Einige Parameter können mit dem gewählten Transkoder unverträglich sein; Fehler erscheinen in dessen Log.

Audioverarbeitung

Standardmäßig werden alle Tonspuren ohne Verarbeitung von Input zu Output durchgereicht. Unnötige Spuren lassen sich über PID-Filter im Stream entfernen.

Wenn der Ton transkodiert werden soll, lässt sich das über Regeln pro Audio-Codec konfigurieren. Option skip — Tonspur mit diesem Codec entfernen.

Fehlen im Ausgangsstream Tonspuren, kommt es zu einem Fehler — siehe Transkoder-Logs.

PCR-Erzeugung und TR 101 290.

Der MPEG-TS-Multiplexer erzeugt einen neuen PCR. Bei korrekt gesetztem Align Total Bitrate (über der Summe aus Video- und Audiobitrate) sollte der PCR die TR-101-290-Prüfung bestehen.

Status der Transkoder

Bei Problemen im Transkoder-Betrieb (kein Stream vom Encoder) sind die Logs im Bereich Transcoders zu prüfen — dort ist die Liste der Instanzen zu sehen (jede Zeile ist eine separate Instanz, decoder + N encoders); beim Klick auf eine Instanz öffnet sich der Log-Status-Dialog. Angezeigt werden das aktuelle Log und das Log des vorherigen Starts. Für ein detailliertes Log aktivieren Sie trace in den output (decoder)-Einstellungen.