Communitygithub.com

Éditeur vidéo FFmpeg

Modifier des vidéos, extraire l'audio, créer des GIF, ajouter des sous-titres, compresser, manipuler des fichiers multimédia et transcrire/analyser du contenu parlé (enregistrements de réunions, interviews) avec identification des locuteurs — le tout via ffmpeg et le script utilitaire fftools.py.

Qu'est-ce que Éditeur vidéo FFmpeg ?

Ce skill permet de réaliser des opérations avancées d'édition vidéo et audio directement depuis la ligne de commande, sans interface graphique. Il utilise un script helper `fftools.py` qui simplifie l'utilisation de FFmpeg pour des tâches courantes comme le découpage, le montage, la conversion de formats, l'extraction d'audio, la création de GIF, l'ajout de sous-titres, la compression et bien plus. Il prend en charge la transcription locale et hors ligne avec reconnaissance des locuteurs grâce aux modèles WhisperX et sherpa-onnx, permettant d'analyser des réunions ou interviews sans envoyer les données sur le cloud. Le skill est conçu pour être utilisé avec Claude Code, Cursor, Codex ou tout agent capable d'exécuter des commandes shell, et offre une documentation complète couvrant à la fois les commandes principales et des options avancées d'utilisation directe de ffmpeg.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/beveradb/claude-code-config/tree/HEAD/skills/ffmpeg

Demander à votre IA préférée

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

Documentation

Que fait Éditeur vidéo FFmpeg ?

Modifiez des vidéos, de l'audio et des images depuis le terminal en utilisant ffmpeg et le script utilitaire fftools.py.

Outil CLI

Toutes les opérations passent par le script helper. Trouvez-le par rapport à l'endroit où vous avez cloné le dépôt, ou à :

SCRIPT="~/.claude/skills/ffmpeg/scripts/fftools.py"

Toute la sortie est au format JSON.

Référence des commandes

# INFO — Obtenir les détails du fichier (durée, résolution, codecs, taille)
python3 $SCRIPT info input.mp4

# CUT — Extraire un segment
python3 $SCRIPT cut input.mp4 output.mp4 --start 00:01:30 --end 00:02:45
python3 $SCRIPT cut input.mp4 output.mp4 --start 00:01:30 --duration 30

# MERGE — Concaténer plusieurs vidéos
python3 $SCRIPT merge video1.mp4 video2.mp4 video3.mp4 -o merged.mp4
python3 $SCRIPT merge video1.mp4 video2.mp4 -o merged.mp4 --reencode  # codecs différents

# EXTRACT AUDIO — Extraire la piste audio
python3 $SCRIPT extract-audio input.mp4 output.mp3
python3 $SCRIPT extract-audio input.mp4 output.opus --bitrate 128k

# SUBTITLES — Graver les sous-titres dans la vidéo
python3 $SCRIPT subtitles input.mp4 output.mp4 --srt subs.srt

# RESIZE — Changer la résolution
python3 $SCRIPT resize input.mp4 output.mp4 --width 1280 --height 720
python3 $SCRIPT resize input.mp4 output.mp4 --width 1920 --height -1  # hauteur automatique

# GIF — Vidéo vers GIF animé (deux passes, haute qualité)
python3 $SCRIPT gif input.mp4 output.gif --fps 15 --width 480
python3 $SCRIPT gif input.mp4 output.gif --start 00:00:05 --duration 3

# THUMBNAIL — Extraire une image unique
python3 $SCRIPT thumbnail input.mp4 thumb.jpg --time 00:00:30

# THUMBNAILS — Extraire N images espacées uniformément
python3 $SCRIPT thumbnails input.mp4 --count 10 --output-dir ./thumbs/

# COMPRESS — Réduire la taille du fichier
python3 $SCRIPT compress input.mp4 output.mp4 --crf 28 --preset medium
python3 $SCRIPT compress input.mp4 small.mp4 --crf 32 --preset fast  # agressif

# SPEED — Modifier la vitesse de lecture
python3 $SCRIPT speed input.mp4 fast.mp4 --factor 2.0    # 2x plus rapide
python3 $SCRIPT speed input.mp4 slow.mp4 --factor 0.5    # moitié vitesse (ralenti)

# WATERMARK — Ajouter une superposition d'image
python3 $SCRIPT watermark input.mp4 output.mp4 --watermark logo.png --position bottom-right

# TEXT — Graver une superposition de texte
python3 $SCRIPT text input.mp4 output.mp4 --text "Chapitre 1" --position center --size 72 --border
python3 $SCRIPT text input.mp4 output.mp4 --text "Promo !" --position top-left --start 5 --end 15

# CONVERT — Changer de format
python3 $SCRIPT convert input.avi output.mp4
python3 $SCRIPT convert input.mp4 output.webm --video-codec libvpx-vp9

# FRAMES — Extraire des images
python3 $SCRIPT frames input.mp4 --output-dir ./frames/
python3 $SCRIPT frames input.mp4 --output-dir ./frames/ --every 30  # toutes les 30 images

# AUDIO REPLACE — Remplacer la piste audio
python3 $SCRIPT audio-replace input.mp4 output.mp4 --audio music.mp3

# VOLUME — Ajuster le niveau audio
python3 $SCRIPT volume input.mp4 output.mp4 --level 2.0      # doubler le volume
python3 $SCRIPT volume input.mp4 output.mp4 --level 0.5      # moitié du volume
python3 $SCRIPT volume input.mp4 output.mp4 --level 10dB     # augmenter de 10dB

# FADE — Ajouter des effets de fondu
python3 $SCRIPT fade input.mp4 output.mp4 --fade-in 2 --fade-out 3

# STABILIZE — Stabiliser une vidéo tremblante (nécessite le filtre vidstab)
python3 $SCRIPT stabilize input.mp4 output.mp4 --shakiness 7 --smoothing 15

# TRANSCRIBE — Reconnaissance vocale AVEC identification des locuteurs (hors ligne ; voir section Transcription)
python3 $SCRIPT transcribe meeting.mp4                       # → meeting.json/.srt/.txt
python3 $SCRIPT transcribe meeting.mp4 --speakers 3          # indiquer le nombre de locuteurs
python3 $SCRIPT transcribe meeting.mp4 --no-diarize          # transcription seule, sans locuteurs

Transcription & Analyse — comprendre ce qui est dit dans une vidéo

Utilisez la commande transcribe pour transformer un enregistrement de réunion, une interview ou toute vidéo/audio contenant de la parole en une transcription horodatée avec identification des locuteurs. C'est l'outil pour les questions comme "qu'est-ce qui a été discuté ?", "qui a dit quoi ?", "résume cette réunion" ou "trouve où ils ont parlé de X".

Elle s'exécute 100 % localement et hors ligne — l'audio ne quitte jamais la machine, pas d'API cloud. En coulisse : WhisperX (large-v3) pour la transcription + horodatage au niveau du mot, et sherpa-onnx pour la diarisation des locuteurs (sans token, modèles ONNX ouverts).

Installation unique (nécessite un accès réseau une fois)

Exécutez la commande slash /setup-transcribe, ou directement :

bash ~/.claude/skills/ffmpeg/scripts/install-transcribe.sh

Par défaut, cela télécharge un bundle préconstruit depuis la version GitHub (rapide : pas de contrôle de modèle, pas de build torch) et l'installe complètement hors ligne ; si cela n'est pas disponible (version manquante, ou plateforme dont les roues ne correspondent pas), cela bascule automatiquement vers une construction à partir de zéro. Cela crée un environnement virtuel Python 3.12 isolé (via uv) et tous les modèles ; ensuite, transcribe n'a besoin d'aucun réseau. Si la commande signale que l'environnement virtuel est manquant, exécutez ceci.

Forcez un mode spécifique si vous le souhaitez :

bash install-transcribe.sh --release   # seulement le bundle préconstruit
bash install-transcribe.sh --build     # seulement une construction à partir de zéro (HF + PyPI)
HF_TOKEN=hf_xxx bash install-transcribe.sh --build   # active aussi --diarizer pyannote

Environnement isolé / pas d'accès HuggingFace ? Construisez un bundle autonome une fois sur une machine connectée, hébergez-le n'importe où, et installez-le sans accès HF/PyPI :

# Sur une machine où install-transcribe.sh a déjà été exécuté :
bash ~/.claude/skills/ffmpeg/scripts/make-bundle.sh ffmpeg-transcribe-bundle.tar.gz

Le bundle regroupe tout le code, les modèles, les caches de modèles et les roues Python. S'il dépasse 2 Go, il est automatiquement divisé en <nom>.part-aa, <nom>.part-ab, … (chacun < 2 Go) pour respecter les limites d'hébergement/téléchargement. Ensuite, sur la machine cible (nécessite seulement uv, ffmpeg et python3.12) :

# Bundle en un seul fichier :
bash install-transcribe.sh --bundle https://votre.serveur/ffmpeg-transcribe-bundle.tar.gz

# Bundle divisé — passez les parties dans l'ordre (elles sont concaténées automatiquement) :
bash install-transcribe.sh --bundle \
  https://votre.serveur/ffmpeg-transcribe-bundle.tar.gz.part-aa \
  https://votre.serveur/ffmpeg-transcribe-bundle.tar.gz.part-ab

(Pour réassembler manuellement à la place : cat ffmpeg-transcribe-bundle.tar.gz.part-* > ffmpeg-transcribe-bundle.tar.gz.)

Utilisation

# Transcription complète + identification des locuteurs (écrit meeting.json, meeting.srt, meeting.txt)
python3 $SCRIPT transcribe meeting.mp4

# Options
python3 $SCRIPT transcribe interview.mp4 --speakers 2          # nombre connu de locuteurs → meilleure précision
python3 $SCRIPT transcribe call.m4a --language fr             # forcer la langue (ignorer la détection auto)
python3 $SCRIPT transcribe lecture.mp4 --format txt           # écrire seulement .txt
python3 $SCRIPT transcribe long.mp4 --model medium            # plus rapide, moins précis
python3 $SCRIPT transcribe q4.mp4 --diarizer pyannote         # diariseur de meilleure qualité (nécessite jeton HF)
python3 $SCRIPT transcribe notes.mp4 --no-diarize            # transcription seule, sans séparation des locuteurs
python3 $SCRIPT transcribe raw.wav -o ./out/session          # chemin de base de sortie personnalisé

Formats de sortie

  • .txt — lisible par l'homme, regroupé par tour de parole. Lisez ceci pour comprendre le contenu : [00:03:12] SPEAKER_01: ...
  • .srt — sous-titres avec balises de locuteur, pour le brûlage (subtitles command)
  • .json — données structurées complètes : chaque segment + mot avec temps de début/fin et locuteur, pour une analyse programmatique (recherche, chronologies, citations avec horodatage)

Workflow d'analyse de réunion

# 1. Transcrire avec identification des locuteurs
python3 $SCRIPT transcribe meeting.mp4

# 2. Lire la transcription pour analyser le contenu
#    (utilisez l'outil Read sur meeting.txt, ou analysez meeting.json pour les horodatages)

# 3. À partir de là, vous pouvez résumer, extraire des actions, trouver qui a dit quoi,
#    ou accéder à un moment : associez un horodatage JSON avec `cut`/`thumbnail`.
python3 $SCRIPT cut meeting.mp4 clip.mp4 --start 00:12:30 --end 00:14:00

Remarques :

  • La transcription s'exécute sur CPU (CTranslate2 n'a pas de chemin GPU sur Apple Silicon), donc large-v3 est environ 1 à 2× temps réel. Une réunion d'une heure ≈ 30–60 min à traiter — peut être exécutée en arrière-plan. Utilisez --model medium ou distil-large-v3 pour la vitesse.
  • Passer --speakers N (quand vous connaissez le nombre) améliore sensiblement la diarisation.

Workflow standard

Étape 1 — Analyser l'entrée

Commencez toujours par obtenir les informations du fichier :

python3 $SCRIPT info input.mp4

Cela vous donne la durée, la résolution, les codecs, la taille du fichier. Utilisez ces données pour prendre des décisions éclairées sur les paramètres de sortie.

Étape 2 — Effectuer l'opération

Utilisez la commande appropriée. Pour les montages complexes, enchaînez plusieurs opérations — utilisez la sortie de l'une comme entrée de la suivante.

Étape 3 — Vérifier le résultat

Après toute opération, vérifiez la sortie pour confirmer qu'elle a fonctionné :

python3 $SCRIPT info output.mp4

Étape 4 — Afficher le résultat

Utilisez l'outil Read pour afficher les images (vignettes, images). Pour les vidéos, indiquez à l'utilisateur le chemin de sortie et la taille du fichier.

ffmpeg brut — Pour les opérations avancées

Lorsque le script helper ne couvre pas votre cas d'utilisation, utilisez ffmpeg directement :

# Incrustation image dans image
ffmpeg -y -i main.mp4 -i overlay.mp4 \
  -filter_complex "[1:v]scale=320:-1[pip];[0:v][pip]overlay=W-w-10:H-h-10" \
  -c:v libx264 -c:a copy output.mp4

# Comparaison côte à côte
ffmpeg -y -i left.mp4 -i right.mp4 \
  -filter_complex "[0:v]pad=iw*2:ih[bg];[bg][1:v]overlay=W/2:0" \
  -c:v libx264 output.mp4

# Grille/mosaïque (2x2)
ffmpeg -y -i a.mp4 -i b.mp4 -i c.mp4 -i d.mp4 \
  -filter_complex "[0:v]scale=640:360[v0];[1:v]scale=640:360[v1];
    [2:v]scale=640:360[v2];[3:v]scale=640:360[v3];
    [v0][v1]hstack[top];[v2][v3]hstack[bot];[top][bot]vstack" \
  -c:v libx264 grid.mp4

# Inverser la vidéo
ffmpeg -y -i input.mp4 -vf reverse -af areverse reversed.mp4

# Extraire un canal audio spécifique
ffmpeg -y -i input.mp4 -af "pan=mono|c0=FL" left_channel.wav

# Réduction du bruit
ffmpeg -y -i input.mp4 -af "afftdn=nf=-25" denoised.mp4

# Correction des couleurs (luminosité, contraste, saturation)
ffmpeg -y -i input.mp4 -vf "eq=brightness=0.1:contrast=1.2:saturation=1.3" corrected.mp4

# Incrustation chroma key (suppression fond vert)
ffmpeg -y -i greenscreen.mp4 -i background.mp4 \
  -filter_complex "[0:v]chromakey=0x00FF00:0.3:0.1[fg];[1:v][fg]overlay" \
  -c:v libx264 composited.mp4

# Timelapse à partir d'une séquence d'images
ffmpeg -y -framerate 30 -i frame_%04d.jpg -c:v libx264 -pix_fmt yuv420p timelapse.mp4

# Vidéo à partir d'une seule image + audio
ffmpeg -y -loop 1 -i cover.jpg -i audio.mp3 -c:v libx264 -tune stillimage \
  -c:a aac -shortest output.mp4

# Fondu enchaîné entre deux vidéos (1 seconde)
ffmpeg -y -i first.mp4 -i second.mp4 \
  -filter_complex "xfade=transition=fade:duration=1:offset=FIRST_DURATION_MINUS_1" \
  -c:v libx264 crossfade.mp4

Guide de qualité CRF

CRFQualitéCas d'utilisation
18Sans perte visuelleArchivage, montage professionnel
23Haute qualitéffmpeg par défaut, bon pour la plupart des usages
28Bonne qualitéRecommandé pour le partage, fichiers plus petits
32AcceptableRéseaux sociaux, compression agressive
38+Basse qualitéAperçus, vignettes

CRF plus bas = fichier plus grand, meilleure qualité. Chaque +6 réduit environ de moitié la taille du fichier.

Référence rapide des formats

ConteneurCodec vidéoCodec audioCas d'utilisation
.mp4H.264 (libx264)AACCompatibilité universelle
.webmVP9 (libvpx-vp9)OpusWeb, fichiers plus petits
.mkvH.265 (libx265)OpusCompression maximale
.movProResPCMMontage professionnel
.gif——Animations, pas d'audio

Gestion des erreurs

  • "No such file" — Vérifiez le chemin d'entrée, utilisez des chemins absolus
  • "Unknown encoder" — Codec non compilé. Vérifiez ffmpeg -encoders
  • "Permission denied" — Le chemin de sortie n'est pas accessible en écriture
  • "Avi header too large" — Entrée corrompue, essayez -fflags +genpts avant l'entrée
  • Timeout — La vidéo est très longue. Augmentez le délai d'attente ou utilisez --preset ultrafast
  • Out of memory — Réduisez d'abord la résolution, puis traitez

Skills associés