[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [gulliver] Filmer son écran


From Florent Monnier <fmonnier at linux-nantes dot fr dot eu dot org>
Subject Re: [gulliver] Filmer son écran
Date Fri, 3 Mar 2006 20:54:10 +0100

Bonsoir,

> Je me suis rendu sur le site de Florent Monnier donné en lien dans un
> autre fil.
> J'y découvre de superbes animations blender et surtout des petites
> vidéos de leur réalisations...
> Et là, je me demande : mais comment fait il ?
> Moi j'utilise Istanbul mais je dois pas savoir m'en servir car la vidéo
[...]

Je n'avais pas connaissance de ce logiciel lorsque je les ai faites,
mais on m'avait indiqué un autre logiciel qui lui aussi ne permettait pas de 
faire ce que je voulais car il ne fournissait aucune souplesse.

je me permet de copier coller le mel où on me l'avait indiqué :
"""
il existe un petit programme x11rec qui permet de "presque" faire ça,
il génère en fait 25 images seconde qu'il compilera par la suite pour en 
faire une vidéo. Bien que je ne connaisse pas d'autre moyen de le faire, 
je trouve ça assez long (très en fait) & surtout il te faudra beaucoup 
de place pour stocker les images plus la vidéo qui devra être générée 
derrière, j'espère cependant qu'il existe d'autre moyen ...
"""
je n'ai pas utilisé ce logiciel mais j'ai grossièrement repris le même 
principe. Ce script est écrit en Ruby, il est assez court et facile à 
comprendre et donc à améliorer :)

Pour avoir plus de souplesse j'ai fait mon propre script.

Par exemple capturer 25 frames par seconde n'est pas forcément l'idéal ou ce 
que l'on souhaite, car présenter la vidéo en durée réelle peu être trop long, 
on voudra souvent la présenter en accéléré auquel cas il faut adapter le 
nombre de frames à capturer par seconde en fonction de la vitesse prévue.
On peut aussi voir montrer la vidéo à vitesse d'exécution réelle mais en 
mettant moins que 25 fps, par exemple 10 reste acceptable et la vidéo sera 
beaucoup plus légère si on la met à disposition sur un site internet.

On peut aussi ne pas souhaiter tout enregistrer d'une traite pour pouvoir 
faire des poses. Ou bien en cas d'erreur on peut vouloir effacer la fin et 
repartir à partir d'un certain point.

On peu aussi vouloir recadrer sur une fenêtre, redimentionner, choisir le 
bitrate, etc...

Ci-dessous j'ai préféré décrire en détail la recette qui ma permis de faire ma 
tambouïlle, et que vous pourrez cuisiner avec votre langage de script 
préféré, car si j'envoie mes scripts en l'état vous aurez peut-être du mal à 
vous y retrouver. D'autant que je ne sais plus vraiement où j'ai bien pu 
mettre ces scripts vieux de 3 ans comme les vidéos ;-)
(j'en ai aussi sur Gimp et Sodipodi qui ne sont pas en ligne en raison de 
l'espace dispo)


Voici ma recette :

1) Les ingrédients :
+ xwd
(mnémotechnique pensez à pwd, P comme path est remplacé par X)
c'est l'outil de capture d'écran intégré livré avec le serveur X
d'autres logiciels existent pour capturer l'écran mais l'opération étant très 
coûteuse, c'est vers xwd que je me suis tourné.

+ un langage de script (voir de programmation pour les amateurs)
pas bash car c'est du pur interprété, il est donc trop gourmand,
mais tout autre langage de script devrait faire l'affaire.
x11rec est en Ruby, Istanbul semble avoir du Python et du C,
j'ai utilisé du php-cli, mais utiliserais désormais de l'OCaml.

+ un utilitaire de compression d'image pour éviter de remplir le disque dur
en effet xwd enregistre en non compressé.
'convert' de la suite ImageMagick ou de sa fourchette plus collaborative 
GraphicsMagick sera parfait.
Je compresse en JPEG après car cette opération est également coûteuse en 
ressources.
En effet si la capture des frames[1] mobilise trop de ressources le logiciel 
enregistré répondra de manière saccadé et ça se verra sur la vidéo.

+ tout de même un peu de place sur le disque pour les fichiers temporaires.

+ quelquechose pour gérer le temps entre chaque capture
La solution la plus simple est d'utiliser la fonction sleep de votre langage 
de script préféré.
Utiliser un timer qui appelle le callback réalisant les captures améliore 
peut-être la régularité ou la précision du temps souhaité entre chacune ?
La plupart des langages de script ont une interface pour GTK ou openGL qui 
toute deux fournissent un tel timer que l'on peut utiliser seul 
indépendamment du reste de la lib sans créer la moindre instance de fenêtre.

+ un logiciel d'encodage vidéo
j'utilisais mencoder, mais ffmpeg présenté par Frédéric Mahé à la soirée 
encodage vidéo me semble meilleur.


2) La préparation :
+ Il serait tentant de lancer les xwd derrière un nice en raison de leur 
gourmandise qui provoquent de micro-freeze à chaque capture, mais alors ce 
qui se produit c'est que lorsque le logiciel filmé pompe du cpu, il y aura 
moins de frames, et inversement lorsque l'on fait de petites pauses dans 
l'utilisation du logiciel filmé, elle paraîtront durer beaucoup plus 
longtemps que ce qu'elles ont durées réellement.

+ Il peut être intéressant de lancer X avec une résolution moindre.
Le poids des frames sera moindre, moins de place sera nécessaire pour les 
stocker, que ce soit les version initiales d'xwd ou ultérieurement les JPEG.
Je ne sais pas si lancer X avec une profondeur de couleur moindre peu apporter 
quelquechose.

+ à partir du script (pas de bash comme expliqué plus haut) faire un sleep de 
quelques seconde pour avoir le temps de changer de bureau avant le début de 
l'enregistrement, faire un beep pour prévenir que c'est partit, lancer une 
boucle qui réalise les appels système à xwd. Penser à regarder avec df quelle 
partition a la plus d'espace disponible pour accueillir le répertoire qui 
contiendra les fichiers temporaires "capture-%d.xwd"
Arrêter la boucle avec le système de votre choix, ou au choix un Ctrl+C un 
suffire ;)

3) La finition :
+ compressez les captures originales en jpeg :
convert -quality 80% origs/1.xwd  jpegs/1.jpg
Reprennez l'enregistrement là où vous étiez rendu (faire des pause peut être 
soit voulu, soit nécessaire en raison de la capacité du disque), et continuez 
ainsi de suite.
Vous pouvez vérifier les frames avec : gqview -f jpegs/ pour vérifier le début 
ou la fin et éventuellement les supprimer ; ou vérifier si le niveau de 
compression jpeg vous convient (ci-dessus c'était 80%).
Si vous n'êtes pas satisfait du dernier morceau enregistré, vous pouvez 
l'effacer, et reprendre à la fin du morceau précédent, si vous avez pensé à 
enregistrer le fichier après chaque morceau d'enregistrement.
Vous pouvez aussi réaliser la conversion des images .xwd brutes en .jpg en 
parallèle avec un niveau d'ordonnancement moindre.
Si votre langage de script ne fournit pas la modification du niveau 
d'ordonnancement (nice) et les fourchettes (fork), faite 2 scripts et lancez 
l'un des deux dernière nice.
Lors de la conversion des images .xwd brutes en .jpg vous pouvez aussi cadrer 
la fenêtre du logiciel plutôt que d'avoir l'écran entier avec l'option -crop 
de l'utilitaire convert. Pour les amateurs, vous pouvez aussi ajouter un 
filtre lol.

+ lorsque la séquence est complète, c'est le moment de vérité :
  ffmpeg \
              -i $(TMP_PATH)/frame-%d.jpg  \
              -s $(SIZE)  \
              -b $(BITRATE)  \
              -pass 1  \
              -y video.mpg
  ffmpeg \
              -i $(TMP_PATH)/frame-%d.jpg  \
              -s $(SIZE)  \
              -b $(BITRATE)  \
              -pass 2  \
              -title "Software machin-truc HOWTO" \
              -author "Nom ou pseudo" \
              -copyright "2006 (C) Nom prénom" \
              -comment "This video is available under CC-by-sa." \
              -y video.mpg
  mplayer  video.mpg



4) Servir Libre !
+ choisir sa licence. La CC-by-sa est très à la mode. La GPL est possible. 
peut-être la FDL aussi ? (à confirmer)
Autre au choix... Vous pouvez aussi pourquoi pas écrire la votre...


5) Pistes à creuser pour éventuellement améliorer la recette :
+ Lancer les xwd (avec le même niveau d'ordonnancement comme expliqué plus 
haut) en enregistrant les captures sur un ramdisk et ainsi économiser un 
accès disque coûteux. Un ramdisk n'a qu'une capacité limitée, il faut donc 
que le script fasse une fourchette pour en parallèle copier avec un niveau 
d'ordonnancement moindre les images temporaires vers le lieu de stockage sur 
le disque. Je serais très curieux de voir si on gagne quelquechose ou pas.
La formule magique :
mke2fs /dev/ram6 ; mount /dev/ram6 /mnt/ramdisk/ ; chmod a+w /mnt/ramdisk

+ est-ce que wraper la fonction d'xwd de la xlib pour son langage de script 
favori aurait une chance d'améliorer les performances, plutôt que réaliser un 
appel système ???

+ est-il possible, plutôt que de garder les jpeg temporaires après chaque 
morceau d'enregistrement, de les encoder puis de concaténer les morceaux de 
vidéos ?

+ ffmpeg est-il capable de prendre en entrée des frames au fur et à mesure 
qu'elles arrivent, plutôt que de travailler sur un ensemble d'image déjà 
faites au préalable ?

+ si vous avez d'autres idées de piste qui pourraient éventuellement peut-être 
améliorer quelquechose, merci de m'en informer.

-- 
Si vous le souhaitez, vous pouvez disposer du contenu de ce mel suivant les 
termes de la licence GNU/FDL  http://www.fsf.org/licensing/licenses/fdl.html
mais si vous le faite, s'il vous plais améliorez le quand même un peu avant ;)
2006 (C) Florent Monnier
--
[1] Qui conait la traduction française de ce terme ?