FFMPEG - Cas pratique d'utilisation
Ph.Leroy
2018-1108
FFMPEG
Fffmpeg est un merveilleux outil pour manipuler des vidéos, que ce soit à partir de fichier ou a partir de flux viéo (caméra,...); ce document n'est qu'un pense bête me permettant de retrouver ce que j'ai déjà eu le besoin de faire dans le passé.
L'essentiel
ATTENTION à ne plus employer pile@vps337721:/var/www/raphia$ ffmpeg -ss 00:00:01 -i /var/www/raphia/video/Compilation Leroy 1950-1970.webmsd.webm -vf scale=200:-1 -vframes 1 /var/www/raphia/thumb/19/03/910958259.jpg ffmpeg version 0.8.21-6:0.8.21-0+deb7u1, Copyright (c) 2000-2014 the Libav developers built on Oct 16 2017 15:36:54 with gcc 4.7.2 The ffmpeg program is only provided for script compatibility and will be removed in a future release. It has been deprecated in the Libav project to allow for incompatible command line syntax improvements in its replacement called avconv (see Changelog for details). Please use avconv instead. /var/www/raphia/video/Compilation: No such file or directory
Ffmpeg est en ligne de commande il attend des sources en entrée (option -i) et produit un fichier en sortie (sans option) dans la logique d'Unix.
$ffmpeg -i SOURCE -i SOURCE2 PUIT
Les sources multiples sont identifiées par leur indice d'entrée (SOURCE2 -> 1), d'une manière générale les options s'appliquent à l'entrée ou sortie suivantesuivante afin d'éviter tout mélange.
Par exemple:
- Pour préciser le débit de sortie (video bitrate)
$ ffmpeg -i input.avi -b:v 64k -bufsize 64k output.avi
- Pour forcer le nombre d'images par seconde (frame rate) à 24 ips:
ffmpeg -i input.avi -r 24 output.avi
- pour forcer le nombre d'images par seconde de l'entrée (applicable aux seuls formats bruts) à une image par seconde et le nombre d'images par seconde de la sortie à 24 ips:
ffmpeg -r 1 -i input.m2v -r 24 output.avi
==Extraction d'une partie temporelle== Si vous devez extraire une partie de la video commencant à [start] pour une durée de [duration]:ffmpeg -ss [start] -i in.mp4 -t [duration] -c copy out.mp4
Les options signifient: - ss définit la datation de départ, par exemple 00:01:23.000 ou 83 (en secondes)
- t définit la durée de la séquence (même format que ci-dessus), des versions récentes de ffmpeg disposent de l'option -to pour définir la datation de fin.
- c copy copient le premier flux video, audio et sous-titre de la source vers le puit sans les réencoder; cela permet de ne pas perdre en qualité et d’exécuter la commande très rapidement.
Par exemple extraction a partir de la 2° seconde pour une durée de 3,5 secondes:
ffmpeg -ss 2 -t 3.5 -i IMG_2862.mp4 -c copy out.mp4
Extraction d'une partie de la vue
$ ffmpeg -i source.mp4 -filter:v "crop=in_w/2:in_h/2:in_w/4:in_h/4" -c:a copy puit.mp4
Le fichier source est source.mp4, le fichier produit est puit.mp4 et on utilise le filtre "crop". Ce filtre attend en paramètre la largeur, la hauteur, l'abscisse et l'ordonnée de la zone que l'on veut extraire; ici on utilise les dimensions de la source (in_w et in_h).
Génération des calques
Pour générer les calques c'est à dire toutes les images contenues dans la vidéo, afin de pouvoir faire un gif par exemple, il suffit de:
$ ffmpeg -i source.mp4 -r 15 image-%3d.png
Comment faire un aller-retour
Si vous avez l'intention de faire un gif animé qui boucle en permanenece, pour éviter les sauts on peut dupliquer les calques générés en ordre inverse pour un aller et retour.
Un petit shell est bien pratique.
#!/bin/sh
# On a 55 calques generes par ffmpeg frame-001.png a frame-055.png
for i in `seq 1 55`
do
j=$((56-$i));
src=$(printf "Clip_premiere-%03d.png" $j);
k=$((55+55-$j+1));
puit=$( printf "Clip_premiere-%03d.png" $k);
#echo $src vers $puit;
cp $src $puit;
done
Extraction d'une image pour en faire un poster
Lorsque on inclut une video dans une page html, la balise <video> permet de sélectionner un poster.
La commande suivante permet de générer une image a partir d'une vidéo, ici à la 15° seconde.
ffmpeg -ss 00:00:15 -i video.mp4 -vf scale=800:-1 -vframes 1 image.jpg
Obtention des informations d'un fichier
Pour obtenir les informations essentielles d'un fichier vidéo, on peut utiliser ffprobe qui est un exécutable du paquet avec la syntaxe suivante (attention il y a beaucoup d'informations).
$ ffprobe -v error -print_format json -select_streams v:0 -show_entries stream my_video.mp4
c/doc/19/04/lanXHWKQ.mp4'
{
"programs": [
],
"streams": [
{
"index": 0,
"codec_name": "h264",
"codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
"profile": "High",
"codec_type": "video",
"codec_time_base": "50/2997",
"codec_tag_string": "avc1",
"codec_tag": "0x31637661",
"width": 240,
"height": 180,
"coded_width": 240,
"coded_height": 180,
"has_b_frames": 2,
"sample_aspect_ratio": "0:1",
"display_aspect_ratio": "0:1",
"pix_fmt": "yuv420p",
"level": 12,
"chroma_location": "left",
"refs": 1,
"is_avc": "true",
"nal_length_size": "4",
"r_frame_rate": "2997/100",
"avg_frame_rate": "2997/100",
"time_base": "1/11988",
"start_pts": 0,
"start_time": "0.000000",
"duration_ts": 42006,
"duration": "3.504004",
"bit_rate": "68404",
"bits_per_raw_sample": "8",
"nb_frames": "105",
"disposition": {
"default": 1,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0,
"timed_thumbnails": 0
},
"tags": {
"language": "und",
"handler_name": "VideoHandler"
}
}
]
}
On peut choisir le format de production des données (-print_format ou -of: default, compact, flat, ini, json, xml cf.man), choisir le flux (-select streams v:0), et montrer que certaines entrées (-show_entries stream=codec_name); ci-dessus on a affiché l'ensemble des entrées disponibles sur les flux.
Nous ce qui nous intéresse est ceci:
$ ffprobe -v error -show_entries stream=width:stream=height -of flat myvideo.mp4 streams.stream.0.width=240 streams.stream.0.height=180
Ou sinon
$ ffprobe -v error -show_entries stream=width:stream=height -of default=noprint_wrappers=1 my_video.mp4 width=240 height=180
Génération du gif animé
Gimp peut servir a générer un gif animé "assez" simplement.
On a donc généré nos calques (on prend le terme utilisé par Gimp)
$ ffmpeg -i source.mp4 -r 15 calques/image-%3d.png
On ouvre Gimp en précisant "Fichier/Ouvrir en tant que calques..."
On convertit la palette en palette de couleurs indexées "Image / Mode / Couleurs indexées "
On choisit la palette la plus petite possible 63 par exemple (c'est là où on gagne sur la taille finale).
On fait attention à l'ordre des images que l'on peut changer avec " Calque / Pile / Inverser l'ordre des calques".
On peut utiliser l'optimisation pour réduire aux seules parties mouvantes des images "Filtres / Animation / Optimiser (pour Gif)".
Et enfin on exporte " Fichier / Exporter sous..." dans un fichier auquel on donne l'extension ".gif", dans la page qui s'ouvre on précise "En tant que animation", "Boucler indéfiniment" et on valorise le délai à 66 soit 1000/15 (nb d'ips choisi plus haut avec le -r 15).
Byzanz
Byzanz est un petit logiciel en ligne de commande qui permet de créer facilement des gifs animés à partir de capture d'écran.
Par exemple pour faire une capture d'écran:
byzanz-record --duration=20 --x=0 --y=0 --width=1024 --height=800 moo.gif
byzanz-record est bien entendu la commande base --duration=20 correspond à un enregistrement de 20 secondes x et y correspondent aux coordonnées du rectangle d’enregistrement --width et --height correspondent à la résolution d’écran souhaitée et enfin, moo.gif est bien entendu le nom du fichier de sortie