Communitygithub.com

Lumos12345/Extraction-de-texte-video

Extraire les paroles/sous-titres avec horodatages à partir de fichiers vidéo/audio locaux : transcription via whisper + OCR du texte incrusté (hardsub).

Qu'est-ce que Extraction-de-texte-video ?

Cette compétence permet d'extraire des paroles ou sous-titres horodatés à partir de fichiers vidéo ou audio locaux, notamment lorsqu'une vidéo téléchargée ne contient pas de piste de sous-titres logiciels mais affiche du texte incrusté (hardsub). Elle prend en charge les formats courants comme .mp4, .m4s, .mkv, .m4a et .mp3. La compétence utilise une approche hiérarchique : d'abord la recherche de sous-titres logiciels (extraction directe), puis l'OCR du texte incrusté (via Tesseract et vision_analyze pour les cas difficiles), et enfin la transcription audio via faster-whisper pour les fichiers audio uniquement. Elle est particulièrement utile pour les vidéos Bilibili/YouTube, les karaokés, les AMV et les clips musicaux. La compétence produit des fichiers .lrc ou des transcriptions horodatées, et s'enchaîne naturellement avec la compétence `guitar-tabs` pour générer des grilles d'accords synchronisées.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add Lumos12345/video-text-extraction

Demander à votre IA préférée

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

Documentation

Extraction de texte vidéo / audio

Produire un fichier de transcription ou de paroles horodaté à partir d'un fichier média local (.mp4, .m4s, .mkv, .m4a, .mp3). Gère le cas courant où une vidéo téléchargée ne contient pas de piste de sous-titres logiciels mais possède du texte incrusté (hardsub) dans l'image, ainsi que le cas où l'on ne dispose que de l'audio.

Quand l'utiliser

  • « Extrais les paroles / sous-titres de cette vidéo et marque l'heure de début de chaque ligne. »
  • « Transcris cet audio avec des horodatages. »
  • Fichiers .m4s/.m4a téléchargés depuis Bilibili/YouTube ; karaokés/AMV/clips musicaux où les paroles sont rendues dans l'image.
  • Toute demande souhaitant un format .lrc ou .srt.

Étape 0 — Inspecter d'abord, toujours

ffprobe -v quiet -print_format json -show_streams -show_format FICHIER | python3 -m json.tool

Éléments clés à identifier :

  • Flux présents. Les fichiers .m4s de Bilibili sont souvent vidéo uniquement (l'audio se trouve dans un autre fichier .m4s/.m4a). S'il n'y a pas de flux audio, trouver le fichier audio compagnon dans le même dossier en faisant correspondre la durée.
  • Sous-titres logiciels ? ffprobe ... -select_streams s — si un flux de sous-titres existe, l'extraire directement (ffmpeg -i FICHIER -map 0:s:0 out.srt) et ignorer tout travail d'OCR/whisper. C'est le chemin le plus rapide.
  • Durée. L'utiliser pour trouver le fichier audio correct lorsque la vidéo n'en a pas.
  • Le carton titre n'est pas la bande de sous-titres. L'image ~0 porte souvent un grand titre + un overlay d'interprète dans une position et une police différentes des véritables sous-titres de paroles. En dériver des coordonnées de recadrage produit une bande qui manque chaque parole. Échantillonner plutôt une image du milieu de la chanson (avec une longue ligne de paroles visible) — et lire le carton titre séparément si vous avez besoin du nom de la chanson/de l'artiste.
  • Confirmer la chanson avant de transcrire. Un nom de fichier et un carton titre peuvent ne pas correspondre au nom que l'utilisateur donne au morceau. Si l'audio/les paroles ne correspondent pas au nom attendu, le dire avant de produire une transcription complète — et si la vidéo contient plusieurs chansons, dire laquelle vous avez effectivement transcrite.

Étape 1 — Déterminer la source de texte (ordre de priorité)

  1. Flux de sous-titres logiciels → extraire directement. Terminé.
  2. Texte incrusté (hardsub) → OCR des images (Étape 3). Cela donne le texte officiel, correctement orthographié. À privilégier lorsque la vidéo affiche visiblement des paroles/sous-titres.
  3. Audio uniquement, pas de texte à l'écran → transcription whisper (Étape 2).

Si les DEUX texte à l'écran et transcription audio existent, utiliser l'OCR pour les mots et whisper pour le minutage/l'orientation — le texte OCR est l'orthographe de référence, whisper donne la grille temporelle mais méprend grandement les mots chantés (par exemple, il a entendu « pédophiles » pour « pétales », « frit bien » pour une voyelle chantée). Se recouper mutuellement.

Étape 2 — Transcription audio (whisper)

Installation unique (voir references/whisper-setup.md pour le correctif miroir HF en Chine continentale) :

uv venv /tmp/wvenv
/tmp/wvenv/bin/python -m pip install faster-whisper

Extraire un WAV mono 16 kHz, optionnellement normalisé :

ffmpeg -y -i AUDIO -af "loudnorm=I=-16:TP=-1.5:LRA=11,highpass=f=80" -ar 16000 -ac 1 -c:a pcm_s16le /tmp/song.wav

Transcrire (script dans scripts/transcribe.py) :

HF_HUB_DISABLE_XET=1 HF_ENDPOINT=https://hf-mirror.com \
  /tmp/wvenv/bin/python scripts/transcribe.py /tmp/song.wav medium
  • Le modèle medium est le meilleur compromis ; large-v3 est plus précis mais lent sur CPU.
  • medium sur CPU (int8) transcrit une chanson d'environ 2,5 min en quelques minutes ; le processus a une faible RSS pendant le chargement du modèle, puis monte à environ 1,4 Go RSS pendant la transcription effective — ne pas le tuer paniqué pendant la phase de chargement, vérifier /proc/<pid>/status VmRSS à la place.
  • Ne PAS utiliser le filtrage VAD pour le chant. vad_filter=True supprime les lignes vocales douces/réverbérées et peut réduire une chanson de 3 minutes à une poignée de segments. Transcrire la piste entière.
  • Réglage « chant » fonctionnel (pas de VAD) : beam_size=5, condition_on_previous_text=True, repli de température [0.0,0.2,0.4,0.6,0.8,1.0], no_speech_threshold=0.8, log_prob_threshold=-1.5, compression_ratio_threshold=2.8, word_timestamps=True, hallucination_silence_threshold=1.5. (Les valeurs par défaut suppriment des phrases entières et émettent des hallucinations de silence sur les intervalles instrumentaux.)

Étape 3 — OCR du texte incrusté (le chemin à forte valeur ajoutée)

Guide complet : references/hardsub-ocr.md. Résumé :

  1. Installer tesseract sans sudo en extrayant les .deb vers un préfixe (détails dans la référence). Les corrections de liens symboliques pour liblept.so.5 et libarchive.so.13 y sont documentées.
  2. Trouver la région de texte : lire une image avec vision_analyze et demander les coordonnées en pixels de la bande de sous-titres. Les sous-titres sont généralement en bas à gauche sur les clips musicaux — NE PAS deviner.
  3. Extraire les images densément : ffmpeg -i SRC -vf fps=2 /tmp/frames/f_%04d.png (2 ips → résolution ~0,5 s ; l'image N est à t = N/2 s).
  4. Recadrer la bande, agrandir 2–3×, niveaux de gris, OCR chaque image (--psm 6 ou --psm 7).
  5. Dédoublonnage : les images consécutives répétant une ligne = une ligne de paroles ; la première lecture propre donne son heure de début.
  6. Texte à faible contraste : recourir à vision_analyze. Tesseract échoue sur les textes sérigraphiés pâles sur fond clair/photo. Le modèle de vision les lit fiablement — l'utiliser pour les images sur lesquelles tesseract renvoie des absurdités. Ce hybride (Tesseract en masse + vision pour les cas difficiles) est le modèle de production.

Résultat

Produire un fichier .lrc lorsque l'utilisateur demande des paroles + horodatages ([mm:ss.xx]ligne), sinon MM:SS texte brut. Sauvegarder dans le chemin nommé par l'utilisateur (généralement leur Bureau Windows lorsqu'ils sont sur WSL, par exemple /mnt/c/Users/<utilisateur>/Desktop/).

Transfert : le fichier .lrc produit ici est exactement l'entrée dont la compétence guitar-tabs a besoin pour sa grille d'accords synchronisée avec le LRC / alignement d'accords par ligne. Lorsqu'une demande de paroles puis de tablatures arrive comme une seule tâche, conserver le .lrc et le fournir directement à guitar-tabs (son scripts/chord_analyze.py prend <audio> <lyrics.lrc> et imprime un accord par ligne de paroles). Les deux compétences s'enchaînent : video-text-extraction → paroles horodatées → guitar-tabs → tablature d'accompagnement.

Pièges

  • .m4s est généralement vidéo uniquement. Ne pas supposer qu'il contient de l'audio. Faire correspondre le fichier audio compagnon par la durée.
  • Ne pas faire confiance à l'orthographe de whisper pour les voix chantées. Vérifier contre le texte à l'écran lorsqu'il est disponible.
  • Le VAD supprime les voix douces — voir Étape 2.
  • Tesseract nécessite un recadrage précis. Une bande décalée verticalement d'environ 100 px renvoie du bruit. Obtenir d'abord les coordonnées via la vision.
  • Les dépendances de bibliothèques partagées de Tesseract arrivent une par une. Chaque exécution échoue avec une error while loading shared libraries: X différente — liblept.so.5, puis libarchive.so.13, puis libgif.so.7, etc. Ne pas abandonner et ne pas installer une par commande : télécharger toute la liste d'un coup (voir la référence), extraire, puis ldd … | grep "not found" pour voir tout ce qui manque encore en un seul passage. Deux pièges supplémentaires : libarchive13 n'a pas de candidate sur Ubuntu plus récent (utiliser libarchive13t64), et liblept5 est le paquet qui contient le véritable liblept.so.5.0.4 — le paquet -dev ne fournit que des liens symboliques pendants.
  • Une lecture OCR courte/dénaturée est souvent un problème de recadrage, pas un problème d'OCR. Avant de régler --psm ou les seuils, utiliser vision_analyze sur la bande recadrée elle-même. Si la vision ne voit pas non plus de texte, le recadrage est erroné. Cette unique vérification évite beaucoup de réglages de filtres inutiles.
  • Les commandes terminal avec export / pipes peuvent nécessiter une approbation. Regrouper les variables d'environnement tesseract dans un script .sh et exécuter bash script.sh plutôt que des export ...; tesseract ... en ligne.
  • HuggingFace est lent/bloqué en Chine continentale. Toujours définir HF_ENDPOINT=https://hf-mirror.com ET HF_HUB_DISABLE_XET=1 (le backend xet renvoie une 401 contre le miroir).
  • Vérifier que le téléchargement du modèle progresse réellement. Une exécution de faster-whisper qui reste à environ 5 Mo RSS et 0 jiffies CPU est bloquée à récupérer le modèle ; une exécution réelle monte à environ 1,4 Go RSS. Inspecter /proc/<pid>/status (VmRSS) plutôt que de le tuer ou d'attendre aveuglément.

Skills associés