Files

5.9 KiB
Raw Permalink Blame History

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.