mpv pour créer des thumbnails de vidéos

Avec mon précédent article on a vu comment chercher, lister, trier sur des noms, des tailles, des md5sum ou des extensions. On va voir maintenant un cas pratique.

En ce qui me concerne il y a deux opérations que je fais assez régulièrement sur des vidéos. La première c’est de couper un morceau d’une vidéo par exemple conserver que de 00:01:00 à 00:03:24 sur la vidéo. La seconde c’est de créer des thumbnails des vidéos.

Thumbquoi ? Thumbnails ! C’est plus clair avec quelques exemples.

24_001

24_002

24_003

24_004

Il y a des outils avec une interface graphique pour faire cela, on peut citer movie thumbnailer (mtn) ou encore Thumbnailme. On peut préciser qu’ils semblent être abandonnés.

La plupart des gens se jetteront dessus et s’en contenteront même si ça ne fait pas exactement ce qu’ils veulent. L’intérêt de jouer avec la ligne de commande est de comprendre ce que font les logiciels, de reprendre la main sur l’ordinateur et finalement d’être encore plus autonome, d’avoir une plus grande souplesse avec les outils utilisés.

Pour créer un thumbnail d’une vidéo, il faut le faire en 2 grandes étapes minimum. La première étape est de créer des images/screenshots d’une vidéo, c’est cette étape que nous allons voir dans le détail. La seconde étape est de « monter » ces images en une seule image. La seconde étape est la plus simple, on utilisera la commande montage (exemples) du logiciel ImageMagick qu’on installera ainsi apt-get install imagemagick.

Pour la première étape, les outils les plus indiqués sont ffmpeg (apt-get install ffmpeg) et son fork avconv (apt-get install libav-tools). Une recherche sur Internet vous donnera plus ou moins la même ligne de commande à utiliser (l’option -bt n’est pas obligatoire pour ffmpeg mais elle l’est pour avconv, je l’ai mise pour comparer des exemples identiques au niveau des options). Je vous mets à la fin de la ligne le temps « real » donné par l’outil time.

avconv -i "a.mkv" -bt 20M -vf fps=1/30 "img_tmp_a.mkv"_%03d.jpg # Résultat de la commande time : 0m28.288s
ffmpeg -i "a.mkv" -bt 20M -vf fps=1/30 "img_tmp_a.mkv"_%03d.jpg # Résultat de la commande time : 0m28.411s
avconv -i "a.mkv" -bt 20M -r 1/30 "img_tmp_a.mkv"_%03d.jpg # Résultat de la commande time : 0m37.109s
ffmpeg -i "a.mkv" -bt 20M -r 1/30 "img_tmp_a.mkv"_%03d.jpg # Résultat de la commande time : 0m37.442s

On ne va évidemment pas parler d’un centième de seconde gagné, c’est négligeable. On voit donc que c’est le même temps qu’on utilise avconv ou ffmpeg. On voit également que pour effectuer sensiblement le même job on peut utiliser des options différentes (-vf fps=1/30 ou -r 1/30 cependant si vous faites le test vous verrez qu’il n’y a pas le même nombre d’images) et que le gain gagné est impressionnant près de 9 secondes en moins avec -vf fps=1/30 d’où la nécessité de comprendre ce que l’on fait et de faire des benchmarks. Le dernier point à remarquer c’est qu’il s’agit d’un traitement excessivement long près de 28 secondes dans le meilleur des cas pour une vidéo. Pour ces exemples je me suis inspiré d’un article du wiki de FFmpeg, ces lignes de commande permettent d’obtenir une image toutes les 30 secondes de la vidéo.

Essayons maintenant avec mplayer (apt-get install mplayer2).

mplayer -vo jpeg -sstep 30 a.mkv

Je n’utiliserai pas la commande time pour deux raisons. La première raison c’est que le processus ne s’arrêtera pas, il continue à tourner encore et encore. La seconde raison c’est que la génération d’une image toutes les 30 secondes de notre vidéo prend 2 secondes. C’est quasi-instantané, incomparable avec avconv/ffmpeg. On a donc là un PoC (proof of concept = démonstration de faisabilité) qu’on peut aller bien plus vite qu’en passant par ffmpeg ou avconv et quand ce n’est pas un besoin professionnel et qu’on a une centaine (ou plus) de vidéos à traiter c’est très intéressant.

MPV

On débarque enfin sur l’outil royal, celui qui va nous apporter la solution : mpv (apt-get install mpv). mpv est un fork de mplayer2 introduisant des nouveautés. Un article a été publié sur ce logiciel sur linuxfr. Notre premier problème c’est de résoudre le fait que le processus ne s’arrête pas car oui nous avons la même chose que pour mplayer (ce qui est assez logique puisque c’est un fork).

La première solution que l’on pourrait proposer est d’utiliser l’option --end qui permet de dire à mpv où l’on souhaite arrêter le traitement. Évidemment le plus logique est de l’arrêter à la fin de la vidéo mais comment connaître la durée d’une vidéo ? Il y a un one-liner pour ça ;)

mplayer -vo dummy -ao dummy -identify "a.mkv" 2>/dev/null | perl -nle '/ID_LENGTH=([0-9.]+)/ && ($t +=$1) && printf "%02d:%02d:%02dn",$t/3600,$t/60%60,$t%60' # Ou bien car les deux lignes font la même chose
mplayer -vo null -ao null -identify -frames 0 "a.mkv" 2>/dev/null | perl -nle '/ID_LENGTH=([0-9.]+)/ && ($t +=$1) && printf "%02d:%02d:%02dn",$t/3600,$t/60%60,$t%60'

La vidéo de test que j’utilise (a.mkv) fait 00:28:24 (28 mn et 24 secondes) si j’utilise mpv -vo image -sstep 30 -end 00:28:24 a.mkv alors ça fonctionne ! Mais la vie est cruelle ça ne fonctionne pas avec un fichier .wmv, ne me demandez pas pourquoi, j’en ai aucune idée. On est bloqué.

Notre salut vient de deux options --end (toujours) et --length. On peut voir dans la documentation de mpv la différence entre les deux. --end est basé sur un temps absolu et --length sur un temps relatif. Ce qui achève de nous convaincre que mpv c’est de la bombe c’est qu’on peut utiliser des pourcentages et des valeurs négatives (voir cet article en Anglais pour quelques exemples) et ici pour les explications.

La vidéo de test que j’utilise (b.wmv) fait 00:24:43. Voyons les exemples.

mpv -vo image -sstep 30 -end 00:24:43 b.wmv # Ça tourne et ça tourne...
mpv -vo image -sstep 30 -end -30 b.wmv # Ça fonctionne et ça fonctionne ! On arrête le traitement 30 secondes avant la fin (-end -30) et du coup on n'a pas à calculer la durée de la vidéo aussi
mpv -vo image -sstep 30 -end 99% b.wmv # Ça fonctionne et ça fonctionne !
mpv -vo image -sstep 30 -length 99% b.wmv # Ça fonctionne et ça fonctionne !

BENCHMARKS

avconv -i "b.wmv" -bt 20M -vf fps=1/30 "img_tmp_b.wmv"_%03d.jpg # Résultat de la commande time : 1m41.521s (1 mn 41 secondes et des poussières)
ffmpeg -i "b.wmv" -bt 20M -vf fps=1/30 "img_tmp_b.wmv"_%03d.jpg # Résultat de la commande time : 1m43.038s
mpv -vo image -sstep 30 -end -30 b.wmv # Résultat de la commande time : 0m1.807s (1,8 seconde)

On peut dire qu’il y a pas photo ;)

SCRIPT

Maintenant notre script (testé et fonctionnel sur avi, mp4, mpeg, wmv, flv, mov, mkv et sûrement d’autres extensions non testées).

#!/bin/bash
# thumbnail.sh v1.0
#
# 24/08/2015
#

tmp_dir=$(mktemp -d)
mpv -vo image:outdir="$tmp_dir" -sstep 30 -end -30 "$*"
montage $tmp_dir/*.jpg -geometry 200x+0+0 "$*".jpg
rm -r $tmp_dir

mktemp -d : On crée un nom de répertoire temporaire unique grâce à mktemp
tmp_dir=$(mktemp -d) : On met le nom de notre répertoire dans une variable
image:outdir="$tmp_dir" : Les images obtenues par mpv seront placées dans le dossier généré par mktemp -d
mpv -vo image:outdir="$tmp_dir" -sstep 30 -end -30 "$*" : On génère une image toutes les 30 secondes du fichier passé en paramètre ("$*") et ces images sont placées dans le dossier généré par mktemp -d. Si vous souhaitez une image toutes les 20 secondes ça donnera mpv -vo image:outdir="$tmp_dir" -sstep 20 -end -20 "$*"
montage $tmp_dir/*.jpg -geometry 200x+0+0 "$*".jpg : On prend toutes les images présentes dans le dossier généré par mktemp -d et on les traite pour fabriquer notre thumbnail. Si on a un fichier a.mkv, le thumbnail sera nommé a.mkv.jpg ("$*".jpg)
rm -r $tmp_dir : On supprime le dossier généré par mktemp -d (ainsi que son contenu évidemment)

CAS PRATIQUE

Si je souhaite générer un thumbnail de tous les fichiers .mkv de mon dossier /home/babar/grosdossiertipiaksecret/.

find /home/babar/grosdossiertipiaksecret/ -type f -iname "*mkv" -print0 | xargs -0 -I{} /home/babar/thumbnail.sh {}

A la prochaine fois pour de nouvelles aventures !

Déjà 7 avis pertinents dans mpv pour créer des thumbnails de vidéos

  • Merci pour cet article plutôt complet. Par contre ce que tu nommes « thumbnails » est en fait une mosaïque de miniatures vidéo. Oui c’est plus long à écrire, mais on comprend mieux de quoi il s’agit du premier coup ^^

    En tout cas, comme tu le dis, il n’y a pas photo entre les solutions que tu proposes ici. Merci pour cette trouvaille.

  • En fait, en lisant le titre je pensai qu’il était question que de miniature et non de mosaïque, vu que c’est la traduction de « thumbnail ». Je trouve ça étonnant que du coup cela soit le terme utilisé pour faire des mosaïques.

    Mais le langage de la partie « professionnelle » de la tech’ française m’étonnera toujours sur sa fainéantise à vouloir traduire certain termes. Je ne sais pas si c’est pour faire plus chic ou je ne sais quoi, mais je trouve dommage que par ce biais là ils intègrent des termes anglais là où il n’a pas lieu d’être :-p

  • Je me répond à moi même :-° : En fait il est bien question de miniatures pour mpv, la partie s’occupant de la mosaïque étant réalisé par ImageMagick.

    C’était juste une petite précision, j’arrête de t’embêter :-p

  • C138
    Yop
    Le titre théoriquement exact serait : construire des mosaïques avec des miniatures (extraites) de vidéos ..

    :-D

Les commentaires sont fermés.