~rom1v/blog { un blog libre }

screex264 : réencodez vos captures d'écran vidéos (screencasts) sous Ubuntu

Vous connaissez sans doute l’outil gtk-recordmydesktop, qui permet de faire une capture vidéo (un screencast) de votre écran.

Pour obtenir une bonne qualité, dans les options vidéos, il faut vérifier que “compression nulle” est bien sur l’option “Activé” (malheureusement, la compression à la volée utilisée provoque quand même une légère perte de qualité).

Mais une telle vidéo prend un peu de place. Je vous propose donc de la réencoder, dans le format x264 (issu du projet VideoLAN, ayant donné naissance à VLC), multiplexé dans le conteneur MKV.

Le fichier ainsi généré sera lisible par exemple avec VLC.

Disons-le tout de suite, le x264 est actuellement LE meilleur codec de compression vidéo, proposant un rapport qualité/taille impressionnant. Le mkv permet, par exemple, de contenir une piste vidéo, plusieurs pistes audio dans différentes langues, des sous-titres, des chapitres, des pièces jointes… Ici, ce qui nous intéresse, c’est qu’il est libre, et qu’à contenu égal, il prend moins de place que les autres conteneurs (l’overhead est quasi-nul).

Voici comment utiliser le script.

Pour encoder la vidéo mavideo.ogg en mavideo.mkv, avec un débit de 400Kbps :

screex264 mavideo.ogg mavideo.mkv 400

Pour encoder la vidéo mavideo.ogg en mavideo.mkv, avec un débit de 400Kbps avec une meilleure qualité (plus lent) :

screex264 mavideo.ogg mavideo.mkv 400 -hq

Pour encoder la vidéo mavideo.ogg en mavideo.mkv, avec un débit de 400Kbps avec une qualité maximale (très lent) :

screex264 mavideo.ogg mavideo.mkv 400 -vhq

Il est également possible d’utiliser n’importe quels paramètres de mencoder. Ainsi, pour encoder la vidéo mavideo.ogg en mavideo.mkv, avec un débit de 400Kbps, à partir de la 10e seconde et pour une durée de 20 secondes :

screex264 mavideo.ogg mavideo.mkv 400 -ss 10 -endpos 20

Ce script peut également permettre à réencoder les petites vidéos enregistrées grâce à un appareil photo, et diviser leur taille d’un facteur 15.

Passons donc aux choses sérieuses. Tout d’abord, ce script nécessite x264, mencoder et mkvtoolnix pour fonctionner.

#!/bin/sh
# screex264 : screencast encoding script
#
# 11th september 2008 - Romain Vimont (®om)
#
# v0.2 (26th june 2009)
#
# Converts input video (ignoring audio) to x264 video, muxed in mkv.
#
# Syntax:
#   screex264 input_file output_mkv bitrate [quality_preset]
#     [mencoder_options [...]]
#
# quality_preset must be one of :
#   -std : (default) standard quality (good quality, normal)
#   -hq  : high quality (very good quality, slow)
#   -vhq : very high quality (best quality, very slow)
#
# mencoder_options are appended to command line of mencoder call.
# For example :
#   -ss 10 -endpos 56 : trim the video from 10s to 66s.
#
# (of course, there are no options -std, -hq nor -vhq)
#

# Syntax error detected.
# Exits the program with return code 1.
syntax_error() {
   printf '%s%sn' "Syntaxe : $0 input_file output_mkv bitrate " 
     '[quality_preset] [mencoder_options [...]]' >&2
   exit 1
}

# Indicates whether the argument represents an integer.
# Returns the integer if the argument represents an integer, an empty string if
#   it doesn't.
#
# $1: value to test
is_integer() {
   local value="$1"
   printf %s "$1" | grep -o '^[[:digit:]]+$'
}

# Gets a unique id, based on the clock (seconds + nanoseconds).
# Returns a unique id.
uid() {
   date +'%s%N'
}

# Returns the command line arguments for the selected preset.
#
# $1: preset
# return: command line arguments
x264_preset() {
   local preset="$1"
   case "$preset" in
   '-std')
       printf '%s%s%s' "bitrate=$bitrate:frameref=8:mixed_refs:" 
         "bframes=3:b_adapt:b_pyramid:weight_b:partitions=all:8x8dct:" 
         "me=hex:subq=5:trellis=2:threads=auto" ;;
   '-hq')
       printf '%s%s%s' "bitrate=$bitrate:frameref=16:mixed_refs:" 
         "bframes=3:b_adapt:b_pyramid:weight_b:partitions=all:8x8dct:" 
         "me=umh:subq=6:trellis=2:threads=auto" ;;
   '-vhq')
       printf '%s%s%s' "bitrate=$bitrate:frameref=16:mixed_refs:" 
         "bframes=3:b_adapt:b_pyramid:weight_b:partitions=all:8x8dct:" 
         "me=esa:subq=7:trellis=2:threads=auto" ;;
   *)
       printf '%s%sn' 'Quality preset must be one of {-std,-hq,-vhq} : ' 
         "$preset" >&2
       exit 4
   esac
}

# error when less than 3 arguments
[ $# -ge 3 ] || syntax_error

# reads the arguments
in=$1; shift
out=$1; shift
bitrate=$1; shift

# input file must exist
if [ ! -f "$in" ]
then
   printf '%sn' "Input file doesn't exist : $in" >&2
   exit 2
fi

# bitrate value must be integer
if [ ! $(is_integer "$bitrate") ]
then
   printf '%sn' "Bitrate value must be integer : $bitrate" >&2
   exit 3
fi

# choose the quality preset
quality='-std'
if [ "$1" = '-std' -o "$1" = '-hq' -o "$1" = '-vhq' ]
then
   quality="$1"
   shift
fi

# gets the x264 options
opts=$(x264_preset $quality)

# gets a unique filename, in order to avoid collisions when encoding two video
# at the same time
uid=$(uid)
tmp_x264=$(printf '%s' "/tmp/$uid.avi")
tmp_log=$(printf '%s' "/tmp/$uid.log")

# encodes the first pass
mencoder "$in" -o /dev/null -passlogfile $tmp_log -ovc x264 -x264encopts 
 "$opts:pass=1" -nosound $@ &&

# encodes the second pass
mencoder "$in" -o $tmp_x264 -passlogfile $tmp_log -ovc x264 -x264encopts 
 "$opts:pass=2" -nosound $@ &&

# muxes the result in a mkv
mkvmerge -o "$out" -d 0 -A -S "$tmp_x264" --track-order 0:0

Vous pouvez maintenant faire chauffer le processeur !

Commentaires

agathe

chez moi le script plante, il doit manquer la dernière ligne.

petite remarque :

là on fait une double passe. le fichier tmp.avi fini dans la poubelle, dans ce cas autant rediriger le flu vers /dev/null (votre disque dur va vous dire merci) il faut rajouter -f avi pour spécifier le type du conteneur

# encodes the first pass
mencoder "$in" -o /dev/null -f avi -passlogfile $tmp_log -ovc x264 -x264encopts "$opts:pass=1" -nosound $@ &&

en revenge je ne comprends pas bien l’emploi de mkvmerge on n’est pas forcé l’encapsuler le fichier dans un conteneur de type mkv on pourrait aussi bien conserver le format avi.

®om

Bizarre qu’il plante, il te dit quoi précisément?

Concernant ta remarque sur le fichier vidéo généré lors de la première passe, es-tu absolument sûre que ce fichier n’est pas du tout utilisé lors de la seconde passe?

A priori, je pense que tu as raison, car dès que la seconde passe commence, le fichier est écrasé… Je vais faire quelques tests et modifier le script.

Sinon, effectivement tu pourrais le laisser dans un .avi, mais comme je le dis dans le billet :

Ici, ce qui nous intéresse, c’est qu’il est libre, et qu’à contenu égal, il prend moins de place que les autres conteneurs (l’overhead quasi-nul).

MKV est meilleur que AVI, donc pourquoi garder un .avi?

®om

J’ai modifié le script, pour remplacer la sortie par /dev/null lors de la 1ère passe.

Cependant, l’option -f n’existe pas :

-f is not an MEncoder optionExiting... (error parsing command line)
Compte0

Petite correction x264 est une implementation libre d’une compression propriétaire h264, comme le xvid l’est pour le divx. Donc la vidéo encodé avec x264 est encodé dans un format proprio.C’est la même chose que le doc, on peut le créer/modifier avec OOo, mais ça reste proprio

Pour encoder facilement sans trop ce prendre la tête en format libre, j’ai trouvé OggConvert. Il convertit tout les vidéo/musique en formats libres, notament le Dirac qui est un concurrent libre au h264

Agathe
mkvmerge v2.3.0 ('Freak U') built on Sep 7 2008 22:13:04

Error: '--track-order' lacks its argument.

C’est –track-order qui fait planter le script, sans ça tous fonctionne ( c’est peut-être dû a la version de mkvmerge que j’utilise )

Au temps pour moi!

la commande est -of avi

si on en croit la doc

-of (format) (CODE BÉTA!)
    Encode dans le format de conteneur donné (par défaut : AVI).

dans le cas présent c’est superflu.

®om

Compte0, merci de la précision. Et au niveau rapport qualité/taille ça donne quoi? De même pour le theora?

Anonymous

J’avais posté un message sur le dirac dans le forum ubuntu-fr (dans la partie actualité), mais comme il est indisponible je peux pas te filer le lien.

A qualité comparable (à vue de nez), Big buck bunny est a peu près pareil en h264 et dirac. Sinon, t’as la dépêche sur da linux french page Tu pourra comparer les vidéos fournies avec celle du site de bigbuckbunny.

Sinon pour le theora, ç’est juste bine pour du streaming ou des truc basse qualité. c’est moins bien que le divx

Les commentaires sont fermés.