Cache HLS .0 → MP4
Le sniff-download du navigateur Huawei stocke chaque vidéo dans un dossier UUID contenant du HLS chiffré, puis ajoute .0 à chaque nom de fichier. Le lecteur du téléphone utilise sa propre base de données et ces noms. Les lecteurs PC et FFmpeg ne le font pas.
Cette compétence convertit ce cache en créant des liens physiques (hardlinks) .ts.0→.ts et .key.0→.key, en utilisant la playlist originale avec FFmpeg (-c copy), puis en supprimant uniquement les noms temporaires. Vérifié sur les caches du navigateur Huawei. Non testé avec d'autres fournisseurs.
Quand l'utiliser
Activez si l'une de ces conditions est vraie :
- Les noms de dossiers ressemblent à
64f1723d-421b-495c-8a10-85ab7d74ddab - Fichiers nommés
aq.m3u8.0,*.ts.0,*.key.0 - L'utilisateur mentionne 嗅探下载 / 华为浏览器 / VideoData / 手机能播电脑不能
- Les lignes de log contiennent
DLEngine,DLSegMgr,download_content_
À ne pas utiliser pour : télécharger une URL m3u8 (c'est le rôle de N_m3u8DL-RE / 猫抓), le DRM Widevine/PSSH, ou le remux d'un .mp4 déjà clair.
Structure (ne pas se fier à la recherche dans l'espace de travail)
Cursor/ripgrep ignorent les fichiers binaires *.0. Glob **/*.ts.0 renvoie 0 même si 73 segments existent. Prouvez l'existence des fichiers avec un listing de répertoire (Get-ChildItem / dir / Path.iterdir), ou en lisant un chemin nommé d'après la playlist (erreur de lecture binaire = fichier existe).
Chaque dossier vidéo :
<uuid>//
aq.m3u8.0 # playlist ; référence foo.ts et foo.key (sans .0)
<digits>.ts.0 # AES-128 MPEG-TS, ~10s chacun
<digits>.key.0 # clé HLS 16 octets
Le dossier facultatif log/<uuid>.txt est du texte DLEngine, pas un média.
Consultez references/layout.md si l'arborescence diffère (clé manquante, dossiers imbriqués, pas de aq.m3u8.0).
Flux de travail
Barrière stricte — à faire avant toute conversion ou téléchargement.
0. Trouver ffmpeg, ou s'arrêter et demander
Recherche bornée uniquement (ne jamais parcourir un disque entier). scripts/convert.py utilise le même ordre :
--ffmpeg/ variable d'environnementHLS_DOT0_FFMPEG<racine-cache>/ffmpeg.exeou<racine-cache>/ffmpegPATH(where.exe ffmpeg/command -v ffmpeg)- Quelques répertoires courants si toujours manquant :
%LOCALAPPDATA%\Microsoft\WinGet\Links\ffmpeg.exe,%USERPROFILE%\scoop\shims\ffmpeg.exe,C:\ffmpeg\bin\ffmpeg.exe,/opt/homebrew/bin/ffmpeg,/usr/local/bin/ffmpeg
Exécutez ffmpeg -version (ou le chemin absolu). Succès → passez à l'étape 1.
Si introuvable, arrêtez-vous. Proposez à l'utilisateur exactement ces deux options ; n'installez ni ne convertissez avant qu'il ne réponde :
- A. Il installe lui-même
ffmpeg, puis vous prévient quand c'est prêt — relancez cette recherche +-version. - B. Vous l'installez — détectez d'abord l'OS et l'architecture (
win32+PROCESSOR_ARCHITECTURE/uname -s+uname -m). Suivez ensuite uniquement la valeur par défaut correspondante dans references/ffmpeg-install.md.
Règles d'installation : une commande par défaut, une solution de repli en cas d'échec, puis demandez à nouveau. N'installez pas Homebrew / Chocolatey / Scoop juste pour obtenir ffmpeg, sauf si l'utilisateur est d'accord. Ne commitez pas un binaire téléchargé dans ce dépôt de compétence. Après une installation réussie, vérifiez -version dans un nouveau shell ou via le chemin de l'installateur (le PATH Windows est souvent obsolète).
1. Planifier (afficher, puis convertir)
Listez les répertoires UUID (8-4-4-4-12 hex). Pour chacun, comptez *.ts.0, *.key.0, et vérifiez si aq.m3u8.0 existe. Ignorez les dossiers avec 0 segments ou sans clé.
Ordre par défaut : nom de dossier A–Z. Numérotez les sorties 01.mp4, 02.mp4, … dans --out-dir (par défaut <racine-cache>/mp4) à partir de --start (par défaut 1). Le script saute un nom quand ce mp4 existe déjà (JSON skipped: true) sauf si --force est utilisé. Relancez la même commande après un lot partiel — les numéros déjà faits restent, le reste est converti. N'inventez pas un second système de numérotation.
2. Exécuter le script fourni (ne pas réinventer)
Depuis la racine de cette compétence :
python scripts/convert.py --root <racine-cache> --dry-run
python scripts/convert.py --root <racine-cache> --out-dir <racine-cache>/mp4 --start 1
python scripts/convert.py --root <racine-cache> --folder <uuid> --name 01 --force
Passez toujours --dry-run en premier sur une nouvelle arborescence. La sortie standard du script est du JSON ; la progression va vers stderr.
Ne pas réécrire la playlist en *.ts.0. FFmpeg rejette cette extension même avec -allowed_extensions ALL (not in allowed_segment_extensions). Créez un lien physique/copie vers les noms déjà présents dans aq.m3u8.0.
Ne pas sonder les sorties avec PowerShell $ErrorActionPreference = "Stop" plus ffmpeg -i fichier -f null -. FFmpeg écrit la bannière sur stderr ; PowerShell la traite comme une erreur fatale et un catch supprimant le mp4 effacera une conversion réussie.
Drapeaux FFmpeg exacts (fragiles — ne pas omettre) :
ffmpeg -y -hide_banner -loglevel warning -stats -allowed_extensions ALL -protocol_whitelist file,crypto,data -i play.m3u8 -c copy out.mp4
3. Nettoyage et rapport
Le script supprime uniquement les noms temporaires qu'il a créés lors de cette exécution (plus les liens physiques restants qui pointent déjà vers les fichiers .0) et supprime toujours play.m3u8. Les fichiers *.ts.0 / *.key.0 / aq.m3u8.0 d'origine restent. Il ne supprime pas un .ts / .key préexistant qui n'est pas un lien physique vers le fichier .0.
Rapportez un tableau : numéro, taille, durée si connue, sps_warning. Voir references/troubleshooting.md pour les SPS et autres échecs.
Si l'utilisateur demande de ré-encoder un fichier avec avertissement SPS : ffmpeg -i 04.mp4 -c:v libx264 -crf 18 -c:a copy 04_fixed.mp4 — uniquement ces fichiers, pas tout le lot.
Liste de vérification
- Le listing du répertoire montre
.ts.0et.key.0(les outils de recherche peuvent mentir) - ffmpeg trouvé (recherche bornée) ou l'utilisateur a choisi A/B ;
-versionok ; pas de scan complet du disque - Si installation : OS/arch détecté ; uniquement les commandes correspondantes dans
references/ffmpeg-install.md - Le plan
--dry-runsemble correct (comptages, noms de sortie,SKIPsur mp4 existants) - Un dossier converti et l'utilisateur peut le lire (sauf s'il a demandé de tout convertir)
- Batch JSON
ok/skipped/ erreurs par élément ; liens temporaires supprimés - Mentionnez les numéros avec avertissement SPS pour que l'utilisateur puisse vérifier
Format de sortie
Converti N/M vidéos → <dossier-sortie>
01.mp4 101 Mo (~12:10) ok
04.mp4 251 Mo (~23:59) Avertissement SPS — vérifier le début et les coupures à ~10s
ÉCHEC <uuid> clé.0 manquante
Pièges
.0est le vrai média. Le fait que Glob/index ignore les fichiers binaires n'est pas « fichiers manquants ».- Playlist
URI="….key"et….ts— sur le disque ils sont….key.0/….ts.0. - Les liens physiques doivent rester sur le même volume ; si
os.linkéchoue, copiez (lent, disque supplémentaire). non-existing SPS 0 referenced in buffering periodest généralement cosmétique avec-c copy. Vérifiez les limites à 10s ; ré-encodez uniquement si la lecture est cassée.- Les outils GUI (N_m3u8DL-RE, m3u8-to-mp4) attendent des extensions standard. Ils fonctionnent après renommage/lien physique, pas sur les noms bruts Huawei.
- Il s'agit de HLS AES-128 standard avec une clé locale (
no psshdans les logs DLEngine), pas de contournement Widevine. - Pas de ffmpeg → demandez A/B d'abord. Ne lancez pas silencieusement
winget/brew/aptou ne téléchargez pas un exe. - Les
01.mp4existants… sont ignorés, pas des erreurs. Utilisez--forceuniquement quand l'utilisateur veut que ces fichiers soient écrasés.