DVR / Archives¶
Depuis la version 1.13, Perfect Streamer intègre un DVR — une archive flux persistante sur disque, fonctionnant en parallèle avec la diffusion OTT normale (HLS / DASH). L’archive est écrite automatiquement, sans processus séparé, et lue via les mêmes URLs OTT que le live — seule différence : le paramètre query.
Fonctionnalités :
Enregistrement de chaque flux OTT dans l’archive sur le stockage choisi.
Lecture HLS, DASH et Low-Latency HLS de l’archive (VOD) sur les mêmes URL que le live (DASH et LL-HLS — sur CMAF, en OTT/HLS/LL-HLS/LL-Dash).
Sous-titres (WebVTT) — écrits avec les chunks TS.
Plusieurs stockages — un flux est lié à un seul ; différents flux peuvent écrire sur différents disques.
Nettoyage automatique par temps de rétention et utilisation disque.
EPG-aligned VOD — archive par référence à un événement EPG.
VOD adaptatif — pris en charge pour les groupes adaptatifs.
Le DVR ne requiert pas de licence séparée. Activé par flux en ajoutant une liaison stockage.
Le DVR ne remplace pas la diffusion live. Si un flux possède une archive, le client reçoit une playlist live au comportement identique à celui sans DVR. L’archive ne commence à se lire que lorsque le client demande explicitement le mode VOD via un paramètre de requête de l’URL (voir ci-dessous).
Configuration du stockage¶
Un stockage est un enregistrement dans la section Configuration / DVR Storage. Chaque enregistrement décrit un répertoire sur disque où PSS écrit les fichiers d’archive. Un flux utilise un stockage.
À l’ajout d’un stockage, on configure :
Name — nom affiché.
Dir Path — chemin du répertoire sur disque. Après création, le chemin n’est pas modifiable — pour déplacer l’archive, supprimer l’enregistrement et en créer un nouveau. Les fichiers existants ne sont pas touchés sur disque à la suppression.
Max Usage, % — seuil d’utilisation disque (par défaut 90 %). Au-dessus, le nettoyage size-based démarre (voir ci-dessous). Min 1 %, max 100 %.
Cleanup Interval, sec — période de la tâche de nettoyage (par défaut 10 sec). À chaque tick, on coupe d’abord tout ce qui dépasse la profondeur de rétention ; puis, si Max Usage est dépassé, les anciens chunks.
Disk Pressure Grace, sec — durée pendant laquelle Used % doit dépasser Max Usage en continu avant le Size-based cleanup (par défaut 60 sec). Filtre les pics courts.
Disk Pressure Cut, sec — limite haute par tick de nettoyage : secondes vidéo par flux supprimables d’un coup (par défaut 300 sec). Le reste passe au tick suivant.
Disk Emergency Bytes — seuil d’espace libre sous lequel le stockage passe en Error et l’enregistrement s’arrête (par défaut 2 GiB). Reprise auto si espace libre ≥ 2 × cette valeur.
Alarm Disk-Full Hysteresis, % — la marge sous Max Usage jusqu’à laquelle le nettoyage basé sur la taille abaisse le remplissage, afin que Used % ne fluctue pas juste au niveau du seuil (2 % par défaut).
La plupart des valeurs par défaut conviennent aux installations courantes ; seul Max Usage et Dir Path demandent généralement un ajustement.
Il est judicieux de créer un stockage par disque. Si plusieurs enregistrements avec des sous-répertoires différents sont définis sur le même disque, ils se disputent l’espace libre — le disque est partagé, mais le nettoyage est propre à chaque stockage.
Liaison d’un flux à un stockage¶
Dans les paramètres Stream / OTT apparaît une section DVR :
Storage — liste déroulante des stockages ; 0 signifie « archive désactivée pour ce flux ».
Storage Hours — profondeur d’archive de ce flux, en heures, de 1 à 2160 (jusqu’à 90 jours). Les chunks plus anciens que cette valeur sont supprimés à chaque tick de la tâche de nettoyage (Rolling cleanup).
Storage Min Hour — seuil de protection bas (heures). Le nettoyage ne supprime jamais de chunks plus récents, même sous pression Max Usage. Utile si la logique métier exige un enregistrement récent garanti, ex. « les 2 dernières heures toujours présentes ».
Modification de Storage à la volée :
mettre 0 — désactive l’archive ; les chunks sur disque sont conservés, plus rien n’est écrit. Les sessions VOD renvoient 404 ;
choix d’un autre stockage — le flux se détache de l’ancien et écrit dans le nouveau. Les fichiers de l’ancien disque ne sont pas migrés.
Les modifications de Storage Hours et Storage Min Hour s’appliquent aussitôt — au tick suivant, le nettoyage utilise la nouvelle valeur.
Après configuration, le flux écrit automatiquement l’archive dès qu’il passe en Running.
VOD : lecture de l’archive¶
L’archive est lue via les mêmes URLs que le live HLS / DASH (voir section OTT service) — seul le paramètre query change.
URLs et paramètres¶
URL pour HLS, DASH et Low-Latency HLS (DASH et LL-HLS — sur CMAF, nécessitent le mode OTT/HLS/LL-HLS/LL-Dash) :
Sans paramètre query — live ordinaire à fenêtre glissante. Avec le paramètre t — mode VOD.
Paramètre |
Rôle |
|---|---|
|
Heure de début VOD (Unix epoch, sec). t=0 — depuis le début de l’archive. La présence de t (même t=0) active le mode VOD. |
|
Durée de la fenêtre VOD, sec. d=0 ou paramètre absent — « jusqu’à maintenant ». N’a de sens qu’avec t. |
|
EPG-aligned VOD : le serveur localise l’événement EPG actif au moment indiqué et prend ses start et duration comme bornes. Incompatible avec t et d (remplacement côté serveur). Voir ci-dessous. |
|
Paramètres live standard (voir OTT service) ; |
Comportement selon t et d :
t |
d |
Fenêtre |
Condition 404 |
|---|---|---|---|
aucun |
— |
live (fenêtre glissante) |
— |
0 |
aucun / 0 |
[début archive, maintenant] |
DVR non lié |
0 |
> 0 |
[début archive, +d] |
DVR non lié |
> 0 |
aucun / 0 |
[t, maintenant] |
DVR non lié |
> 0 |
> 0 |
[t, t+d] |
DVR non lié |
Normalisation des bornes :
t avant le début de l’archive — start est automatiquement aligné sur le premier chunk disponible (le nettoyage a pu rogner). Ce n’est pas un 404 — on sert ce qui reste.
t dans le futur ou fenêtre entièrement avant l’archive — playlist vide mais valide (HLS : header seul +
EXT-X-ENDLIST; DASH :@type="static",mediaPresentationDuration="PT0S").Les chunks sont sélectionnés strictement par leur instant de début tombant dans l’intervalle semi-ouvert [t, t+d) — pas de segments partiels.
VOD sur un flux sans archive (ou dont le stockage est en Error) — 404 immédiat sur master playlist / MPD. Aucune session créée.
Textes d’erreur dans le corps 404 (visibles dans les logs et le corps HTTP) :
VOD: stream not running— le flux est dans la config mais pas en Running.VOD: no DVR archive— aucun stockage défini sur le flux, ou stockage en Error.VOD: DVR detached— le flux a été détaché du stockage entre les requêtes.VOD: EPG event not found— aucun événement trouvé pour?epg=.
Playlist HLS VOD — fermée (le lecteur voit la durée et peut chercher) :
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.000,
...
#EXT-X-ENDLIST
Ces marqueurs sont absents de la playlist live — c’est la seule différence.
MPD DASH VOD — statique : @type="static", mediaPresentationDuration fixe, <SegmentURL> explicites. Le DASH live reste @type="dynamic".
Si l’intervalle choisi a des trous dans l’archive (ex. redémarrage d’enregistrement ou nettoyage au milieu), le MPD DASH est scindé automatiquement en plusieurs <Period> — un par piste contiguë. Les lecteurs (VLC, dashjs, Shaka) franchissent les frontières de période sans configuration.
EPG-aligned VOD¶
Si le flux est lié à une source EPG (champs EPG Source et EPG Channel des paramètres du flux), le client peut demander l’archive par un instant compris dans un événement EPG :
http://host:port/hls/stream/login/password/index.m3u8?epg=1778500000
http://host:port/dash/stream/login/password/index.mpd?epg=1778500000
Le serveur localise l’événement EPG actif à l”epoch donné et utilise ses start et duration comme bornes de la fenêtre VOD. Utile pour les catalogues : l’UI connaît l’heure de l’événement mais n’a pas à calculer les bornes exactes.
Si le flux n’est pas lié à l’EPG ou qu’aucun événement n’est actif — 404 ``VOD: EPG event not found``. t et d sont ignorés en présence de epg.
Flux adaptatifs¶
Les groupes adaptatifs (voir HLS Adaptive Multistream) acceptent les mêmes paramètres VOD :
http://host:port/hls/adaptive/group/login/password/index.m3u8?t=0
http://host:port/dash/adaptive/group/login/password/index.mpd?t=0
Seules les variantes avec un stockage DVR configuré entrent dans la master playlist (HLS). Celles sans DVR sont ignorées (VOD: variant N has no DVR apparaît au log) ; l’assemblage continue avec les autres.
En variante DASH, chaque qualité devient un <Representation> distinct dans des <Period> communs ; le lecteur peut changer de qualité sans rouvrir le manifeste.
Comportement du lecteur¶
Le VOD HLS / DASH de l’archive est lu par les lecteurs standards : VLC, hls.js, dashjs, Shaka, ffmpeg. La recherche timeline marche.
Si le lecteur demande un segment déjà supprimé par le nettoyage, le serveur renvoie 404 pour ce segment (pas 500). VLC, hls.js, dashjs sautent ce segment et continuent au suivant.
Fonctionnalités complémentaires :
Protection des sessions actives : tant qu’une session VOD est ouverte, le nettoyage ne supprime pas les chunks dans sa fenêtre (voir ci-dessous).
Live-edge bridge : si un client en session VOD demande un segment au-delà de la borne droite de la fenêtre VOD — par exemple, avance dans la timeline en atteignant la fin de l’archive — le serveur fournit automatiquement le segment depuis la mémoire live. Pas de redirections, pas de réauthentification.
Cache playlist : sur des requêtes répétées du même VOD
index.m3u8/index.mpd, le serveur renvoie une réponse identique octet pour octet — sans reconstruction. Adapté à un CDN devant PSS.
Sous-titres dans l’archive¶
Si le flux porte des sous-titres (DVB Subtitling, Teletext ou WebVTT) et que l’option OTT WebVTT est active, les sous-titres sont archivés en parallèle des chunks TS — en fichiers .vtt à côté des .ts.
En live, la master playlist contient EXT-X-MEDIA:TYPE=SUBTITLES ; en VOD, le serveur renvoie une playlist VOD de sous-titres (avec ENDLIST) et des segments .vtt aux mêmes URLs.
Particularités :
HLS : l’en-tête
X-TIMESTAMP-MAPest conservé au début de chaque.vtt(requis par la spec HLS).DASH : l’en-tête
X-TIMESTAMP-MAPest retiré à la volée (lié au PCR absolu, en conflit avec l’ancre DASH ; sinon VLC affiche des sous-titres vides).En groupe adaptatif : si le sub-stream actif n’écrit pas de sous-titres, les segments VTT renvoient 404. Sur la variante suivante, le lecteur peut en recevoir à nouveau.
Les sous-titres se désactivent via l’option OTT WebVTT du flux, ou en n’activant pas HLS en mode OTT/HLS.
Nettoyage et rétention¶
PSS utilise quatre stratégies de nettoyage, exécutées à chaque tick de la tâche de nettoyage (par défaut toutes les 10 sec) :
Rolling cleanup (par flux) : pour chaque flux, les chunks plus vieux que Storage Hours sont supprimés. Tourne toujours, même disque à moitié vide.
Size-based cleanup (par stockage) : quand Used % dépasse en continu Max Usage pendant Disk Pressure Grace sec, les chunks les plus anciens sont coupés au prorata sur tous les flux liés au stockage. Par tick : Disk Pressure Cut sec vidéo par flux. Jamais de chunks plus jeunes que Storage Min Hour.
Emergency disk-full cut : si l’espace libre tombe sous Disk Emergency Bytes, le nettoyage devient agressif et peut supprimer même des chunks protégés. L’enregistrement s’arrête jusqu’à reprise de l’espace libre avec hystérésis × 2.
Orphan scan : des fichiers non répertoriés dans l’index peuvent subsister sur le disque (après un arrêt brutal de PSS). Le collecteur parcourt les sous-répertoires des flux et supprime ces fichiers « oubliés » — le premier passage peu après le démarrage du service, puis une fois par heure et à chaque déclenchement de la pression disque. Pour se protéger d’une course avec l’écriture, les fichiers de moins de 60 s sont ignorés.
Note. Les tâches de nettoyage tournent en arrière-plan ; l’utilisateur n’a normalement rien à faire. Si l’archive croît plus vite qu’elle n’est rognée, baisser Storage Hours sur les flux ou augmenter Disk Pressure Cut.
Protection des sessions VOD actives¶
À l’ouverture d’une session VOD, un « créneau de protection » avec l’heure de début de fenêtre est posé sur chaque stockage impliqué. Les nettoyages Rolling et size-based ne touchent pas les chunks dans la fenêtre de la session ouverte. Le créneau est libéré automatiquement à la fermeture (FIN, timeout).
Cela signifie :
Si un client garde une session VOD longtemps, il peut chercher tout instant dans sa fenêtre — les chunks ne « disparaissent pas sous lui ».
Le nettoyage Max Usage peut temporairement ne pas ramener Used % au seuil tant qu’une session est active ; dès le départ du client, le nettoyage rattrape.
Emergency disk-full cut et Storage Min Hour contournent la protection : si le disque est presque vide, les chunks sont supprimés et le client reçoit 404 sur les segments touchés (le lecteur les saute).
Après redémarrage de PSS, les créneaux de protection disparaissent — le nettoyage reprend aussitôt.
Plusieurs stockages¶
On peut créer un nombre quelconque d’enregistrements DVR Storage — un par répertoire / disque. Les flux sont liés indépendamment à différents stockages. Nettoyage et seuils (Max Usage, Disk Pressure) fonctionnent par stockage.
Cas d’usage :
Tiering par valeur : stockage SSD rapide pour chaînes premium avec grande profondeur, stockage HDD capacitif pour les autres.
Disque dédié à l’archive : pour que l’enregistrement DVR ne concurrence pas le disque système ou les fichiers temporaires.
Séparation par projet : un disque pour le lot de chaînes nº 1, un autre pour le nº 2 — simplifie migration et audit.
Changer la liaison du flux (champ Storage dans Stream / OTT) bascule l’enregistrement à la volée. Les anciens fichiers restent intacts sur le disque précédent — à supprimer à la main ou à réattacher en remettant le flux.
État du stockage et monitoring¶
La section Data / DVR Storage List (et l’API GET /data/dvr-storage-list) affiche par stockage :
State — Ready / Error (ainsi que l’état intermédiaire Not Ready pour un stockage qui vient d’être ajouté).
Total / Free / Used Bytes — espace libre et occupé sur le disque.
Used % — pourcentage actuel d’utilisation.
Archived Bytes — taille totale des chunks indexés sur tous les flux liés (hors fichiers orphelins).
Pressure Since Sec — moment (epoch) où Used % a d’abord dépassé Max Usage dans l’épisode courant ; 0 signifie « pas de pression ».
Active Task — l’opération de maintenance en arrière-plan en cours d’exécution : gc-orphans (suppression des fichiers orphelins), disk-pressure-trim (élagage sous pression disque) ou none, et depuis combien de secondes elle s’exécute. Les opérations de courte durée (< 2 s) ne clignotent pas dans l’interface.
Last cleanup — un récapitulatif des dernières exécutions de nettoyage : depuis combien de temps a eu lieu la précédente collecte des fichiers orphelins (et combien ont été supprimés) et le dernier élagage sous pression disque (combien d’espace a été libéré).
Attached streams — la liste des flux rattachés ; pour chacun sont affichés le nom, l’indicateur d’enregistrement en cours (active), la profondeur d’archive configurée (retention-hours) et le remplissage réel (archived-sec et archived-bytes). La somme des archived-bytes sur l’ensemble des flux est égale aux Archived Bytes de tout le stockage.
États :
Ready — le répertoire est disponible, l’enregistrement et le nettoyage se déroulent normalement.
Error — le répertoire de stockage est indisponible (démonté, droits manquants, erreur de système de fichiers) ou l’espace libre sur le disque est critique ; l’enregistrement est arrêté. La récupération est automatique — dès que le répertoire est de nouveau disponible et qu’un espace libre suffisant apparaît.
Si le stockage est passé en Error, vérifiez si le répertoire de l’archive est monté et s’il y a de l’espace libre sur le disque — PSS ne sort pas seul de cet état tant que le problème n’est pas physiquement résolu.
Remplissage de l’archive dans le temps :
Au niveau du flux (Data / Stream), la métrique storage-gap-percent est disponible — la proportion de trous temporels dans l’archive accumulée : 0 % signifie un enregistrement continu, des valeurs plus élevées signifient qu’il y a des trous dans l’archive (redémarrages de la source, segments supprimés par le nettoyage).
Le endpoint
GET /data/dvrstatrenvoie un histogramme du remplissage de l’archive par intervalles de temps, avec le marquage des événements d’enregistrement (démarrage/arrêt de la source, changement de PMT, commutations de l’embrouillage, reconstruction de l’index, passage de nettoyage) et de l’activité des sous-titres — pour le rendu de la frise de l’archive DVR dans l’interface d’administration.
Protection contre la perte accidentelle¶
Plusieurs opérations admin entraînent une perte d’archive ou un arrêt de la diffusion VOD. Avant exécution, l’UI affiche une confirmation modale :
Suppression d’un DVR Storage — tous les flux liés perdent l’accès VOD ; les fichiers restent sur disque mais sont inaccessibles via PSS sans l’enregistrement.
Bascule du flux vers un autre stockage — le VOD sur l’ancienne archive cesse.
Détachement du flux du stockage (Storage = 0) — même effet.
Baisse de Max Usage — peut déclencher le nettoyage size-based et supprimer d’anciens chunks.
Baisse de Storage Hours / Storage Min Hour — peut sortir une partie de l’archive du rolling.
Décision produit assumée : opération autorisée mais avec confirmation, et les fichiers supprimés restent sur disque (restaurables depuis un backup). Placer l’archive sur un serveur de fichiers / RAID séparé réduit fortement le risque de perte irréversible.
Limites de la version actuelle¶
Une session VOD ouverte par un client ne suit pas le live edge — si de nouveaux chunks ont été ajoutés pendant la session, le client doit redemander la playlist (comportement standard HLS / DASH).
Un stockage par disque est recommandé — plusieurs enregistrements avec sous-répertoires différents se disputent l’espace libre.
Les segments sont adressés par hachage (HLS sur MPEG-TS) ou via le modèle
$Number$.m4savec uninit.mp4commun (live DASH sur CMAF) / via des<SegmentURL>explicites vers des.m4s(VOD DASH). Modifier la taille de chunk entre live et VOD ne nécessite pas de rouvrir l’URL.Le scanner orphelin tourne chaque heure ; pour accélérer, redémarrer PSS.