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 imagemagickIl ne faut pas confondre
montageetmontage:
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
ffprobecontient les millisecondes et que la fréquence a toutes les chances d'être inférieure à une image par seconde mais quebashne sait pas faire de calcul à virgule (c=$(($length/$nb))ne gère que des entiers), nous allons utiliserbc.
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.
ffmpegappliquer 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 redimensionner les images.
for i in capture*.png
do
convert $i -resize 160x120 resized-$i
doneCosmos Laundromat utilise une définition de 1920x804 (format 2.39, aussi nommé DCI). Pour respecter ce format, leur redimensionnement sera en 160x67, mais il est inutile d’être à ce point précis car
convertse débrouillera tout seul pour respecter le ratio 2.39.
Cré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.