Créer une planche-contact d'une vidéo sous Linux
Divulgâchage : Très pratique dans les rapports d’expertises (mais pas que), la planche-contact, permet de montrer des extraits d’une vidéos en une seule image. Voici comment nous nous y prenons pour les générer. Nous allons utiliser ffprobe, ffmpeg, convert et montage (issus de imagemagick). Le premier pour obtenir les paramètres de la vidéo, le deuxième pour extraire les images qu’on veut garder (en png), le troisième pour réduire la taille des images et le dernier pour construire la planche contenant les miniatures.
Dans une expertise judiciaire où on trouve des vidéos, il est très utile d’afficher des planches avec des miniatures de celles-ci. D’un seul coup d’œil, le juge peut avoir un aperçu du contenu sans pour autant devoir visionner la vidéo en entier.
Issu de la photographie et de la vidéo sur bandes, le terme « planche contact » désigne le tirage de toutes les vues d’un film sur une même feuille à partir de son négatif.
Les anglophones ont repris adapté l’idée au numérique avec leur « Video Contact Sheet » qui défini l'aperçu d'une vidéo numérique à raison d'un nombre défini d'images de la vidéo sur une même planche. Là où une planche contact contient toutes les images, la video contact sheet n’en contient qu’un sous-ensemble.
En français, on pourrait traduire cette variante par « Planche Contact Vidéo », mais il semble très peu utilisé et on généralise donc la planche contact aux aperçus ne contenant que certaines images. Et c’est ce dont nous allons parler aujourd’hui.
Installation des outils
Sans surprise, nous avons besoin des commandes suivantes :
ffprobepour déterminer la durée de la vidéo,ffmpegpour prendre les captures,convertpour réduire la taille des captures,montagepour fabriquer la planche contact.
ffprobe étant inclus dans le paquet ffmpeg et montage et convert dans celui de imagemagick, nous n’avons qu’à installer ces deux paquets.
sudo apt-get install ffmpeg imagemagickTourisme. Il ne faut pas confondre montage et montage :
montage, l’outil deimagemagick, qui sert à créer une image composée d'autres images,montage, le paquet ubuntu développé par Caltech pour assembler des images spatiales.
Fréquence d’échantillonnage
Dans l’idéal, on aimerait pouvoir dire à un outil « prend X images réparties régulièrement ». Mais ça ne marchera pas directement avec ffmpeg qui veut, lui, une fréquence d’échantillonnage (nombre d’images par secondes).
Dans la suite, on utilisera la vidéo Cosmos Laundromat, cinquième court métrage libre de la fondation Blender sous licence Creative Commons Attribution 4.0.
Durée de la vidéo
On commence par calculer la durée de la vidéo. Cela peut être fait en utilisant ffprobe, avec les options suivantes :
- -show_entries format=duration : parmi les informations à montrer, on ne veut que la durée,
- -v quiet : désactive les messages d'informations,
- -of csv="p=0" : indique que nous souhaitons une sortie de type CSV. p=0 indique que l’on souhaite uniquement la valeur,
- -i : pour spécifier le fichier à lire.
ffprobe \
-show_entries format=duration \
-v quiet \
-of csv="p=0" \
-i cosmos-laundromat.mp4Fréquence d’échantillonnage
Avec la durée de la vidéo, on est tenté de calculer le temps entre chaque capture (la période), mais ffmpeg veut l’inverse (la fréquence).
Comme la durée issue de ffprobe contient les millisecondes et que la fréquence a toutes les chances d'être inférieure à une image par seconde mais que bash ne sait pas faire de calcul à virgule (c=$(($length/$nb)) ne gère que des entiers), nous allons utiliser bc.
Si $length est la durée de la vidéo fournie par la commande précédente, et $nb le nombre d’images, la fréquence d’échantillonnage peut se calculer en bash avec la ligne suivante :
echo "(($nb/$length))" | bc -lLes captures
Échantillonner
Pour extraire les images, on va demander à ffmpeg de convertir le film au format png. Comme il s’agit d’un format d’images (et pas de vidéo), ffmpeg va créer autant de fichiers qu’il n’y a d’images dans la vidéo. Pour ça, on utilise l’option -vcodec png et on lui donne le patron pour construire les noms des fichiers capture-%03d.png (%03d sera remplacé par un numéro sur trois chiffres qui s’incrémente à chaque image).
Et comme on ne veut que certaines images, on va lui dire la fréquence d’images par secondes à utiliser lors de la conversion. On ajoute donc l’option -vf fps=$freq (où $freq est la fréquence, résultat du calcul précédent).
ffmpeg \
-i cosmos-laundromat.mp4 \
-vf fps=$freq \
-vcodec png \
capture-%03d.pngTant qu’on y est, nous allons en profiter pour ajouter l’horodatage de la capture en bas de chaque image. On va donc ajouter un filtre drawtext à appliquer avant l’échantillonnage pour ajouter du texte en bas des images.
ffmpeg appliquer ses filtres les uns après les autres, dans l’ordre où vous les lui fournissez. Si vous mettez ce filtre après la fréquence, le timestamp sera calculé après échantillonnage et vous n’obtiendrez pas les horodatages que vous attendiez.
ffmpeg \
-i cosmos-laundromat.mp4 \
-vf drawtext="text='timestamp: %{pts \: hms}':x=(w-text_w)/2:y=h-th-10:box=1:fontcolor=black:boxcolor=white@0.5:fontsize=(h/5)",fps=$freq \
-vcodec png \
capture-%03d.pngRedimensionner
On pourrait construire une planche contact en juxtaposant les images extraites directement mais le résultat sera bien trop grand inutilement. Aucun écran ne pourra afficher autant de pixels d’un coup, surtout une fois la planche contact inclue dans une page de rapport A4 (et ne parlons même pas de l‘impression). Plutôt que de gaspiller des Mo inutilement, on va redimensionner1 les images.
for i in capture*.png
do
convert $i -resize 160x120 resized-$i
doneCréer la planche contact
Enfin, afin de créer la planche contact et tout mettre dans une seule image, on utilise la commande montage. On va l’utiliser avec les options suivantes:
- -title "Titre" : permet de définir le titre de l'image, qui sera affiché en haut. Reconnaît les caractères spéciaux
\net autres\t. - -tile lxh : votre image contiendra
lminiatures de large surhde haut, - -geometry +l+h : chaque miniature sera séparée des autres par
lpixels sur la largeur ethpixels sur la hauteur
Vous devrez également lui donner en entrée les fichiers à partir desquels il doit générer la planche et le nom du fichier en sortie.
montage \
-title "CosmoLaundromat" \
-tile 4x4 \
-geometry +4+4 \
resized-capture-0*.png \
output.pngSi nous n’avions pas redimensionné les images, celles-ci seraient très grandes, et la taille du titre du montage étant fixe, il apparaitrait en tout petit.
Et après ?
Vous pouvez maintenant générer des planches contact facilement, sans installer d'autres logiciels que ffmpeg et imagemagick.
Pour nous simplifier la vie, nous en avons fait un script, que l’on utilise lors de nos expertises.
Il prends comme seul paramètre d’entrée le fichier vidéo. Il créé une planche de 4 sur 4, dont le titre est le nom du fichier vidéo et le nom du fichier est le même que celui de la vidéo (mise à part l'extension).
Il est possible d'utiliser les subtilités de ffmpeg afin de modifier le script à votre goût. Vous pouvez bien sûr changer les couleurs de l’écrit, voir même sélectionner la plage vidéo à utiliser (et non le film en entier). Mais pour cela, il vous faudra alors refaire les calculs.