Communitygithub.com

Tofuswang/video-subtitle-skill

Compétence Claude Code : ajouter des sous-titres aux vidéos avec Whisper local + ffmpeg. 5★.

Qu'est-ce que video-subtitle-skill ?

Cette compétence permet d'ajouter automatiquement des sous-titres à des vidéos en utilisant des modèles Whisper locaux (mlx-whisper sur Apple Silicon ou openai-whisper) et ffmpeg. Elle prend en charge le pipeline complet : extraction audio, transcription en SRT, nettoyage du fichier SRT (suppression des hallucinations, correction des noms propres, fusion des fragments), et incrustation des sous-titres dans la vidéo via le filtre subtitles de ffmpeg. L'utilisateur peut également demander uniquement la génération du SRT ou l'incrustation d'un SRT existant. La compétence fonctionne sur macOS (avec recommandation d'utiliser ffmpeg-full pour le support libass) et Linux. Elle est conçue pour Claude Code et s'active par la commande `/video-subtitle`. La qualité est assurée par la vérification de la fidélité de la transcription, la correction des erreurs courantes de Whisper et le respect des règles de sous-titrage (max deux lignes, ~20 caractères CJK par ligne).

Compatible avec✓Claude Code✓Codex CLI~Cursor
npx skills add Tofuswang/video-subtitle-skill

Demander à votre IA préférée

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

Documentation

/video-subtitle — Outil de sous-titrage vidéo

Transcrire l'audio d'une vidéo en sous-titres SRT à l'aide d'un modèle Whisper local, puis les incruster dans la vidéo.

Invocable par l'utilisateur

Lorsque l'utilisateur tape /video-subtitle, exécutez cette compétence.

Prérequis

Cette compétence nécessite deux outils. Vérifiez leur disponibilité avant de procéder :

1. mlx-whisper (Apple Silicon) ou openai-whisper

Détectez lequel est disponible :

which mlx_whisper whisper 2>/dev/null

Si aucun n'est trouvé, guidez l'utilisateur pour en installer un :

  • Mac Apple Silicon (recommandé) : pip install mlx-whisper
  • Toute plateforme : pip install openai-whisper

2. ffmpeg avec libass

Vérifiez le support de libass :

ffmpeg -filters 2>&1 | grep subtitles

Si aucune sortie (libass manquant), le filtre subtitles est indisponible :

  • macOS : brew install ffmpeg-full (keg-only, utilisez /opt/homebrew/opt/ffmpeg-full/bin/ffmpeg)
  • Linux : sudo apt install ffmpeg (inclut généralement libass)
  • Solution de repli : Si l'utilisateur a ffmpeg classique sans libass, intégrez doucement le SRT comme piste de sous-titres au lieu de l'incruster.

Sélection du modèle Whisper

Découvrez les modèles en cache :

ls ~/.cache/huggingface/hub/ 2>/dev/null | grep whisper

Préférez le modèle le plus grand disponible. Si aucun n'est en cache, utilisez :

  • mlx-whisper : mlx-community/whisper-large-v3-mlx
  • openai-whisper : large-v3

Modes

  • /video-subtitle chemin/vers/video.mov → Pipeline complet (transcription + correction + incrustation)
  • /video-subtitle srt chemin/vers/video.mov → SRT uniquement (transcription, sans incrustation)
  • /video-subtitle burn chemin/vers/video.mov chemin/vers/sub.srt → Incrustation uniquement (utiliser un SRT existant)
  • /video-subtitle (sans argument) → Interactif, demander le chemin de la vidéo

Pipeline complet

Étape 1 : Vérifier la vidéo

Si aucun chemin n'est fourni, demandez-le avec AskUserQuestion. Confirmez que le fichier existe et lisez les métadonnées :

ffmpeg -i "<video_path>" 2>&1 | grep -E "Duration|Stream.*(Video|Audio)"

Signalez la durée, la résolution et la taille du fichier à l'utilisateur.

Étape 2 : Extraire l'audio

ffmpeg -i "<video_path>" -vn -acodec pcm_s16le -ar 16000 -ac 1 "<output_dir>/<basename>_audio.wav" -y

Le WAV mono 16 kHz est le format d'entrée optimal pour Whisper.

Étape 3 : Confirmer la langue

Demandez à l'utilisateur avec AskUserQuestion. Options courantes :

LangueDrapeau
Chinois--language zh
Anglais--language en
Japonais--language ja
Détection autoomettre --language

Étape 4 : Transcrire

mlx-whisper :

mlx_whisper --model "<model>" --language <lang> --output-format srt --output-dir "<output_dir>" "<audio_wav>"

openai-whisper :

whisper "<audio_wav>" --model large-v3 --language <lang> --output_format srt --output_dir "<output_dir>"

Dites à l'utilisateur : « Transcription en cours, veuillez patienter... »

Étape 5 : Nettoyer le SRT

Lisez le SRT généré et corrigez :

  1. Supprimer les hallucinations : Supprimez les entrées avec des horodatages de durée nulle (ex. 00:00:57,640 --> 00:00:57,640) ou un texte vide
  2. Corriger les noms propres : Whisper reconnaît mal les noms de marques et les termes techniques — utilisez le contexte de la conversation pour corriger
  3. Fusionner les fragments : Combinez les entrées plus courtes que 0,5s qui sont sémantiquement liées
  4. Re numéroter : Exécutez cet extrait Python pour re numéroter toutes les entrées :
python3 -c "
import re
with open('<srt_path>', 'r') as f:
    content = f.read()
blocks = re.split(r'\n\n+', content.strip())
out = []
for i, block in enumerate(blocks, 1):
    lines = block.strip().split('\n')
    if len(lines) >= 2:
        lines[0] = str(i)
        out.append('\n'.join(lines))
with open('<srt_path>', 'w') as f:
    f.write('\n\n'.join(out) + '\n')
"

Présentez le SRT corrigé à l'utilisateur et demandez si d'autres modifications sont nécessaires avant l'incrustation.

Étape 6 : Incruster les sous-titres

Déterminez le bon binaire ffmpeg (préférez ffmpeg-full si ffmpeg classique manque de libass) :

FFMPEG="ffmpeg"
if ! ffmpeg -filters 2>&1 | grep -q subtitles; then
  if [ -x /opt/homebrew/opt/ffmpeg-full/bin/ffmpeg ]; then
    FFMPEG="/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg"
  fi
fi

Puis incrustez :

$FFMPEG \
  -i "<video_path>" \
  -vf "subtitles=<srt_path>:force_style='FontSize=24,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,Outline=2,MarginV=30'" \
  -c:v libx264 -preset medium -crf 23 \
  -c:a aac -b:a 128k \
  -pix_fmt yuv420p \
  "<output_dir>/<basename>_subtitled.mp4" -y

Options force_style :

ParamètreValeur par défautDescription
FontSize24Taille de police
PrimaryColour&H00FFFFFFTexte blanc
OutlineColour&H00000000Contour noir
Outline2Épaisseur du contour
MarginV30Marge inférieure

Important : Le chemin du fichier SRT ne doit pas contenir de caractères spéciaux qui perturbent l'analyseur de filtre ffmpeg. Utilisez des chemins relatifs ou un lien symbolique si nécessaire.

Étape 7 : Terminé

Signalez le chemin et la taille du fichier de sortie. Suggérez open <chemin> pour prévisualiser. Rappelez à l'utilisateur que le fichier intermédiaire _audio.wav peut être supprimé.


Dépannage

ProblèmeCauseSolution
No such filter: 'subtitles'ffmpeg manque libassUtilisez ffmpeg-full ou installez libass
No such filter: 'drawtext'ffmpeg manque libfreetypeUtilisez ffmpeg-full
Entrées SRT en double/videsHallucination de WhisperNettoyez à l'étape 5
Les caractères chinois s'affichent comme des carrésPolice CJK manquantemacOS : repli automatique sur PingFang. Linux : apt install fonts-noto-cjk
Error parsing filterchainCaractères spéciaux dans le chemin SRTUtilisez un chemin relatif, évitez les espaces

Règles de qualité

  • Transcription fidèle : Ne transcrivez que ce qui a été réellement dit — n'ajoutez ni ne réécrivez le sens
  • Correction des noms propres : Corrigez les erreurs courantes de Whisper, mais confirmez avec l'utilisateur
  • Rythme des sous-titres : Maximum deux lignes par entrée, maximum ~20 caractères CJK par ligne
  • Nettoyage : Rappelez à l'utilisateur de supprimer les fichiers intermédiaires (_audio.wav) une fois terminé

Skills associés