Totem, xine, gstreamer, ffmpeg, ouhlàlà...

Tout d'abord il faut savoir que si vous ne voyez jamais de prévisualisation de vos vidéos, c'est peut-être simplement parce que vous n'avez pas installé totem auquel vous préférez certainement d'autres lecteurs multimédia. Un premier pas consiste donc bien sûr à installer totem, ce qui donne sur un système Linux Debian ou assimilé :

$ sudo apt-get install totem

Cependant la page de Wikipedia traitant de totem nous apprend que celui-ci peut utiliser une des deux bibliothèques suivantes : GStreamer ou xine. Si vous souhaitez l'utiliser avec xine il faudra installer le paquet totem-xine (c'est le choix par défaut du système), sinon il s'agira de totem-gstreamer qu'il faudra accompagner de son paquet gstreamer0.10-ffmpeg[1] pour bénéficier des services de ffmpeg. Dans ce dernier cas, on utilisera la commande suivante :

$ sudo apt-get install totem-gstreamer gstreamer0.10-ffmpeg

Si ceci active effectivement la prévisualisation des vidéos, le résultat n'est pas toujours au rendez-vous, comme la capture d'écran de l'introduction l'a montré. Or, toujours en consultant les pages de Wikipedia, on découvre que xine et gstreamer sont tous les deux sensés se reposer sur ffmpeg. Alors ? Alors ça doit être un problème de version obsolète ou d'options de compilation car on peut décider de ne pas compiler tous les formats reconnus, généralement pour des raisons de propriété intellectuelle sur certains formats et dans certains pays[2]. Il y a alors deux solutions :

  • trouver une version plus récente et/ou plus complète de ffmpeg
  • recompiler ffmpeg

La première solution est de loin la plus simple sous Linux Debian grâce au dépôt « Debian multimedia » (voir le billet Dépôts supplémentaires pour Debian Etch sur ce blog). Il faut ajouter ce dépôt comme expliqué dans le billet mentionné puis mettre à jour ffmpeg puis gstreamer :

$ sudo apt-get update
$ sudo apt-get upgrade

Par contre ce dépôt ne proposera pas de mise à jour pour xine, il vous faudra donc travailler avec gstreamer. Le résultat est cette fois-ci au rendez-vous comme le montre la capture d'écran plus bas. Enfin pour ceux qui seraient tentés par la seconde méthode (y en a-t-il vraiment ?), vous avez dû vous rendre compte avec ces explications techniques qu'il fallait non seulement recompiler ffmpeg mais aussi totem et xine ou gstreamer ! Bref, il faut être motivé.

ffmpeg thumbnailer Avec ffmpeg de « Debian multimedia », tout redevient conforme aux attentes !

Tout paraît pour le mieux dans le meilleur des mondes, néanmoins il peut encore arriver que certaines vidéos soient toujours récalcitrantes, auquel cas il faudra court-circuiter totem pour aller directement chez ffmpeg, ce qui chez moi donne - enfin - 100% des prévisualisations. De même vous pouvez souhaiter utiliser ffmpeg sans installer totem dont vous n'avez pas l'utilité, ce qui évite aussi d'avoir à recompiler totem. Dans ces deux cas il faudra utiliser un petit script qui fera l'interface entre Gnome et ffmpeg, le principe est expliqué plus loin.

Tout ceci peut paraître inutilement compliqué : c'est vrai ! :-( C'est un des problèmes du logiciel libre : plus on a de choix, moins on sait quoi choisir et ne pas faire le bon choix peut empêcher de faire correctement ce qu'on souhaite faire par la suite. Ceci explique certainement la grande diversité des distributions Linux : d'autres personnes font des choix pour vous. À suivre...

Court-circuiter totem

Supposons maintenant qu'on ne veuille pas de totem. En fouinant un peu dans le système[3], on peut découvrir que Gnome, pour générer les prévisualisations des vidéos, fait appel à la commande gnome-video-thumbnailer laquelle n'est en fait qu'un lien symbolique pointant sur totem-video-thumbnailer : il s'agit du système des alternatives des Linux Debian et dérivés, expliqué juste après. Pour rediriger Nautilus directement sur ffmpeg, il « suffit » d'écrire un script de remplacement de totem-video-thumbnailer et de le déclarer comme nouvelle alternative pour générer les prévisualisations. Nous allons voir comment...

Que sont les alternatives ?

Le système des alternatives est spécifique aux systèmes Linux Debian et dérivés. Ils consiste à définir des commandes génériques pour un type d'opération standard (naviguer sur le web, éditer un texte, afficher une applet Java, etc.). Par exemple pour lancer le navigateur web, on utilisera la commande x-www-browser qui pointera en réalité sur le navigateur pré-selectionné par l'administrateur du système.

Ainsi si vous êtes agacé par ces applications qui veulent absolument ouvrir les pages web dans Galeon plutôt que Firefox (alias IceWeasel), commencez par faire un tour dans les alternatives avec galternatives qui est une petite interface pour gérer les alternatives. On peut aussi explorer directement le répertoire /etc/alternatives mais il est assez fourni et donc difficile à lire. Bien sûr installer galternatives est d'une simplicité enfantine :

$ sudo apt-get install galternatives

Remarque : dans le même ordre d'idées, si vous avez installé la machine virtuelle Java gjc, rapide à charger, et que vous visitez un site qui ne fonctionne qu'avec celle de Sun, beaucoup plus lourde, il faudra installer cette dernière à partir du paquet Debian en plus de la première. Cependant ça ne marchera toujours pas car il existe de nombreuses alternatives en rapport avec Java et elles utilisent gjc par défaut qui est bien plus rapide à lancer. Faites donc alors un tour dans les alternatives !

Comment Nautilus crée les prévisualisations

La documentation de la commande totem-video-thumbnailer indique qu'elle s'utilise de cette manière :

$ man totem-video-thumbnailer
[...]
totem-video-thumbnailer [-s size] input output [backend options]
[...]
totem-video-thumbnailer is used internally by GNOME applications such as nautilus
to generate PNG thumbnails of video files. While it is possible to invoke it
manually, it is usually done automatically by nautilus.

À l'aide d'un petit script remplaçant momentanément totem-video-thumbnailer on a vite fait de savoir sous quelle forme Nautilus fournit les arguments à cette commande :

  • size indique simplement la largeur de l'image en pixels (par ex. 128), la hauteur est donc déduite des dimensions de la vidéo[4]
  • input et output sont des URL[5], ainsi ils sont précédés de file:// pour indiquer qu'il s'agit de fichiers locaux

On peut bien sûr demander à ffmpeg de réaliser la même opération que totem-video-thumbnailer, mais la commande devra alors être :

ffmpeg -i <input> -vcodec png -vframes 1 -s <size> -f rawvideo -y <output>

où le paramètre size est du type LxH (par ex. 128x96) et <input> et <output> sont des chemins de fichier standards. Il va donc falloir d'une part calculer la hauteur de l'image et d'autre part transformer les URL en noms de fichiers normaux. On s'aidera pour cela du langage Python qui permet d'obtenir rapidement l'opération voulue sans s'arracher les cheveux sur d'horribles problèmes de syntaxe hérités d'un autre âge...

Créer la prévisualisation avec ffmpeg

Le script Python, nommé ffmpeg-video-thumbnailer, est à placer dans le répertoire classique des exécutables destinés à l'utilisateur, /usr/bin. Ensuite on utilisera le système des alternatives pour indiquer à Gnome d'utiliser ce script plutôt que celui fourni par défaut. Vous pouvez bien sûr récupérer ffmpeg-video-thumbnailer dont la somme MD5 vaut 55501e8ce6dbb565bcd5f1ff899435ac. Son listing étant un peu long, il ne sera pas présenté intégralement dans ce billet et seules quelques parties seront présentées en fin de billet.

Bien évidemment ce script s'utilise de la même façon que totem-video-thumbnailer :

ffmpeg-video-thumbnailer [-s geometry] input output

Se déroulement est le suivant :

  1. récupération des arguments (vidéo d'entrée, image de sortie et dimensions)
  2. conversion des URL en noms de fichiers locaux
  3. calcul des dimensions de l'image à partir de celles de la vidéo
  4. génération de la prévisualisation au format PNG
  5. incrustation sur les bords d'une image représentant les trous d'un film

La dernière opération, optionnelle mais réalisée aussi par totem-video-thumbnailer, permet de différencier dans le navigateur de fichiers une prévisualisation d'image d'une prévisualisation de vidéo en lui donnant l'aspect d'un morceau de bande d'un film. On utilisera pour cela la bibliothèque ImageMagick qu'il faudra installer au préalable et l'image que totem-video-thumbnailer utilise lui-même, laquelle a été retrouvée en espionnant les appels système de cette commande grâce à strace :

$ strace totem-video-thumbnailer -s 128 <input> <output>
[...]
open("/usr/share/totem/filmholes.png", O_RDONLY|O_LARGEFILE) = 13
[...]

Évidemment si vous souhaitez vous débarrasser de totem il faudra copier cette image quelque part, par exemple dans un répertoire /usr/share/ffmpeg créé pour l'occasion, c'est un paramètre à modifier en début de script. Pour finir on n'oubliera pas de rendre exécutable le script avec la commande chmod et l'option +x associée au caractère exécutable du fichier :

$ sudo chmod +x /usr/bin/ffmpeg-video-thumbnailer

Tout est prêt pour déclarer une nouvelle alternative pour gnome-video-thumbnailer. Il faut pour cela utiliser la commande update-alternatives avec l'option --install en lui précisant :

  1. le chemin complet de la commande sujette à alternatives (/usr/bin/gnome-video-thumbnailer)
  2. le nom de l'alternative (gnome-video-thumbnailer)
  3. le chemin complet de l'alternative proposée (/usr/bin/ffmpeg-video-thumbnailer)
  4. la priorité de l'alternative[6]

Ceci donne alors :

$ sudo update-alternatives --verbose --install /usr/bin/gnome-video-thumbnailer gnome-video-thumbnailer /usr/bin/ffmpeg-video-thumbnailer 50
Vérification des versions disponibles pour gnome-video-thumbnailer, mise à jour des liens dans /etc/alternatives...
(Vous pouvez modifier ici les liens symboliques vous-même si vous le désirez - voir « man ln »).
Mise à jour de gnome-video-thumbnailer (/usr/bin/gnome-video-thumbnailer) pointant sur /usr/bin/ffmpeg-video-thumbnailer.

On peut vérifier par acquis de conscience à l'aide des deux commandes suivantes :

$ ls -l /usr/bin/gnome-video-thumbnailer
lrwxrwxrwx 1 root root 41 2007-03-18 10:55 /usr/bin/gnome-video-thumbnailer -> /etc/alternatives/gnome-video-thumbnailer
$ ls -l /etc/alternatives/gnome-video-thumbnailer
lrwxrwxrwx 1 root root 33 2007-09-20 22:05 /etc/alternatives/gnome-video-thumbnailer -> /usr/bin/ffmpeg-video-thumbnailer

On a donc bien /usr/bin/gnome-video-thumbnailer qui pointe sur /etc/alternatives/gnome-video-thumbnailer, lequel pointe en fait sur /usr/bin/ffmpeg-video-thumbnailer. Le tour est joué !

Détails du script Python

La transformation des URL en chemins de fichiers locaux est très simple grâce à la bibliothèque urllib (comprenez « URL lib »). Elle contient en effet une fonction url2pathname qui fait exactement ce dont on a besoin, il n'y a plus qu'à éliminer le file:// :

##################
# URL's to pathnames
Input = urllib.url2pathname(Input.replace('file://', ''))
Output = urllib.url2pathname(Output.replace('file://', ''))

Pour calculer la hauteur de l'icône, l'astuce consiste à lancer ffmpeg sans fichier de sortie par l'exécution d'une commande système (fonction commands.getoutput). Dans ce cas il donne les caractéristiques de la vidéo d'entrée puis se plaint de ne pas avoir de sortie. Une petite expression régulière (fonction re.findall) permet alors d'extraire les dimensions de la vidéo :

##################
def dims(FileName):
       """
       gets video dimensions
       """
       Result = commands.getoutput("ffmpeg -i '%s'" % FileName)
       Orient = re.findall(r'(\d+)x(\d+)', Result)
       if len(Orient):
               return map(int, Orient[0])
       else:
               return 0, 0

L'expression régulière (\d+)x(\d+) recherche une série de chiffres (le premier \d+) séparée d'une deuxième série de chiffres par la lettre x. Elle rapportera chaque série de chiffres séparément en omettant le x (c'est l'effet des parenthèses), puis on applique la fonction int à chaque nombre via la fonction map.

Enfin la superposition de l'image des trous de film est basée sur la bibliothèque ImageMagick et la commande suivante :

$ composite -compose atop -geometry +x+y <input1> <input2> <output>

Cette commande est répétée à des positions y différentes jusqu'à ce que toute la hauteur de la prévisualisation en soit ornée. Comme ceci n'affecte qu'un seul côté de l'image à chaque fois, un miroir horizontal permet ensuite de l'appliquer de l'autre côté.

Notes

[1] ce paquet gstreamer0.10-ffmpeg est comme par hasard recommandé par le paquet totem-gstreamer

[2] les formats de fichiers binaires comme les vidéos peuvent, dans certains pays, être associés à des brevets qui en limitent l'utilisation par d'autres logiciels

[3] soit en inspectant la configuration de Gnome avec l'éditeur de configuration gconf, soit en listant les alternatives

[4] ce qui est tout-à-fait normal vu que Nautilus ne peut pas savoir a priori si vous êtes en 4/3 ou en 16/9 par exemple

[5] Uniform Resource Locator, indique l'emplacement d'une ressource, par exemple une image, et la méthode pour y accéder, par exemple avec le protocole FTP

[6] pour déterminer l'ordre d'affichage et le choix par défaut dans la liste des alternatives