Communitygithub.com

zimodzh/hls-dot0-to-mp4-skill

Compétence d'agent : conversion du cache `.0` HLS (aq.m3u8.0 · *.ts.0 · *.key.0) du navigateur Huawei (sniff-download / 资源嗅探) en MP4 lisible sur PC. Remux local uniquement, pas de scraping d'URL, pas de DRM.

Qu'est-ce que hls-dot0-to-mp4-skill ?

Cette compétence d'agent résout le problème des vidéos téléchargées via la fonction de 'sniff-download' du navigateur Huawei, qui stocke les fichiers HLS chiffrés (AES-128) dans des dossiers UUID, en ajoutant un suffixe `.0` à chaque nom de fichier. Bien que ces vidéos soient lisibles sur le téléphone, elles ne le sont pas sur PC car FFmpeg et les lecteurs classiques ne reconnaissent pas ces extensions non standard. La compétence fonctionne en créant des liens physiques (hardlinks) des fichiers `.ts.0` et `.key.0` vers leurs noms sans `.0`, puis en utilisant FFmpeg (`-c copy`) pour remuxer le flux en MP4, et enfin en nettoyant les fichiers temporaires créés. Elle est conçue pour les caches du navigateur Huawei uniquement (non testée avec d'autres fournisseurs). L'agent doit d'abord localiser FFmpeg (recherche bornée sans scan complet du disque) ou demander à l'utilisateur de l'installer via des instructions spécifiques. Le workflow inclut un planification avec `--dry-run`, une conversion par lot avec numérotation des fichiers de sortie, et un rapport détaillé incluant les avertissements SPS. La compétence prend en charge les agents conversationnels (Claude Code, Cursor, Codex) et utilise un script Python (`scripts/convert.py`) pour automatiser les étapes.

Compatible avec~Claude Code~Codex CLI✓Cursor
npx skills add zimodzh/hls-dot0-to-mp4-skill

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

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 :

  1. --ffmpeg / variable d'environnement HLS_DOT0_FFMPEG
  2. <racine-cache>/ffmpeg.exe ou <racine-cache>/ffmpeg
  3. PATH (where.exe ffmpeg / command -v ffmpeg)
  4. 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.0 et .key.0 (les outils de recherche peuvent mentir)
  • ffmpeg trouvé (recherche bornée) ou l'utilisateur a choisi A/B ; -version ok ; pas de scan complet du disque
  • Si installation : OS/arch détecté ; uniquement les commandes correspondantes dans references/ffmpeg-install.md
  • Le plan --dry-run semble correct (comptages, noms de sortie, SKIP sur 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

  • .0 est 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 period est 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 pssh dans les logs DLEngine), pas de contournement Widevine.
  • Pas de ffmpeg → demandez A/B d'abord. Ne lancez pas silencieusement winget/brew/apt ou ne téléchargez pas un exe.
  • Les 01.mp4 existants… sont ignorés, pas des erreurs. Utilisez --force uniquement quand l'utilisateur veut que ces fichiers soient écrasés.

Skills associés