Vidéo (mais plutôt des bas)

Publié le par /

J’ai travaillé il y a quelques mois sur un site Web sur lequel les internautes pouvaient poster des vidéos, soit depuis une application Android, soit en les téléchargeant sur le site. Bien des solutions tierces auraient pu gérer cela pour moi, mais ça n’aurait pas été drôle. J’ai donc décidé de tout faire moi-même, en utilisant naturellement les dernières technos disponibles (à l’époque). Et m’en suis bien mordu les doigts, en y passant des jours (et des nuits). J’ai fini par accoucher d’une petite bibliothèque (en PHP, j’ai des frissons de dégoût rien que d’y repenser) dont je ne peux malheureusement pas publier le code. Grosso-modo, elle acceptait un binaire en entrée, appelait ffprobe pour vérifier son format et en extraire quelques informations, puis lançait des tâches de fond pour convertir, avec ffmpeg, la vidéo initiale vers les quatre formats, pas moins, nécessaires pour espérer être ensuite visualisable depuis n’importe quel terminal :

  • Ogg Theora pour Firefox Stable (3.x) et Opéra;
  • WebM pour Chrome et Firefox 4+;
  • MPEG 4 pour Safari et IE 9
  • FLV pour balancer aux vieux machins via un lecteur Flash;

Comme j’ai pas mal tâtonné pour trouver des réglages potable de ffmpeg, je les reprend ici pour mémoire. Attention, je n’y comprend rien du tout en gestion de son / vidéo, et le peu que j’ai pu comprendre, je l’ai déjà oublié (j’ai codé ce truc il y a plus de 6 mois). Ces réglages ont fonctionné pour moi, je ne garantis pas qu’ils sont adaptés à tous les cas.

La syntaxe générale est ffmpeg -i source dest

Trois options m’ont semblées utiles 

  • -ar pour sélectionner la fréquence d’échantillonage de la piste audio. J’ai décidé de tout ré-échantilloner à 44100Hz, soit -ar 44100;
  • -b pour le débit (bitrate), en kbps. Le meilleur choix a été de conserver celui de la vidéo d’origine, extrait via ffprobe. Soit par exemple pour une vidéo à 3.000 kb/s : -b 3000kb;
  • -r pour le nombre d’images par secondes, 24 est un bon choix;

Quelques « astuces » :

  • par défaut, ffmpeg met les métas-données d’une vidéo en MP4 à la fin du fichier, ce qui empêche de lancer la lecture tant que tout le fichier n’a pas été chargé. Pour y remédier, il suffit d’utiliser l’utilitaire qt-faststart fournis par ffmpeg;
  • si ffmpeg identifie la plupart des formats cibles à leur extension, dans le cas d’Ogg, il faut préciser les codecs audio et vidéo que l’on veut utiliser;
  • ffmpeg permet également d’extraire une image de la vidéo, qui pourra être affichée avant qu’elle ne se lance. Par exemple -ss 3 extrait la première image de la 3° seconde;

Ce qui nous donne, pour une vidéo en entrée à 3.000 kb/s :

ffmpeg -i source  -ar 44100 -b 3000000 -r 24 dest.mp4 && /usr/bin/qt-faststart dest.mp4 dest.mp4.fs && /bin/mv dest.mp4.fs dest.mp4
ffmpeg -i source  -ar 44100 -b 3000000 -r 24 dest.webm 
ffmpeg -i source  -ar 44100 -b 3000000 -r 24 -f ogg -acodec libvorbis -vcodec libtheora dest.ogv
ffmpeg -i source  -ar 44100 -b 3000000 -r 24 dest.flv
ffmpeg -i source -ss 3 dest.jpg

Ne reste plus qu’à l’afficher :

<video controls="true" width="640" height="480" poster="dest.jpg">
  <source src="dest.mp4" type="video/mp4" />
  <source src="dest.webm" type="video/webm" />
  <source src="dest.ogv" type="video/ogg" />
  <!-- Fallback -->
  <object type="application/x-shockwave-flash" data="/flash/player.swf" width="640" height="480">
    <param name="allowfullscreen" value="true" />
    <param name="allowscriptaccess" value="always" />
    <param name="flashvars" value='config={"clip":{"url": "dest.flv", "autoPlay": false}}' />
    <!--[if IE]><param name="movie" value="/flash/player.swf"><![endif]-->
    <img src="dest.jpg" width="640" height="480" alt="Video" />
  </object>
</video>

(les flashvars sont les paramètres passés au lecteur Flash, et dépendent de celui que vous choisirez)

J’avoue avoir failli regretter le temps d’avant HTML5, lorsque la vidéo était prisonnière de Flash. Aujourd’hui, si on veut maîtriser toute la chaîne et être compatible avec la plupart des terminaux fixes et mobiles, on est obligés de stocker chaque vidéo en quatre formats, après les avoir correctement converties. Et je crains qu’il en soit ainsi encore un bon bout de temps :S

Pour réagir, n'hésitez-pas à m'écrire : clochix chez clochix.net ou à soumettre l'url de votre commentaire :
(Je traite les mentions à la main, elles peuvent mettre plusieurs jours avant d'apparaître)

Si vous avez un compte Github, vous pouvez me proposer des corrections en éditant ce billet

Fork me on GitHub