m3u vs m3u8 : l’extension du fichier ne vous dit pas le format
L’un des trois fichiers que nous gardons pour le travail d’analyse s’appelle .m3u8 et contient 1 895 lignes de chaînes. Un autre s’appelle .m3u, et sur 303 de ses 308 lignes le chemin de l’URL se termine par .m3u8.
file named entries URL paths ending .m3u8 lines beginning #EXT-X-
playlist_01 .m3u 308 303 0
playlist_02 .m3u8 1,895 1,621 0
iptv-org-index-sample .m3u 6 6 0
Trois fichiers que nous gardons pour le travail d’analyse : deux vraies playlists et une fixture de test de six entrées. Un échantillon sélectionné, pas un tirage au hasard dans la nature. Gardez cela en tête en lisant chaque nombre ci-dessous. Celui nommé .m3u8 est une liste de chaînes de 1 895 lignes, chacune un nom et une URL, sans la moindre balise HLS. Celui nommé .m3u est aussi une liste de chaînes, et sur 303 de ses 308 lignes le chemin de l’URL se termine par .m3u8. Triez les deux selon leur propre extension et vous les avez à l’envers. Triez-les selon les extensions des URL qu’ils contiennent et vous appelez les deux fichiers HLS, 98.4 pour cent de l’un et 85.5 pour cent de l’autre, ce qui est faux deux fois.
L’extension est une convention de nommage. Elle voyage avec le fichier, celui qui l’a écrit ou servi l’a choisie, et rien ne l’impose. Un analyseur qui s’y fie se trompera sur de vraies entrées. L’erreur est silencieuse.
La RFC 8216 accepte les deux extensions pour le même fichier
Le document qui définit HLS est explicite là-dessus. Il dit le contraire du folklore. Il est de statut Informational plutôt que Standards Track, et une révision qui le rendrait obsolète, draft-pantos-hls-rfc8216bis, attend dans la file de l’éditeur RFC en renommant la Master Playlist en Multivariant Playlist. La règle ci-dessous survit à ce renommage. Section 4 :
Chaque fichier de playlist DOIT être identifiable soit par la composante chemin de son URI, soit par le Content-Type HTTP. Dans le premier cas, le chemin DOIT se terminer par
.m3u8ou par.m3u. Dans le second, le Content-Type HTTP DOIT êtreapplication/vnd.apple.mpegurlouaudio/mpegurl. Les clients DEVRAIENT refuser d’analyser les playlists qui ne sont pas ainsi identifiées.
Lisez les deux moitiés. Une playlist HLS conforme peut être servie à un chemin se terminant par .m3u, l’une des deux orthographes que le document nomme. Et l’identification est un ou bien/ou bien : une playlist identifiée par son Content-Type a satisfait l’exigence avec n’importe quel chemin, y compris sans extension. Donc la spécification que l’on cite pour « .m3u8 signifie HLS » permet .m3u pour HLS et permet un chemin qui ne dit rien.
La moitié encodage du folklore ne s’en sort pas mieux. Le 8 de .m3u8 est largement expliqué comme UTF-8, et la section 4.1 exige bien l’UTF-8, pour toute playlist, à l’une comme à l’autre extension : « Les fichiers de playlist DOIVENT être encodés en UTF-8. Ils NE DOIVENT PAS contenir de marque d’ordre des octets (BOM) ; les clients DEVRAIENT échouer à analyser les playlists qui contiennent une BOM ou ne s’analysent pas comme UTF-8. » L’exigence s’attache à la playlist, pas à l’orthographe de son nom. Nos trois fichiers se décodent tous en UTF-8 avec zéro caractère de remplacement, aucun ne porte de BOM, et celui nommé .m3u a du non-ASCII dans 24 de ses noms d’affichage, donc ici non plus les extensions ne vous disent rien.
Ce que la spécification utilise bel et bien pour classer une playlist, c’est son contenu. Section 4.1 : « Une playlist est une Media Playlist si toutes les lignes URI de la playlist identifient des Media Segments. Une playlist est une Master Playlist si toutes les lignes URI de la playlist identifient des Media Playlists. » Le type est une propriété de l’endroit où pointent les lignes URI. Le nom de fichier n’est pas dans cette phrase.
Les deux fichiers ont leurs extensions à l’envers
Pas une ligne dans aucun des trois ne commence par #EXT-X-. Pas une, sur 2 209 entrées, et je ne m’attendais pas à cela d’un fichier nommé .m3u8. La RFC 8216 hérite exactement deux balises de l’ancien format M3U, #EXTM3U et #EXTINF, et toute balise qu’elle définit au-delà de ces deux-là porte le préfixe EXT-X-, donc l’absence est à peu près ce qu’un corpus peut offrir de plus proche d’une preuve : ce sont des listes de chaînes bâties sur les deux balises héritées plus une couche de directives qui leur est propre.
Les suffixes d’URL à l’intérieur du grand fichier sont là où l’histoire de l’extension se défait. Sur ses 1 895 lignes, 1 621 pointent vers un chemin se terminant par .m3u8. Le reste est un éventail : 133 lignes dont le chemin ne porte aucune extension, 15 dont le dernier segment de chemin se termine par un deux-points et un numéro de port que Path.GetExtension prend pour une extension, puis 75 se terminant par .php, 17 par .mpd, 14 par .htm, 7 par .ts, 6 par .m3u, 3 par .2ts, et une ligne chacune se terminant par .smil, .dash, .mp4 et .wmv. Dix-sept lignes se terminent par .mpd et une par .dash, qui nomment toutes deux des manifestes MPEG-DASH, lesquels sont du XML et pas du M3U du tout. Six pointent vers un autre M3U. Deux cent quarante portent un suffixe qui ne nomme aucun format média.
Sur l’ensemble des trois fichiers, 1 930 des 2 209 chemins d’URL se terminent par .m3u8 et 7 par .ts, ce qui à première vue se lit comme 87.4 pour cent de HLS et 0.3 pour cent de MPEG-TS. Rien dans les fichiers ne soutient cela, parce qu’aucun d’eux n’a été récupéré. Ce que le transport s’avère être est un sujet à part.
Une forme de plus tirée du même fichier, parce qu’elle compte plus loin. Sa ligne #EXTM3U fait 6 294 octets de long, et tous ces octets sauf sept sont un attribut x-tvg-url contenant 101 adresses de guide de programmes séparées par des virgules. La RFC 8216 donne comme format de la balise la chaîne nue #EXTM3U, interdit les espaces « sauf pour les éléments où ils sont explicitement spécifiés », et dit qu’une playlist qui viole ses règles est invalide et que les clients DOIVENT échouer à l’analyser. La première ligne de ce fichier est détectablement hors de la spécification, d’une manière qu’aucune playlist HLS ne produirait. C’est un signal, et nous ne l’utilisons pas.
Donnez un manifeste HLS à un analyseur de liste de chaînes et vous obtenez trois échecs différents
Voici une media playlist live, construite pour cet article avec un hôte d’exemple réservé et raccourcie à trois segments :
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:26401
#EXTINF:10.000,
https://example.com/seg26401.ts
#EXTINF:10.000,
https://example.com/seg26402.ts
#EXTINF:10.000,
https://example.com/seg26403.ts
Je l’ai passée dans l’analyseur livré au lieu de la tracer à la main. Trois chaînes, zéro diagnostic.
La ligne 1 est sautée, parce que l’analyseur ne cherche que #EXTINF: et enjambe toute autre ligne # comme directive non reconnue. Les lignes 2, 3 et 4 suivent le même chemin : #EXT-X-VERSION, #EXT-X-TARGETDURATION et #EXT-X-MEDIA-SEQUENCE ne sont pour nous que des dièses. Chaque ligne #EXTINF:10.000, s’analyse proprement, puisque le scanneur de durée prend 10, le reste .000 atterrit sans dommage dans la région des attributs, et le titre après la virgule est vide. Un titre vide devient la chaîne littérale Unnamed channel. Chaque ligne suivante est une URL HTTPS absolue, donc elle est acceptée, et une chaîne est émise.
Trois chaînes appelées Unnamed channel, chacune pointant vers un fragment de dix secondes d’un seul et même flux. Pas d’erreur, pas d’avertissement, pas de compteur. L’import rapporte un succès.
Changez une chose et la forme change complètement. HLS permet qu’une URI de segment soit relative à son manifeste (section 4.1) et permet à un serveur live de laisser tomber les segments par l’avant à mesure que le flux avance (section 6.2.2), et beaucoup de serveurs font les deux, si bien que les lignes se lisent seg26401.ts là où une URL complète se tenait. Celles-là échouent au test d’URI absolue, et le même fichier donne zéro chaîne et trois diagnostics indiquant Skipped non-absolute http(s) URL. Une master playlist avec des URI de rendition absolues échoue d’une troisième manière : elle n’a aucune ligne #EXTINF, seulement #EXT-X-STREAM-INF avant chaque URL de rendition, donc chaque URL arrive sans en-tête en attente et produit URL without preceding EXTINF (skipped).
Trois entrées qui sont toutes la même chose, trois issues sans rapport, et pas une ne dit « ceci est un manifeste HLS ». La pire des trois est celle qui réussit. Un utilisateur qui a importé une media playlist avec des URI de segment absolues obtient une source qui a l’air peuplée, et l’échec ne fait surface que lorsqu’il essaie de lire une ligne.
La première ligne #EXT-X- vous dit ce qu’est le fichier
Chacun de ces fichiers s’annonce dans ses quatre premières lignes. Le test est bon marché, ce n’est pas l’extension, et rien dans notre client ni nos services ne l’effectue : lisez la tête du corps et cherchez une ligne dont les sept premiers caractères sont #EXT-X-. Toute occurrence signifie HLS en pratique, puisque chaque balise que la spécification définit au-delà des deux qu’elle a héritées porte ce préfixe. Deux occurrences sont décisives quant au type :
#EXT-X-TARGETDURATIONsignifie une media playlist, une liste de segments. La section 4.3.3.1 la rend REQUIRED dans une telle playlist, donc son absence a du poids aussi.#EXT-X-STREAM-INFsignifie une master playlist, une liste de renditions.
La spécification ne réserve aucun préfixe et ne tient aucun registre de balises, donc c’est une convention forte et non une garantie : une liste de chaînes pourrait porter une ligne #EXT-X- égarée et être mal lue par la procédure que je recommande. Aucune des nôtres ne le fait.
Sans aucun #EXT-X- nulle part, trois formes corroborantes appuient une liste de chaînes. Une durée de -1, que portent nos 2 209 entrées, se situe hors de la grammaire de la RFC 8216, parce que ni la forme decimal-integer ni la forme decimal-floating-point ne prend de moins. Des attributs sur la ligne #EXTM3U, comme dans l’en-tête de 6 294 octets ci-dessus. Et des attributs tvg- entre la durée et la virgule, une convention sans spécification derrière elle.
Les deux balises se trouvent par convention près du haut du fichier auquel elles appartiennent. La RFC 8216 n’impose une position que pour #EXTM3U, donc une lecture bornée est une heuristique.
Le Content-Type est un troisième avis et nous ne l’avons jamais demandé
La RFC 8216 propose le Content-Type comme alternative au chemin, ce qui ressemble à la moitié fiable jusqu’à ce qu’on remarque ce que permet le ou bien/ou bien : un serveur qui a identifié sa playlist par le chemin peut ensuite envoyer l’en-tête qu’il veut.
Nous avons écrit une garde pour cela. Elle rejette les familles MIME manifestement fausses avant qu’un corps soit lu : HTML, JSON, images, vidéo, polices, multipart et WebAssembly. Les types inconnus et génériques passent jusqu’à la vérification du corps, text/plain étant l’exemple nommé. Elle taille ensuite deux exceptions dans son propre rejet global audio/* : audio/x-mpegurl, au motif déclaré que les réseaux de diffusion de contenu et l’hébergement statique servent couramment les playlists sous ce type, et audio/mpegurl, l’un des deux types que nomme la spécification et que la règle globale refuserait sinon. La garde est testée unitairement et n’a aucun appelant en production. Elle en avait un jusqu’à ce que le changement thin-catalog supprime le récupérateur côté serveur qui l’utilisait.
Ce qui s’exécute bel et bien, c’est un reniflage du corps, et il s’exécute sur votre appareil. Il saute une BOM UTF-8 facultative et tout espace de tête, puis accepte le fichier si les sept octets suivants sont #EXTM3U ou #EXTINF. Exécuté contre la garde livrée, il accepte une master playlist HLS, une media playlist HLS, une liste de chaînes sans ligne d’en-tête et un fichier préfixé d’une BOM. Il rejette une page d’erreur HTML et un corps d’erreur JSON, qui est la classe d’entrée pour laquelle la garde de Content-Type a été écrite. Il rejette aussi un fichier dont la première ligne est un commentaire # ordinaire, et la RFC 8216 refuserait celui-là aussi puisqu’elle exige #EXTM3U en premier, donc nous atterrissons au bon endroit par accident.
Quelle copie s’exécute a son importance, et je la plaçais au mauvais endroit jusqu’à ce que je parcoure le graphe d’appels. Le service catalogue porte une jumelle avec une couche binaire par-dessus, rejetant les octets nuls et six séquences magiques couvrant PDF, exécutables Windows, binaires ELF et trois variantes ZIP. Cette couche dit si le fichier est un binaire déguisé, jamais s’il est HLS. Et rien en production ne l’atteint : le seul appelant de la vérification de contenu de la jumelle serveur est un test d’intégration. La vérification qui s’exécute sur un vrai envoi est celle du client, à CloudSyncUploadService.cs:28, six lignes avant que le texte en clair soit chiffré, si bien que les octets qu’un serveur pourrait renifler sont du texte chiffré au moment où ils quittent votre machine.
Ce reniflage lit au plus 8 192 octets, une borne choisie pour plafonner une vérification de sécurité sans aucune pensée pour la classification d’un format. À peine assez. Dans le fichier de 308 lignes, la première ligne fait 7 octets et 29 lignes #EXTINF complètes tiennent dans la fenêtre, 28 d’entre elles avec leur URL. Dans le fichier de 1 895 lignes, la première ligne à elle seule mange 6 294 des 8 192, laissant 1 898 octets contenant 9 lignes #EXTINF complètes, 8 d’entre elles avec leur URL. Une master playlist tient en entier et une media playlist place #EXT-X-TARGETDURATION dans ses premières lignes, donc la fenêtre fonctionne grâce à l’endroit où se trouvent les balises HLS. Huit kilooctets n’est pas une fraction raisonnée d’un fichier à lire.
Le comportement face à la BOM est la partie que je continue de regarder. La RFC 8216 dit que les clients DEVRAIENT échouer à analyser une playlist contenant une marque d’ordre des octets, et la première chose que fait notre reniflage est d’en enjamber une et de continuer. Le Bloc-notes et Out-File de PowerShell écrivent une BOM, et refuser ces fichiers coûterait à un utilisateur un import fonctionnel pour satisfaire une règle sans conséquence pratique pour nous, donc nous dévions en le sachant. Cela reste une déviation, et un lecteur qui construit contre la spécification ne devrait pas la copier chez nous.
Enregistrez une playlist par URL au lieu de l’envoyer et il n’y a aucun corps à renifler, parce que cet enregistrement stocke une adresse comme métadonnée de compte et ne récupère rien. Ce qui reste, c’est l’extension, et notre vérification fonctionne à l’envers : elle ne se déclenche que lorsque le chemin en a déjà une, si bien qu’une URL se terminant par .txt est refusée et qu’une URL se terminant par /playlist est acceptée sans examen. La règle inspecte les URL qui vous disaient quelque chose et laisse passer les silencieuses. Attrape-fautes de frappe bon marché, vérification de format inutile.
L’extension dans une URL de flux est une demande, pas une description
Tout ce qui précède concerne le fichier de playlist. Le même problème se répète un niveau plus bas, sur les URL qu’il contient, où il est plus facile à démontrer parce que c’est nous qui les écrivons.
Les logiciels de portail de la famille Xtream Codes construisent une URL live comme {portal}/live/{user}/{pass}/{streamId}.{ext}, et l’extension est le client qui demande au serveur quel conteneur envoyer. La même chaîne est 1234.ts ou 1234.m3u8 selon ce que vous tapez. Son point de terminaison d’export de playlist prend le même choix comme paramètre de requête, et les deux vocabulaires ne concordent pas : le chemin l’écrit .m3u8, tandis que la documentation communautaire de cette API donne comme valeurs de requête ts, hls et rtmp, avec ts par défaut. Notre propre commentaire de documentation à XtreamM3uPlusExportUri.cs:5 écrit output=ts|m3u8, une valeur que cette documentation ne liste pas, donc nous livrons la confusion dans un fichier source. Rien ne change dans la chaîne, et l’extension n’est jamais qu’une demande.
Notre dépôt contient deux constructeurs pour cette URL et ils divergent. Celui qui s’exécute sur l’appareil code en dur .ts. L’autre ajoute .m3u8 et n’a aucun appelant en dehors de son propre test. Pendant ce temps, chaque source Xtream porte un réglage persistant pour exactement cela, exposé sur les sources non agrégées comme un contrôle à deux positions libellé « Format de flux », options « MPEG-TS » et « HLS (m3u8) », indication « Conteneur demandé au portail Xtream ». Cherchez ce champ dans le client de bureau et vous trouvez le contrat d’API, la ligne du modèle de vue et la boîte de dialogue des réglages, nulle part ailleurs. Le constructeur d’URL ne le lit pas. Le chemin de lecture ne le lit pas.
Donc un utilisateur peut ouvrir les réglages de la source, passer en HLS, enregistrer, rouvrir la boîte de dialogue et voir HLS sélectionné, et l’appareil continuera de demander .ts pour chaque chaîne. La valeur fait l’aller-retour et ne change rien. Ce qui nous a surpris, c’est que celui-là est le nôtre, livré, et que personne ne l’a remarqué : le contrôle a été construit en même temps que le champ persistant et le constructeur n’y a jamais été câblé, si bien que le réglage rapporte un état qu’il n’a pas, ce qui est pire que de ne pas le proposer. Il est apparu pendant que je rassemblais des éléments pour cette page, jamais par un rapport de support, ce qui vous dit combien il est visible de l’extérieur.
Les classificateurs que nous exécutons bel et bien sur ces URL divergent aussi entre eux, de façon plus modeste. Le chien de garde de lecture décide hls ou ts en testant si l’URI entière contient la sous-chaîne .m3u8, donc un jeton dans une chaîne de requête compte. La boîte de dialogue Stream Information rapporte un conteneur en mettant en majuscules l’extension du chemin de l’URL, si bien qu’un point de terminaison get.php afficherait PHP, une ligne .mpd MPD, et les 15 lignes dont le chemin se termine par un groupe multicast et un port quelque chose de la forme 1:1234. Passez les deux sur le fichier de 1 895 lignes et ils divergent sur 6 lignes, chacune portant .m3u8 à l’intérieur d’une requête plutôt qu’en fin de chemin. Six lignes, ce n’est pas une crise, et le verdict du chien de garde est de la télémétrie qu’aucun seuil ne lit, donc rien n’agit dessus. Cela reste deux fonctions dans une même application qui répondent différemment à la même question, et aucune ne demande au démultiplexeur, le seul composant qui sait.
La limite, c’est que nous détenons trois fichiers sélectionnés. Les octets de playlist sont lus sur votre appareil, contre l’adresse que vous lui indiquez, et nous sélectionnons des adresses de guide de programmes et jamais les données du guide. Je peux donc vous dire à quoi ressemblent ces 2 209 entrées et ce que notre analyseur fait d’un manifeste. Je ne peux pas vous dire à quelle fréquence une URL .m3u8 dans la nature renvoie une liste de chaînes, parce que le mesurer voudrait dire tirer des corps de playlist depuis des adresses que des utilisateurs nous ont données.
Pour voir ce qu’un fichier contient réellement, les applications Windows et Xbox l’analysent localement et listent ce qui en est sorti ; un compte gratuit suffit pour l’essayer contre une source que vous avez déjà.
Pour qui écrit l’analyseur, la règle est plus étroite que « renifler le corps ». Décidez ce qu’est le fichier à partir de la première balise qui ne peut appartenir qu’à un seul format, et faites que cette décision produise un message. L’extension et le Content-Type sont des indices qui ne coûtent rien à vérifier et ne prouvent rien quand ils concordent. Le nôtre produit deux diagnostics qui nomment le mauvais problème et un import qui réussit tout en étant entièrement faux, et c’est le troisième qui vous coûte un fil de support.
Ce que cet article a mesuré34 affirmations, chacune avec les preuves derrière elles
| Réclamation | Preuve | Compté |
|---|---|---|
| La RFC 8216 identifie une playlist par son chemin OU par son Content-Type, le chemin peut se terminer par .m3u8 ou par .m3u, et les clients devraient refuser une playlist qui n’est identifiée par aucun des deux.RFC 8216 section 4, verbatim: Each Playlist file MUST be identifiable either by the path component of its URI or by HTTP Content-Type. In the first case, the path MUST end with either .m3u8 or .m3u. In the second, the HTTP Content-Type MUST be "application/vnd.apple.mpegurl" or "audio/mpegurl". Clients SHOULD refuse to parse Playlists that are not so identified. | Spécification | Sans objet |
| La RFC 8216 est de statut Informational, pas Standards Track, et une révision qui la rendrait obsolète et renommerait la Master Playlist en Multivariant Playlist est dans la file de l’éditeur RFC. La règle d’identification citée ici y est inchangée.RFC 8216 Status of This Memo, verbatim: This document is not an Internet Standards Track specification; it is published for informational purposes. Revision: draft-pantos-hls-rfc8216bis-22 (1 May 2026), datatracker state Sent to the RFC Editor, marked obsoletes 8216 (if approved), titled HTTP Live Streaming 2nd Edition, which introduces the Multivariant Playlist in place of the Master Playlist. | Spécification | Sans objet |
| La RFC 8216 exige l’UTF-8 pour toute playlist quelle que soit l’extension et demande aux clients d’échouer sur une marque d’ordre des octets.RFC 8216 section 4.1, verbatim: Playlist files MUST be encoded in UTF-8 [RFC3629]. They MUST NOT contain any Byte Order Mark (BOM); clients SHOULD fail to parse Playlists that contain a BOM or do not parse as UTF-8. | Spécification | Sans objet |
| La RFC 8216 définit le type d’une playlist par ce vers quoi pointent ses lignes URI, pas par son extension.RFC 8216 section 4.1, verbatim: A Playlist is a Media Playlist if all URI lines in the Playlist identify Media Segments. A Playlist is a Master Playlist if all URI lines in the Playlist identify Media Playlists. | Spécification | Sans objet |
| La RFC 8216 hérite exactement deux balises de l’ancien format M3U, EXTM3U et EXTINF. Toute autre balise qu’elle définit porte le préfixe EXT-X-, ce qui fait d’une ligne #EXT-X- un signal HLS exploitable. La RFC n’énonce aucune réservation du préfixe et ne définit aucun registre de balises.RFC 8216 section 4, verbatim: The format of the Playlist files is derived from the M3U [M3U] playlist file format and inherits two tags from that earlier file format: EXTM3U (Section 4.3.1.1) and EXTINF (Section 4.3.2.1). Section 4.1 says only: Tags begin with #EXT. They are case sensitive. Section 9 registers one media type and reserves no tag prefix. | Spécification | Sans objet |
| EXT-X-TARGETDURATION est obligatoire dans une Media Playlist, ce qui fait de son absence un signal exploitable.RFC 8216 section 4.3.3.1, verbatim: The EXT-X-TARGETDURATION tag is REQUIRED. | Spécification | Sans objet |
| EXTM3U doit être la première ligne de toute playlist, son format spécifié est la chaîne nue #EXTM3U, et les espaces sont interdits sauf là où une balise les spécifie explicitement. Une playlist qui viole ces règles est invalide et les clients doivent échouer à l’analyser.RFC 8216 section 4.3.1.1, verbatim: It MUST be the first line of every Media Playlist and every Master Playlist. Its format is: #EXTM3U. Section 4.1, verbatim: Whitespace MUST NOT be present, except for elements in which it is explicitly specified. Section 4, verbatim: Playlists that violate these rules are invalid; clients MUST fail to parse them. | Spécification | Sans objet |
| La durée #EXTINF est une valeur decimal-integer ou decimal-floating-point, et aucune des deux productions n’admet de signe moins, donc #EXTINF:-1 est hors de la grammaire de la RFC 8216.RFC 8216 section 4.3.2.1 (Its format is: #EXTINF:<duration>,[<title>]) with section 4.2, where decimal-integer is characters from [0..9] and decimal-floating-point is characters from [0..9] and '.' expressing a non-negative number; only signed-decimal-floating-point admits '-'. | Spécification | Sans objet |
| La RFC 8216 permet une URI de segment relative et permet à un serveur live de retirer des segments de la playlist à mesure que le flux avance. Ce sont deux permissions, pas une pratique exigée, et l’exemple live de la RFC elle-même utilise des URI de segment absolues.RFC 8216 section 4.1, verbatim: A URI in a Playlist, whether it is a URI line or part of a tag, MAY be relative. Section 6.2.2, verbatim: The server MAY limit the availability of Media Segments by removing Media Segments from the Playlist file (Section 6.2.1). If Media Segments are to be removed, the Playlist file MUST contain an EXT-X-MEDIA-SEQUENCE tag. Section 8.2, Live Media Playlist Using HTTPS, lists absolute https segment URIs. | Spécification | Sans objet |
| Le point de terminaison d’export de playlist de Xtream Codes documente output=ts, output=hls et output=rtmp, avec ts par défaut. m3u8 n’est pas l’une des valeurs de requête documentées, bien que .m3u8 soit l’orthographe de l’extension de chemin pour le même choix.Community reference documentation for the Xtream Codes API (zaclimon/xipl wiki, Xtream-Codes-API), verbatim on the output parameter: ts, hls and rtmp are available. By default it will be ts which represents the MPEG-TS container. | Spécification | Sans objet |
| Notre propre commentaire de documentation pour l’analyseur d’URL d’export Xtream documente la requête comme [&output=ts|m3u8], ce qui n’est pas une valeur que la documentation communautaire liste. | n = 1 | 23 août 2026 |
| Le corpus est fait de trois fichiers sélectionnés, 2 209 entrées EXTINF+URL, et pas une ligne dans aucun d’eux ne commence par #EXT-X-. | n = 2209 | 23 août 2026 |
| Le fichier nommé .m3u contient 308 lignes de chaînes dont 303 (98.4 pour cent) ont un chemin d’URL se terminant par .m3u8. Le fichier nommé .m3u8 contient 1 895 lignes de chaînes, est lui-même une liste de chaînes, et 1 621 de ses lignes (85.5 pour cent) ont aussi un chemin d’URL se terminant par .m3u8. Trier selon l’extension de l’URL interne classe donc les deux fichiers comme HLS. | n = 2203 | 23 août 2026 |
| Dans le fichier de 1 895 lignes, le chemin de l’URL se termine par .m3u8 sur 1 621 lignes et ne porte aucune extension sur 133 ; 15 lignes se terminent par un deux-points et un numéro de port que Path.GetExtension prend pour une extension ; 75 se terminent par .php, 17 par .mpd, 14 par .htm, 7 par .ts, 6 par .m3u, 3 par .2ts, et une ligne chacune se termine par .smil, .dash, .mp4 et .wmv. | n = 1895 | 23 août 2026 |
| 240 des 1 895 lignes portent un suffixe d’URL qui ne nomme aucun format média : 133 sans extension, 15 avec un deux-points et un port, 75 .php, 14 .htm et 3 .2ts. | n = 1895 | 23 août 2026 |
| Les trois fichiers se décodent en UTF-8 avec zéro caractère de remplacement et aucun ne porte de marque d’ordre des octets. Le fichier nommé .m3u a des caractères non ASCII dans 24 de ses noms d’affichage, et le fichier nommé .m3u8 dans 736 de ses noms d’affichage et un nom de groupe. | n = 2209 | 23 août 2026 |
| Sur l’ensemble des 2 209 entrées, 1 930 chemins d’URL se terminent par .m3u8 (87.4 pour cent) et 7 par .ts (0.3 pour cent). 368 entrées portent une chaîne de requête. | n = 2209 | 23 août 2026 |
| Les 2 209 lignes #EXTINF du corpus portent toutes une durée de -1. | n = 2209 | 23 août 2026 |
| Le reniflage du préambule lit au plus 8 192 octets. Dans le fichier de 1 895 lignes, la première ligne à elle seule fait 6 294 octets, laissant 1 898 octets de fenêtre, dans lesquels apparaissent 9 lignes #EXTINF complètes, 8 d’entre elles avec leur URL. Dans le fichier de 308 lignes, la première ligne fait 7 octets et 29 lignes #EXTINF complètes tiennent dans la même fenêtre, 28 d’entre elles avec leur URL. | n = 2 | 23 août 2026 |
| La ligne #EXTM3U du fichier de 1 895 lignes fait 6 294 octets et porte un attribut x-tvg-url contenant 101 adresses de guide séparées par des virgules sur 6 274 caractères. La ligne est en ASCII pur, donc octets et caractères concordent. | n = 1 | 23 août 2026 |
| Le reniflage du préambule saute une BOM UTF-8 facultative et les espaces de tête, puis accepte le fichier si les sept octets suivants sont #EXTM3U ou #EXTINF. Exécuté : il accepte une master playlist HLS, une media playlist HLS, une liste de chaînes sans en-tête et un fichier préfixé d’une BOM, et rejette une page HTML, un corps JSON et un fichier dont la première ligne est un simple commentaire #. | n = 11 | 23 août 2026 |
| Le seul appelant en production d’une garde de playlist au niveau des octets est sur l’appareil, et il s’exécute avant que le texte en clair soit chiffré pour l’envoi. La vérification de contenu jumelle du service catalogue n’a aucun appelant en production. | n = 1 | 23 août 2026 |
| Exécuté contre l’analyseur livré : une media playlist HLS avec des URI de segment absolues donne une chaîne par segment nommée Unnamed channel avec zéro diagnostic ; la même playlist avec des URI de segment relatives donne zéro chaîne et un diagnostic par segment ; une master playlist HLS avec des URI de rendition absolues donne zéro chaîne et un diagnostic URL without preceding EXTINF par rendition. | n = 3 | 23 août 2026 |
| Un titre vide après la virgule devient la chaîne littérale Unnamed channel, ce qui explique qu’une media playlist HLS s’importe comme une liste de lignes au nom identique plutôt que comme rien. | n = 1 | 23 août 2026 |
| Rien dans le client ni dans les services ne cherche une balise #EXT-X-. Un grep de EXT-X sur clients/windows/src et src ne renvoie aucun résultat hors des fixtures de test écrites pour cet article. | n = 1 | 23 août 2026 |
| Une garde de Content-Type pour les récupérations de playlist existe, est testée unitairement, et n’a aucun appelant en production aujourd’hui. Elle en avait un jusqu’à ce que le changement thin-catalog supprime le récupérateur côté serveur qui l’utilisait. | n = 1 | 23 août 2026 |
| Le rejet global audio/* de la garde exclut audio/x-mpegurl et audio/mpegurl. Le second est l’un des deux Content-Types que nomme la RFC 8216, donc sans cette exclusion la garde refuserait le type de la spécification elle-même. | n = 1 | 23 août 2026 |
| La garde d’envoi du catalogue rejette un octet nul n’importe où dans la fenêtre de reniflage, six séquences d’octets magiques de tête (PDF, MZ, ELF et trois variantes ZIP) et deux ouvertures HTML, puis applique le même reniflage de préambule. Rien en production ne l’appelle. | n = 8 | 23 août 2026 |
| L’enregistrement d’une URL de playlist n’applique la liste d’autorisation .m3u / .m3u8 que lorsque le chemin de l’URL a une extension, si bien qu’un chemin sans extension est enregistré sans examen et qu’un chemin se terminant par .txt est refusé. | n = 1 | 23 août 2026 |
| Deux constructeurs d’URL live Xtream existent dans le dépôt pour le même flux. Celui que l’appareil exécute ajoute .ts ; l’autre ajoute .m3u8 et n’a aucun appelant en dehors de son propre test. | n = 2 | 23 août 2026 |
| Le contrôle Format de flux par source, libellé MPEG-TS et HLS (m3u8) avec l’indication Conteneur demandé au portail Xtream, n’est proposé que sur les sources Xtream non agrégées, fait l’aller-retour vers le serveur et retour, et n’est jamais lu par le constructeur d’URL ni par le chemin de lecture de la tête de bureau. | n = 1 | 23 août 2026 |
| Le chien de garde de lecture classe une source en testant si l’URI entière contient .m3u8 ; la boîte de dialogue Stream Information rapporte un conteneur en mettant en majuscules l’extension du chemin de l’URL. Sur le fichier de 1 895 lignes, ils divergent sur 6 lignes, qui portent toutes .m3u8 uniquement dans une chaîne de requête. | n = 1895 | 23 août 2026 |
| Parce que la ligne conteneur est l’extension du chemin de l’URL en majuscules, dans le grand fichier 75 lignes afficheraient un conteneur PHP, 17 MPD, 14 HTM, 3 2TS, 133 rien du tout, et 15 une chaîne de la forme 1:1234 qui est la queue d’une adresse multicast et de son port. | n = 1895 | 23 août 2026 |
| La classification ts-ou-hls n’atteint aucun seuil, délai ni branche dans le chien de garde. Elle est transportée pour la télémétrie et pour des seuils par type que personne n’a écrits. | n = 1 | 23 août 2026 |