MPEG-TS ou HLS : ce qu’un flux IPTV en direct envoie réellement, et comment chacun tombe en panne
Une URL live de portail est un seul GET HTTP qui ne se termine jamais. Une URL HLS est un fichier texte qui liste les prochaines secondes. Presque tout le reste en découle.
var sourceKind = uri.Contains(".m3u8", StringComparison.OrdinalIgnoreCase) ? "hls" : "ts";
Une ligne, et c’est l’intégralité de notre détection de transport sur le chemin de lecture. Elle s’exécute à chaque application d’un média live, à quatre points d’appel : le zapping, la reconstruction du moteur et deux chemins de bascule en failover. Un test de sous-chaîne sur l’URL entière, où tout ce qui n’est pas HLS retombe sur ts. Passez-la sur les 2 203 entrées des deux playlists que nous gardons pour le travail d’analyse et elle en étiquette 1 930 hls et 273 ts. Exactement 7 de ces 2 203 URL se terminent par .ts.
L’étiquette et la vérité sont deux choses différentes, et les deux transports qu’elle tente de nommer le sont aussi. L’un est un unique GET HTTP qui ne finit jamais. L’autre est un fichier texte qui liste les prochaines secondes et attend que vous reveniez en chercher d’autres.
Ce que la sous-chaîne rate, en chiffres
Ces deux playlists sont le corpus derrière notre travail d’analyse, des fichiers de type annuaire soigneusement sélectionnés, et leur part écrasante de HLS ne dit rien de ce qu’un portail sert. Le chemin du portail va dans l’autre sens, et c’est la partie que la plupart des articles prennent à l’envers : une URL live construite par notre client demande toujours du .ts. Ce qui revient est l’affaire du portail, et nous ne le sondons jamais.
Ce à quoi le corpus sert, c’est à montrer à quel point un suffixe d’URL décrit mal un flux. Mal est la réponse. Sur l’ensemble du corpus, 1 924 chemins se terminent par .m3u8 et 7 par .ts. Parmi les 273 lignes que la règle appelle ts, les suffixes se répartissent ainsi :
- 147 sans extension lisible, dont 16 parce qu’une ip et un port occupent dans le chemin la place d’un nom de fichier
- 75 se terminant par
.php - 17 se terminant par
.mpd, c’est-à-dire un manifeste DASH, adaptatif exactement de la manière que l’étiquettetsnie - 14 se terminant par
.htm - 7 se terminant par
.ts, 6 par.m3u, 3 par.2ts, et un de chaque pour.smil,.dash,.mp4et.wmv
Six lignes vont dans l’autre sens, classées HLS parce que .m3u8 se trouve dans la chaîne de requête plutôt qu’en fin de chemin. Le fait que la règle lise la requête est le seul endroit où elle peut diverger d’un simple contrôle d’extension, puisqu’aucune ligne du corpus ne porte le jeton au milieu du chemin. Ces divergences, et le second classificateur dérivé de l’URL dans la boîte de dialogue Informations sur le flux qui les produit, sont traitées dans leur propre article avec l’extension propre du fichier de playlist, qui est une question distincte de l’extension de n’importe quelle URL qu’il contient.
Ce qui sauve la mise, c’est que l’étiquette ne fait presque rien. Elle passe dans une ligne Debug quand une session s’arme et dans l’événement Serilog wd.fault à chaque verdict, et aucun seuil, aucun délai, aucune branche dans toute la machinerie de récupération ne la lit. L’enregistrement typé censé la transporter vers un backend est déclaré et jamais construit. Le commentaire de documentation du champ dit lui-même à quoi il sert : la télémétrie, plus des seuils par type que personne n’a écrits. Un classificateur qui étiquette mal au moins 17 lignes sur 2 203 et que rien ne consulte est une chose étrange à livrer, et la raison pour laquelle c’est tolérable tient précisément à cette seconde moitié.
Il n’existe pas non plus de meilleure source. L’enregistrement de chaîne live porte un identifiant de flux, une base de portail, une URL directe facultative, des champs de qualité et un indicateur de replay, et rien qui nomme un conteneur, un transport ou un type MIME. Le transport n’est pas une propriété d’une chaîne dans notre modèle de données, donc l’URL est la seule chose qui reste à lire.
Six URL, et ce que le classificateur dit de chacune
Chaque hôte ci-dessous est un domaine d’exemple réservé et chaque chemin est inventé, mais chaque ligne est assemblée à partir de formes que le corpus atteste.
1 https://example.com/live/user/pass/1234.ts
2 https://example.com/live/user/pass/1234.m3u8
3 https://example.net/hls/channel.mpd
4 https://example.org/live/9001/?file=chan.m3u8&output=playlist.m3u8
5 https://example.net/watch.htm?cont=1&output=7&forceUserAgent=1
6 https://example.net/play/9001
La ligne 1 est ce que notre constructeur de portail émet, le seul cas où l’étiquette est correcte et méritée. La ligne 2 est la même chaîne demandée en HLS, avec la sous-chaîne là où on l’attend.
La ligne 3 est un manifeste DASH. Elle ne contient pas de .m3u8, elle est donc étiquetée ts, à tort dans la direction la plus intéressante : le flux est adaptatif, il a des segments, il a un manifeste, et tout ce que l’étiquette sous-entend à son sujet est faux. Dix-sept lignes de la grande playlist se terminent ainsi.
La ligne 4 est l’inverse. Le chemin se termine par une barre oblique et ne porte aucune extension, mais .m3u8 apparaît deux fois dans la requête, une fois comme indice de source et une fois comme valeur d’un paramètre nommé output. La règle de sous-chaîne répond HLS. Deux lignes réelles ont exactement cette forme, et playlist.m3u8 est un nom de fichier plutôt qu’un nom de conteneur, si bien que même le champ qui semble faire autorité ne répond pas à la question.
La ligne 5 est la forme qui m’a fait cesser de faire confiance au paramètre output. Quatorze lignes portent output=7, et toutes les quatorze se trouvent sur un chemin se terminant par .htm, à côté de clés nommées cont et forceUserAgent. Un champ nommé output réglé sur 7 ne dit rien à un client, et nous n’avons aucun moyen d’apprendre ce que signifie ce 7 : les clés qui l’accompagnent ne correspondent pas à la forme d’export Xtream, donc nous ne pouvons même pas supposer qu’il porte le sens output=ts ou output=m3u8 que documente notre propre analyseur d’import. Pendant ce temps, l’extension que la boîte de dialogue Informations sur le flux lirait sur ce chemin est HTM.
La ligne 6 ne contient rien de lisible du tout, et c’est la majorité de tout ce que la règle appelle ts : 147 de ces 273 lignes. Elle reçoit ts parce que ts est la valeur par défaut, pas parce que quelque chose a été détecté, et c’est ce qui fait de tout le classificateur une convention de nommage plutôt qu’une mesure.
Le chemin du portail demande du .ts et ne demande jamais rien d’autre
Voici l’intégralité de la construction d’URL live pour une source portail, échappement mis à part :
return string.Format(CultureInfo.InvariantCulture, "{0}/live/{1}/{2}/{3}.ts", baseText, user, pass, streamId);
Pas de paramètre, pas de branche, pas d’objet d’options. La seule logique de ce fichier au-delà de la chaîne de format est l’échappement du nom d’utilisateur et du mot de passe. La seule bifurcation sur le chemin de résolution est de savoir si la ligne est arrivée d’une playlist avec une URL complète déjà dedans, auquel cas nous utilisons cette URL telle quelle, ou d’un portail, auquel cas nous construisons la ligne ci-dessus.
Le replay est construit par une seconde fonction de même forme, qui insère une durée en minutes entières et un horodatage de début au format yyyy-MM-dd:HH-mm, et son commentaire de documentation porte le seul avertissement dont l’un ou l’autre constructeur avait besoin : cet horodatage est l’heure locale du serveur du portail, la même horloge que celle de l’EPG du portail, pas celle de l’appareil. Il se termine aussi par .ts.
Deux choses nuancent cela. Chaque source Xtream porte un réglage « Format de flux » persistant avec les options MPEG-TS et HLS (m3u8), et il n’est lu par rien : la valeur fait l’aller-retour dans les réglages et l’appareil continue de demander du .ts. Ce contrôle mort, et le second constructeur côté catalogue qui aurait ajouté .m3u8 si quoi que ce soit l’appelait, sont documentés là où ils doivent l’être. L’autre nuance compte davantage ici. Tout ceci concerne la requête. Un portail est libre de rediriger une URL .ts ailleurs ou de servir du HLS depuis elle, et nous ne regardons jamais, donc rien dans cet article ne constitue une preuve de ce que les portails envoient réellement.
Un flux de transport a une cadence ; ce qui lui manque, c’est une frontière que le lecteur nous transmet
Le cadrage du titre est une erreur de catégorie. Dissipons-la d’abord. La RFC 8216, section 3.2, liste les flux de transport MPEG-2 parmi les formats de segment pris en charge, et exige que chaque segment de ce type contienne un seul programme avec une PAT et une PMT, donc un segment HLS peut être les mêmes paquets de 188 octets découpés dans un fichier. À quelle fréquence c’est le cas, nous ne l’avons pas mesuré, et l’industrie migre vers fMP4 depuis des années. Ce qui diffère de manière fiable, c’est la livraison, et c’est de la livraison que vient chaque différence de comportement ci-dessous.
Un manifeste donne à un client quatre choses qu’une socket ouverte ne donne pas :
- Une requête qui peut échouer. Chaque segment est sa propre transaction HTTP, donc un 404, un délai dépassé ou un corps tronqué est un événement auquel un instant est attaché.
- Une cadence que le client peut faire respecter. La RFC 8216 exige d’un client live qu’il recharge la playlist et fixe l’attente à partir de la durée cible, donc le silence peut être mesuré par rapport à quelque chose que le format lui-même déclare.
- Une discontinuité annoncée, de sorte qu’un raccord arrive comme un marqueur plutôt que comme un saut d’horloge à déduire.
- Une position. Une liste de segments et une durée cible disent ensemble à quelle distance le client se trouve du bord live.
Le MPEG-TS progressif sur HTTP vous donne un GET qui ne finit jamais, avec toute la structure dans les octets : des paquets de 188, une table d’association de programmes, une table de correspondance de programmes, des flux élémentaires sur leurs propres PID, une référence d’horloge de programme pour les cadencer, et des paquets nuls sur le PID 0x1FFF en remplissage.
La phrase que j’avais d’abord écrite ici disait qu’un flux d’octets n’a aucune frontière à laquelle accrocher un délai. J’avais tort, et un ingénieur broadcast m’aurait corrigé au premier coup d’œil : au niveau du format, un flux de transport a une cadence en abondance. L’ISO/IEC 13818-1 contraint l’écart maximal entre références d’horloge de programme, et la norme de surveillance du DVB, l’ETSI TR 101 290, construit tout son ensemble de Priorité 1 exactement sur ces frontières : perte de synchronisation, une PAT qui ne se répète pas dans les 500 ms, un compteur de continuité qui saute, une PMT qui disparaît. Des baies de sondes lisent ces frontières toute la journée. Notre propre relais les présuppose : son défaut nulls continue d’envoyer PAT et PMT parce qu’un flux qui en est dépourvu est une panne différente.
Ce qu’un flux progressif n’a pas, c’est une frontière que le lecteur nous fait remonter. Ce que libvlc nous transmet est un instantané de compteurs cumulatifs, octets lus à la couche d’accès, octets consommés par le démultiplexeur, images décodées et images affichées, et pas un seul champ n’y concerne le timing des tables. Le délai n’a donc nulle part où s’accrocher de façon principielle, et un blocage se déduit d’un delta tombé à zéro. Comment ces deltas sont lus, et pourquoi le moteur continue de signaler une lecture saine pendant que l’image est figée, fait l’objet d’un article séparé.
Notre relais d’injection de pannes rend l’écart concret. C’est un banc d’essai local au développeur, jamais déployé et jamais intégré à aucun service, qui génère un flux de transport synthétique à programme unique sur l’interface de bouclage à environ 4.6 Mbit/s et le casse sur commande. Son mode freeze arrête d’écrire et laisse la socket établie, et le résultat mesuré est l’énoncé le plus net du problème que nous ayons : le delta d’octets lus du client tombe à zéro et il n’y a, selon les propres mots du relais, « aucun événement du tout ». Le moteur ne lève aucune erreur et ne signale aucune fin de flux. La cause est que rien ne va mal à la couche HTTP, parce que la réponse est toujours ouverte et toujours en cours de livraison. Le coût est que toute la détection de blocage dont nous disposons pour ce transport repose sur un compteur et une fenêtre de quatre secondes, et si ce compteur ment un jour, le produit se tait avec lui.
En construisant le relais, la première chose à vaincre a été notre propre serveur web. Kestrel impose par défaut un débit de réponse minimal, 240 octets par seconde avec cinq secondes de grâce, donc une socket maintenue ouverte et silencieuse est précisément ce qu’il est conçu pour tuer. Un défaut freeze serait apparu côté client comme une fermeture de socket : un test de blocage d’accès F1 tournant discrètement comme un test de fin de flux F2, avec toute la matrice invalide et chaque cas toujours au vert. Trois limites sont levées avant que le relais ne serve un octet.
La latence est votre tampon sur un transport et un plancher sur l’autre
La RFC 8216 dit qu’un client NE DEVRAIT PAS démarrer sur un segment situé à moins de trois durées cibles de la fin de la playlist. Avec une durée cible de six secondes, un choix courant plutôt qu’une valeur mesurée, cela fait dix-huit secondes de retard sur le direct avant que le client ait mis en tampon une seule image de son côté, et c’est la source qui a choisi ce nombre en segmentant le flux. Le brouillon de la seconde édition conserve trois durées cibles par défaut et ajoute un retrait distinct pour le mode basse latence dont le minimum est deux fois la durée cible de partie, si bien que le plancher ne bouge que lorsque la source découpe le flux en parties. C’est la décision de la source dans les deux cas, pas celle du lecteur.
Le MPEG-TS progressif n’a pas de tel plancher. La latence est ce que le client décide de retenir, et notre réglage actuel retient très peu. Le moteur est construit avec un cache réseau de 400 ms, et le chemin live applique 1200 ms de mise en cache réseau sur 800 ms de mise en cache live. Les tuiles de multivue descendent à 350 et 200 en sourdine, 500 et 350 avec le son. La lecture à la demande distante reçoit 1500 ms, parce que le défilement veut un tampon plus profond qu’une chaîne live. Ce sont des valeurs de réglage. La prochaine personne qui mesurera le temps de zapping en déplacera certaines.
Les petits tampons ne sont pas gratuits. C’est le compromis que le transport vous impose, pas une préférence. Un flux d’octets avec 1200 ms de coussin reste proche du direct et dispose de 1200 ms de tolérance pour un accroc. Un client HLS assis trois segments en arrière dispose d’énormément de tolérance et ne peut pas la dépenser. Quand notre détecteur de remise en tampon déclare une boucle, sa remédiation relève le plancher de mise en cache de 1000 ms au redémarrage suivant, plafonné à 5000 ms, ce qui est le même compromis fait à l’exécution plutôt que dans les réglages.
La recherche vient de la longueur, pas du transport
Aucun des deux transports n’est navigable en direct dans notre client, et l’indicateur qui en décide ne consulte jamais le transport.
// A live stream with no known length is not seekable in any way the scrubber could honour,
// whatever the demuxer claims; both position and live edge stay unknown then.
var seekAvailable = isSeekable && durationMs > 0;
Deux conditions, toutes deux lues sur le lecteur. Le test qui verrouille ce comportement nomme le transport dans son commentaire là où le code ne le fait pas : « Typical live TS: demuxer may claim seekable but there is no length to scrub against. » Il passe un indicateur seekable à vrai avec une longueur de zéro et affirme qu’aucune recherche n’est proposée. C’est la base de code qui déclare, dans un test, qu’un démultiplexeur progressif revendiquera volontiers une capacité qu’il ne peut pas honorer, et que la longueur est le champ qui dit la vérité.
Ce que libvlc rapporte comme longueur d’une fenêtre HLS live, nous ne l’avons pas mesuré, et la règle ci-dessus est écrite pour que cela n’ait pas d’importance. Si une fenêtre glissante produisait un jour une longueur positive, la barre de défilement s’allumerait et la surcouche de transport proposerait une recherche à travers elle. Que cela fonctionne est une question ouverte de notre côté, pas une affirmation.
Le replay est la version honnête d’une recherche en arrière sur une source portail, et ce n’est pas du tout une recherche : une seconde URL issue d’un second constructeur, portant une durée en minutes et un horodatage de début sur l’horloge du portail, se terminant par .ts comme tout le reste. L’enregistrement a la même limite pour la même cause, puisque la progression d’une capture ne peut pas être un pourcentage d’une durée que l’entrée ne déclare jamais.
Un seul seuil de la machinerie de récupération a la forme de HLS, et c’est le seul
Chaque fenêtre de verdict est indépendante du transport. Quatre secondes de zéro octet à la couche d’accès, six secondes d’octets qui arrivent pendant que le démultiplexeur ne produit rien, quatre secondes de vidéo bloquée sur un son en direct, quatre pour les deux bloqués ensemble, quinze sur une chaîne mesurée à faible cadence d’images. Aucune de ces fenêtres n’a de seconde valeur pour HLS, et aucune n’est sélectionnée par le type de source.
L’exception est le comptage des remises en tampon, et le fichier d’options en donne la raison sur place : les épisodes ne sont comptés que lorsque le cache passe sous un plancher plutôt qu’à chaque rapport sous les 100, parce que « live HLS cache wobbles across segment boundaries and raw sub-100 counting would flag healthy streams ». L’hystérésis va de 62 pour cent pour ouvrir un épisode à 88 pour le clore, avec quatre épisodes sur 60 secondes glissantes pour déclarer une boucle. Le voile de mise en tampon porte sa propre hystérésis pour le même vacillement, son commentaire situant l’effet à environ deux secondes avant les images clés. Les deux existent parce que le niveau de cache d’un flux piloté par manifeste oscille par conception et qu’un seuil brut lit cette oscillation comme une maladie.
L’aveu qui a sa place ici dépasse un seul seuil. Tout le modèle de compteurs derrière la détection de pannes a été calibré sur du MPEG-TS brut, où la couche d’accès et le démultiplexeur sont dans une relation amont propre et où l’écart entre eux veut dire quelque chose de précis. Ce qu’un démultiplexeur adaptatif fait à cette relation lorsqu’il émet ses propres requêtes, nous ne l’avons pas mesuré, donc je ne vous dirai pas que la répartition est fausse sur HLS, seulement qu’elle n’a jamais été vérifiée. Nous portons une étiquette qui nous permettrait de brancher. Nous n’avons jamais écrit un seul seuil spécifique à HLS, et sans télémétrie de flotte nous ne pouvons pas dire ce que cela coûte. Une asymétrie que nous gérons sans le vouloir : la primitive de redémarrage libère le média et réapplique l’URL depuis zéro, ce qui, note le plan, régénère les jetons des sessions HLS dont le jeton est embarqué dans l’URL.
La seule capacité qu’un manifeste nous achète vraiment dans le code livré est plus petite que tout cela. Des plafonds de rendition, appliqués aux tuiles de multivue seulement, 640 par 360 pour une tuile en sourdine et 1280 par 720 pour celle qui a le son, plus une demande de la rendition la plus basse sur le profil en sourdine. Sur du MPEG-TS progressif ces options sont inertes, parce qu’il n’y a aucune rendition à plafonner, et le lecteur les accepte en silence plutôt que de se plaindre. C’est pourquoi elles sont conditionnées au profil de tuile plutôt qu’au type de source : une option qui ne coûte rien quand elle ne fait rien est moins chère à appliquer sans condition qu’à protéger par un classificateur dont nous avons déjà établi qu’il étiquette mal au moins 17 lignes sur 2 203. La lecture live en plein écran ne les utilise pas du tout.
La limite honnête : les deux playlists mesurées ici sont l’intégralité des preuves, et nous ne détenons aucun corpus d’URL live de portail. Tout ce qui précède décrit la requête que fait notre client et le code qui réagit à ce qui revient, jamais ce que les portails envoient. Lire l’URL que votre propre source vous remet reste le moyen le plus rapide de savoir dans laquelle des deux formes vous êtes. Sur les applications Windows et Xbox cela reste une opération locale : elles ouvrent l’adresse que vous leur indiquez et l’analysent sur l’appareil, sans détenir de chaînes propres et sans rien récupérer pour vous ailleurs. La boîte de dialogue Informations sur le flux vous montrera ce que l’URL affirme d’elle-même, avec la réserve posée plus haut sur ce que cette ligne veut vraiment dire, et un compte gratuit suffit pour aller regarder.
Ce que cet article a mesuré35 affirmations, chacune avec les preuves derrière elles
| Réclamation | Preuve | Compté |
|---|---|---|
| Le seul classificateur de transport sur le chemin de lecture est un test de sous-chaîne insensible à la casse pour ".m3u8" sur l’URL entière, évalué à chaque application d’un média live. Tout le reste retombe par défaut sur "ts". | n = 1 | 23 août 2026 |
| Aucun seuil, délai ou branche dans le watchdog ne lit le type de source. Chaque occurrence est une déclaration, une affectation, une copie ou un champ de journal. | n = 1 | 23 août 2026 |
| Le type de source atteint une ligne Debug quand une session s’arme et un événement Serilog wd.fault de niveau Information à chaque verdict de panne. L’enregistrement typé censé le transporter vers un backend est déclaré et jamais construit. | n = 1 | 23 août 2026 |
| Passé sur les deux playlists que nous gardons pour le travail d’analyse, le classificateur livré étiquette 1 930 des 2 203 lignes "hls" et 273 "ts". Exactement 7 des 2 203 URL se terminent par ".ts". | n = 2203 | 23 août 2026 |
| Suffixes de chemin sur l’ensemble du corpus : 1 924 .m3u8, 137 sans extension, 16 sans extension parce qu’un ip:port occupe le chemin, 75 .php, 17 .mpd, 14 .htm, 7 .ts, 6 .m3u, 3 .2ts, et un de chaque pour .smil, .dash, .mp4 et .wmv. Sur les 273 lignes que le classificateur appelle "ts", 147 n’ont aucune extension lisible. | n = 2203 | 23 août 2026 |
| Six lignes sont classées HLS parce que ".m3u8" apparaît dans la chaîne de requête plutôt qu’en fin de chemin. Chacune de ces six a un chemin sans extension. Aucune ligne du corpus ne porte le jeton au milieu du chemin, et aucune ligne nulle part ne porte une clé de requête "out". | n = 2203 | 23 août 2026 |
| Quatorze lignes portent un paramètre de requête output dont la valeur est 7, et toutes les quatorze se trouvent sur des chemins se terminant par .htm, à côté de clés cont et forceUserAgent. Deux lignes règlent output sur playlist.m3u8. Soixante lignes ont get.php comme dernier segment de chemin et pas une seule ne porte de paramètre output. | n = 2203 | 23 août 2026 |
| L’extension propre d’un fichier de playlist ne prédit pas les suffixes des URL qu’il contient. Le fichier .m3u de notre corpus pointe vers 303 URL se terminant par .m3u8 et aucune se terminant par .ts. | n = 308 | 23 août 2026 |
| Les deux playlists mesurées ici sont des fichiers de type annuaire soigneusement sélectionnés, pas des exports de portail, et leur domination HLS ne dit rien de ce qu’un portail sert. | n = 2 | 23 août 2026 |
| Le constructeur d’URL live Xtream du client code en dur un suffixe .ts sans paramètre ni branche, et le constructeur de replay fait de même. C’est ce que nous demandons ; rien ici n’observe ce qu’un portail renvoie. | n = 1 | 23 août 2026 |
| Le contrôle Format de flux proposé sur les sources Xtream normalise, enregistre et recharge, et n’est lu par aucun constructeur d’URL ni aucun code de lecture. Quelle que soit sa valeur, le client de bureau demande du .ts. | n = 1 | 23 août 2026 |
| La boîte de dialogue Informations sur le flux dérive le protocole du schéma de l’URI et le conteneur de l’extension de fichier du chemin, en retombant sur "N/A" quand le chemin n’en a pas. C’est un second classificateur dérivé de l’URL et il n’est pas d’accord avec celui du watchdog. | n = 1 | 23 août 2026 |
| L’enregistrement de chaîne live ne porte aucun champ de conteneur, de transport ou de type MIME, donc le transport n’est jamais un trait de chaîne et ne peut être lu que sur l’URL. | n = 1 | 23 août 2026 |
| HLS livre une Media Playlist qui liste des Media Segments sous une durée cible déclarée, et un client qui suit une présentation live DOIT recharger périodiquement cette playlist pour apprendre quels médias sont disponibles.RFC 8216 section 4.3.3.1 (EXT-X-TARGETDURATION, REQUIRED) and section 6.3.4 (Reloading the Media Playlist File), verbatim: "The client MUST periodically reload a Media Playlist file to learn what media is currently available", and must wait at least the target duration between reloads that found a change. | Spécification | Sans objet |
| La RFC 8216 liste les flux de transport MPEG-2 parmi les formats de Media Segment pris en charge, donc un segment HLS peut être les mêmes paquets de 188 octets découpés dans un fichier. À quelle fréquence c’est le cas, nous ne l’avons pas mesuré.RFC 8216 section 3.1 (Supported Media Segment Formats) and section 3.2 (MPEG-2 Transport Streams), which requires a single MPEG-2 Program per segment and a PAT plus PMT in each segment absent an EXT-X-MAP tag. Sections 3.3 through 3.5 cover fragmented MPEG-4, packed audio and WebVTT. | Spécification | Sans objet |
| Un client qui lit une présentation HLS live NE DEVRAIT PAS choisir un segment de départ qui commence à moins de trois durées cibles de la fin de la playlist.RFC 8216 section 6.3.3 (Playing the Media Playlist File), verbatim: "If the EXT-X-ENDLIST tag is not present and the client intends to play the media normally, the client SHOULD NOT choose a segment that starts less than three target durations from the end of the Playlist file. Doing so can trigger playback stalls." | Spécification | Sans objet |
| Le brouillon de la seconde édition de HLS conserve trois durées cibles comme distance par défaut au bord live et ajoute PART-HOLD-BACK pour le mode basse latence, dont le minimum est deux fois la Part Target Duration. Les parties sont bien plus courtes que les segments, et c’est ainsi que le HLS basse latence passe sous un segment de distance au bord.draft-pantos-hls-rfc8216bis section 4.4.3.8 (EXT-X-SERVER-CONTROL). HOLD-BACK: "Its value MUST be at least three times the Target Duration ... Its absence implies a value of three times the Target Duration." PART-HOLD-BACK: "Its value MUST be at least twice the Part Target Duration." The draft header reads "Obsoletes: 8216 (if approved)". | Spécification | Sans objet |
| Un flux de transport n’est pas sans structure dans le temps. L’ISO/IEC 13818-1 contraint l’écart maximal entre références d’horloge de programme, et la norme de surveillance du DVB transforme la répétition des tables et la continuité en contrôles réussis ou échoués.ISO/IEC 13818-1 (transport stream system layer, PCR interval constraint); ETSI TR 101 290 V1.4.1 (2020-06) Priority 1 measurements, which include TS_sync_loss, Sync_byte_error, PAT_error and PAT_error_2 on a 500 ms PAT repetition limit, Continuity_count_error, PMT_error and PMT_error_2, and PID_error. | Spécification | Sans objet |
| Ce que le lecteur nous transmet est un instantané de compteurs cumulatifs du pipeline, et la machine à états travaille exclusivement sur les deltas entre échantillons consécutifs. Aucun champ n’y concerne le timing des tables. | n = 1 | 23 août 2026 |
| Un flux de transport MPEG-2 est une suite de paquets de 188 octets portant une table d’association de programmes, une table de correspondance de programmes, des flux élémentaires sur leurs propres PID, une référence d’horloge de programme, et des paquets nuls sur le PID 0x1FFF en remplissage.ISO/IEC 13818-1, transport stream packet syntax; mirrored in our own synthetic muxer at clients/windows/tools/FaultRelay/Media/TsMuxer.cs:15-20, which declares PacketSize 188, PatPid 0x0000, PmtPid 0x1000, VideoPid 0x0100, AudioPid 0x0101 and NullPid 0x1FFF. | Spécification | Sans objet |
| Le relais d’injection de pannes est un banc d’essai local au développeur qui génère une vidéo synthétique sur l’interface de bouclage. Il n’est jamais déployé, jamais ajouté à un chart ou à un fichier compose, et jamais référencé par un service backend. | n = 1 | 16 août 2026 |
| Le relais génère un flux de transport à programme unique d’environ 4.6 Mbit/s avec ses valeurs par défaut, avec le PCR sur le PID vidéo et des compteurs de continuité par PID. | n = 1 | 16 août 2026 |
| Un défaut du relais qui arrête d’écrire tout en laissant la socket établie produit un delta d’octets lus nul côté client et aucun événement moteur du tout. | n = 1 | 16 août 2026 |
| Un flux réduit aux tables de programme plus des paquets nuls conserve son débit d’octets pendant que le démultiplexeur est affamé. Cette forme de panne appartient au conteneur, pas à la livraison progressive : une présentation HLS à segments de flux de transport peut la produire et une présentation à segments fMP4 n’a aucun remplissage équivalent. | n = 1 | 16 août 2026 |
| Le relais lève trois limites de Kestrel avant de servir un octet, parce que le débit de réponse minimal par défaut interromprait un défaut de gel d’octets et transformerait chaque test de blocage d’accès F1 en un test de fermeture de socket F2. | n = 1 | 16 août 2026 |
| Le débit de réponse minimal par défaut de Kestrel est de 240 octets par seconde avec une période de grâce de cinq secondes.Microsoft ASP.NET Core Kestrel options documentation, MinResponseDataRate default. | Spécification | Sans objet |
| L’indicateur de recherche en direct est la conjonction de l’indicateur seekable du lecteur et d’une longueur positive. Le transport n’est pas une entrée, et la position comme le bord live restent nuls quand la conjonction échoue. | n = 1 | 23 août 2026 |
| La progression d’un enregistrement ne peut pas être rapportée en pourcentage sur une capture live parce que la durée de l’entrée est inconnue. | n = 1 | 23 août 2026 |
| Les seules options par transport que nous livrons sont des plafonds de rendition, appliqués aux tuiles de multivue seulement : 640 par 360 en sourdine, 1280 par 720 avec le son, plus une sélection de la rendition la plus basse sur le profil en sourdine. Le live en plein écran n’en reçoit aucune. | n = 1 | 23 août 2026 |
| Réglage actuel : le moteur est construit avec un cache réseau de 400 ms, le chemin live applique 1200 ms de cache réseau et 800 ms de cache live, les tuiles de multivue descendent à 350/200 en sourdine et 500/350 avec le son, et la demande distante utilise 1500 ms. | n = 1 | 23 août 2026 |
| Chaque fenêtre de verdict est indépendante du transport : 4 s de zéro octet, 6 s de démultiplexeur affamé, 4 s de vidéo bloquée, 4 s de gel total, 15 s sur une chaîne à faible cadence d’images. | n = 5 | 23 août 2026 |
| Le seul seuil façonné par HLS est le comptage des remises en tampon : un épisode n’est compté que sous 62 pour cent de cache et se termine à 88, quatre épisodes dans une fenêtre de 60 s déclarent une boucle, et la remédiation relève le plancher de mise en cache de 1000 ms par verdict jusqu’à un plafond de 5000 ms. | n = 1 | 23 août 2026 |
| Le voile de mise en tampon porte sa propre hystérésis pour la même raison, et le commentaire du code attribue le vacillement aux frontières de segments HLS, environ deux secondes avant les images clés. | n = 1 | 23 août 2026 |
| Le modèle de compteurs derrière la détection de pannes a été calibré sur du MPEG-TS brut, et aucun seuil que nous livrons n’est spécifique à HLS. | n = 1 | 23 août 2026 |
| La primitive de redémarrage libère le média et réapplique l’URL depuis zéro, ce qui, note le plan, régénère les jetons des sessions HLS dont le jeton est embarqué dans l’URL. | n = 1 | 23 août 2026 |