Créer une planche-contact d'une vidéo sous Linux

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.

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.

Une planche contact. きたし @ wikimedia commons
Une planche contact. きたし @ wikimedia commons

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.

Afin de faire des planches contact facilement, 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.

Installation des outils

Sans surprise, nous avons besoin des commandes suivantes :

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 imagemagick

Il ne faut pas confondre montage et montage :

  • montage, l’outil de imagemagick, 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 :

ffprobe \
    -show_entries format=duration \
    -v quiet                      \
    -of csv="p=0"                 \
    -i cosmos-laundromat.mp4

Fré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 -l

Les 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.png

Tant 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.png

Redimensionner

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
done

Cosmos 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 convert se 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:

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.png

Si 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.

Planche contact obtenue
Planche contact obtenue

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.