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 (subtitlescommand).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 mediumoudistil-large-v3pour 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
| CRF | Qualité | Cas d'utilisation |
|---|---|---|
| 18 | Sans perte visuelle | Archivage, montage professionnel |
| 23 | Haute qualité | ffmpeg par défaut, bon pour la plupart des usages |
| 28 | Bonne qualité | Recommandé pour le partage, fichiers plus petits |
| 32 | Acceptable | Ré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
| Conteneur | Codec vidéo | Codec audio | Cas d'utilisation |
|---|---|---|---|
.mp4 | H.264 (libx264) | AAC | Compatibilité universelle |
.webm | VP9 (libvpx-vp9) | Opus | Web, fichiers plus petits |
.mkv | H.265 (libx265) | Opus | Compression maximale |
.mov | ProRes | PCM | Montage 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 +genptsavant 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