lunes, 19 de marzo de 2012

ScreenCast usando FFMPEG

Hace bastante no toco el blog (bastante bastante tiempo :P) me dieron ganas de darle otra chance. Haciendo un resumen en este tiempo, me instale en Arch un tiempo y luego me pase a Gentoo por unos 6 meses, gran experiencia, poniéndole deificación aprendes muchisimas cosas, pero decidí volver a Arch (y sigo acá) porque si bien aprendes muchas cosas en Gentoo y en un principio es entretenido, luego de que te topas con problemas bastante "chotos" una y otra vez en la compilación principal mente (siempre había un problema) se vuelve tedioso y si a eso le sumas el tiempo que lleva compilar todo es mas tedioso aun, así que decidí volver a ArchLinux devuelta, dejar de lidiar con eso y arrancar con los binarios otra vez (tampoco hay una gran diferencia en rendimiento, que realmente compensara la practicidad de los binarios).

Pasando al tema de la entrada, ultima mente estuve haciendo algunas pruebas para hacer un poco de ScreenCast y pense porque no compartirlo, tuve un par de problemas en un principio con el audio y no encontré en ningún lado que realmente me diera una solución para ello, por esas casualidades encontré la solución en alguna linea suelta perdida en algún foro... pero bueno, la idea es compartir algo un poco mas simple de lo que vi por ahí (hay otras alternativas, pero esto esta pensado para los que usamos OSS4 y quieran grabar sonido).

Bueno primero que nada no voy a utilizar solamente FFMPEG, si bien podría la idea es hacerlo sencillo, con el FFMPEG podes elegir en que área de la pantalla quieras grabar, pero es algo tedioso hacerlo si por ejemplo quieres grabar una ventana en especial y cada vez que la abres la ventana se movio de lugar, básicamente usas xwininfo, seleccionas la ventana y con las coordenadas las usas en FFMPEG, no voy a entrar en mucho detalle pero es algo tedioso si hay que hacerlo una y otra vez. Buscando lo que encontré fue el FFCast que hace ese trabajo por uno, podes seleccionar un área o una ventana cada vez que vas a grabar, lo cual es bastante practico y te ahorra algún que otro dolor de cabeza, el FFcast también funciona con otros, recordmydesktop (no pude grabar audio con OSS4) se que es uno. En este caso voy a utilizar x264 y mp3, pero hay gran variedad que pueden usar pueden ver los codecs que tienen disponibles con:

ffmpeg -codecs
Creo que la forma mas fácil de explicar de forma sencilla como hacerlo es mostrando el comando básico que uso para grabar, seria algo así:

ffcast -w % ffmpeg -f oss -i /dev/dsp -f x11grab -r 30 -s %wx%h -i %d+%x,%y -i :0.0 -acodec libmp3lame -async 1 -vcodec libx264 -preset ultrafast -crf 0 -threads 0 /lugar/donde/guardar.mp4
Esto seria básicamente un comando básico para grabar un ScreenCast, explicado cosa a cosa:

"-w" le esta pasando la opción al FFCast para que pida seleccionar una ventana a la hora de grabar, basta con hacer click en una ventana y comenzara a grabar esa ventana, también se puede utilizar "-s" que básicamente antes de comenzar a grabar te pide que selecciones un area.

"%" basicamente quiere decir que le vas a pasar otros comandos al FFMPEG en este caso.

"-f oss -i /dev/dsp" básicamente se le esta diciendo que grabe el sonido usando OSS desde /dev/dsp, podria ser /dev/dsp_out o lo que sea, dependiendo que quieras grabar, yo utilizo OSS4 pero para los que utilizan alsa seria algo asi "-f alsa -ac 1 -i hw:1" en caso de usar solo alsa y "ffmpeg -f alsa -ac 1 -i pulse" en caso de usar Pulseaudio.

"-f x11grab" básicamente que grabe el escritorio.

"-r 30" acá seleccionas los fps a los que quieras grabar.

"-s %wx%h -i %d+%x,%y -i :0.0" revolución, área a grabar y el display, de las primeras 2 se encarga el FFCast siempre y cuando pongan eso, sino iría lo que saquen de xwininfo.

"-acodec libmp3lame" codec de audio, en este caso mp3, pueden utilizar lo que gusten, también pueden pasarle otras opciones, miren la documentacion de FFMPEG.

"-async 1" esto era lo que les comentaba, sin esta opción el audio queda totalmente desincronizado en mi caso, esto básicamente lo arregla.

"-vcodec libx264 -preset ultrafast -crf 0 -threads 0" el codec de video a utilizar en este caso x264, el preset tiene que ser ultrafast (hay fast, slow, etc) sino no llega a grabar correctamente a la cantidad de fps deseados, les va a dar un archivo grande, casi sin compresion que se puede achicar luego usando el preset slow otro codec o lo que quieran, "-crf 0" basicamente el nivel de compresion, a mas alto menor calidad, pueden poner un valor mas alto pero creo que es conveniente hacerlo en una segunda instancia, por ultimo "threads 0" básicamente la cantidad de hilos a utilizar, 0 lo calcula automaticamente.


Eso seria lo básico, pueden cambiarle los codecs o pasarle otras opciones, va a gusto del consumidor, según mis pruebas (que no fueron demasiadas) eso fue lo que mejor se ajusto a mis necesidades (que son básicamente grabar juegos :P). Luego si quieren tener un archivo mas chico pueden usar ffmpeg devuelta por ejemplo algo así:

ffmpeg -i grabacion.mp4 -acodec libmp3lame -ab 128k -ac 2 -vcodec libx264 -preset slow -crf 10 -threads 0 salida.mp4
Si quieren cortar algo (seguro que el principio y el final, seguro se les superpone algo, o no quieren mostrar cuando arrancan a grabar o terminan) les recomiendo utilizar el OpenShot o el Pitivi, es lo mas sencillo y practico para mi.