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 :
ffprobe
pour déterminer la durée de la vidéo,ffmpeg
pour prendre les captures,convert
pour réduire la taille des captures,montage
pour 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 imagemagick
Il ne faut pas confondre
montage
etmontage
:
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.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 quebash
ne 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 -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:
- -title
Titre
: permet de définir le titre de l’image, qui sera affiché en haut. Reconnaît les caractères spéciaux\n
et autres\t
. - -tile lxh : votre image contiendra
l
miniatures de large surh
de haut, - -geometry +l+h : chaque miniature sera séparée des
autres par
l
pixels sur la largeur eth
pixels 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 \
*.png \
resized-capture-0 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.
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.