5.9 KiB
Validation du lot #5 — pistes texte embarquées
Protocole
Paquet 0.4.0, Jellyfin Server 12.0.0 (image figée dans tests/run.sh),
Jellyfin Web de cette image, Chromium 149.0.7827.55, Playwright 1.61.1.
Compte ordinaire Alice, compagnon de 375 × 812 pixels, préfixe /jellyfin.
bash tests/run.sh --test-name-pattern='embedded SRT'
node --test tests/history.test.mjs
bash tests/run.sh
Le serveur jetable contient trois copies Matroska de la vidéo originale avec
timecode incrusté, chacune avec une piste embarquée : SRT (subrip), WebVTT
(webvtt) ou ASS (ass). Les copies sont silencieuses : le conteneur et la
vidéo commencent à zéro, sans prélecture audio AAC. La piste externe SRT du
lot #3 est réutilisée pour le premier média ; les nouvelles fixtures VTT et ASS
contiennent des accents, des styles et du texte ressemblant à du HTML actif.
Les pistes externes et le média sans sous-titres des lots précédents sont conservés.
Pour chaque format, la première requête authentifiée précède toute lecture du
média, sur un serveur sans cache d'extraction préexistant. La requête suivante
utilise le cache de Jellyfin. Les durées incluent HTTP, extraction éventuelle,
conversion JSON et lecture de la réponse ; ce ne sont ni des mesures de disque
froid ni des mesures de synchronisation. Les données brutes sont écrites dans
.test-state/issue-5/loading.json.
Le lecteur Web ouvre ensuite chaque média à 35 s. Le compagnon vérifie la source réellement lue, sélectionne la piste embarquée et consulte l'historique sans piste d'aide. Une réponse réelle est retenue à la frontière HTTP pour observer le chargement. Une requête vers un indice inexistant produit ensuite une vraie réponse 404 du plugin : le compagnon affiche l'erreur et vide l'historique.
Résultats
Le 17 septembre 2026, compilation C# sans avertissement, vérification
TypeScript et suite complète réussies : 8 tests sur 8. Le contrôle du plugin
sans préfixe réussit également avant la suite sous /jellyfin.
Durées du dernier passage complet (une requête par état et format, pas un benchmark statistique) :
| Piste embarquée | À froid | À chaud |
|---|---|---|
| SRT | 47,14 ms | 13,30 ms |
| WebVTT | 38,14 ms | 13,05 ms |
| ASS | 40,48 ms | 12,89 ms |
Le parcours installé ciblé réussit pour les trois formats : les événements commencent à 5 s et finissent à 6 s sur l'origine du média ; l'historique à 35 s contient les blocs attendus. Les accents et les retours à la ligne restent lisibles, les commandes ASS disparaissent, aucun élément HTML actif n'est créé. Le chargement puis l'erreur 404 sont affichés explicitement et sans ancien historique. L'accès anonyme à chaque piste embarquée est refusé (401).
Le cycle test-échec/correction a reproduit la sélection embarquée absente, le refus serveur 400, l'expiration après huit secondes et les commandes ASS visibles. Les contrôles navigateur ciblés passent après correction.
Revue
Standards : 0 constat. Spec : 0 constat restant ; le problème de lisibilité ASS trouvé pendant la vérification a été corrigé et revérifié. Deux agents ont examiné séparément ces axes.
Couverture et limites
La route conserve le contrôle d'accès au média et utilise directement
ISubtitleEncoder.GetSubtitles avec l'origine complète et la conservation des
horodatages. L'extraction et son cache appartiennent à Jellyfin ; aucun second
plugin, parseur multi-format, service d'extraction, OCR ou fournisseur externe
n'est ajouté. Jellyfin laisse les commandes de style/position ASS dans le JSON :
le compagnon retire ces blocs de commande uniquement pour les codecs ASS/SSA.
Les retours à la ligne sont déjà décodés par Jellyfin. Le rendu reste du
textContent, sans contenu HTML actif.
Les contrôles à la frontière navigateur/API couvrent une extraction dépassant huit secondes, les réponses tardives après changement de piste, source ou média, les données invalides et la perte de connexion. Les inventaires PGS/VobSub sont simulés : les sélecteurs sont désactivés et aucune requête de sous-titres ne part. Ils ne constituent pas une qualification de fichiers graphiques réels. Le parcours installé existant couvre le changement vers un média sans piste texte et la non-régression des sous-titres externes.
Le chargement des sous-titres a une limite de deux minutes, indépendante des huit secondes des autres requêtes. Après un échec, désélectionner puis resélectionner la piste permet de réessayer. Les réponses périmées sont ignorées ; elles ne sont pas annulées activement lors d'un changement de contexte.
Une variante initiale avec audio AAC a produit un décalage de 23 ms :
FFmpeg normalise l'origine du conteneur qui inclut une prélecture audio négative.
Le phénomène a été reproduit directement en extraction FFmpeg ; l'option de
muxage avoid_negative_ts=disabled conserve les PTS des paquets mais n'empêche
pas cette normalisation à l'extraction. Aucun décalage correctif arbitraire n'est
ajouté au compagnon. Les assertions exactes de ce lot portent sur les médias
silencieux à origine zéro ; les autres origines et clients restent à qualifier.
Le code d'extraction de Jellyfin
est la référence du mécanisme réutilisé.
La qualification bilingue assemblée et les mesures multi-clients appartiennent au dernier lot. Les délais ci-dessus ne démontrent pas le seuil de synchronisation de 500 ms. Dans le parcours externe dédié de cette exécution, les six écarts en lecture stable sont 1 229, 1 909, 1 589, 1 269, 1 949 et 1 629 ms : objectif de moins de 500 ms non atteint. Le recalage après déplacement est de 1 292,70 ms, sous l'objectif de deux secondes. La réussite fonctionnelle des huit tests ne transforme pas cet échec de précision en validation.