Algunos emuladores permiten grabar tus gameplays/speedruns de forma que las pulsaciones del mando se graban y luego se puede volver a reproducir ese mismo gameplay, pudiendo incluso exportar el gameplay a video.
Pues hay gente a la que le gusta ver las pulsaciones del mando a la vez que mira el gameplay, y no hay muchas herramientas para ello. Aquí os enseñare como se puede hacer tal cosa tan solo usando el codificador de video FFMPEG, nada de programas externos. Así es, solamente FFMPEG y sus filtros. Para este ejemplo usaré el emulador de NES Nestopia.
Este emulador en concreto guarda las grabaciones (comprimidas con ZLIB) en bloques de 8 bytes por frame donde cada byte representa uno de los 8 botones del mando de la NES. 0x40 cuando no esta pulsado, 0x41 cuando esta pulsado.
Muy bien, ¿y que hacemos con este archivo en FFMPEG? Pues resulta que podemos abrirlo como rawvideo. Le decimos a FFMPEG que tiene una resolucion de 8x1, que esta en escala de grises (1 byte por pixel), y le adaptamos el brillo y contraste para que se note la diferencia de 0x40 y 0x41.
Ahora si ponemos el video .AVI exportado y el rawvideo del mando uno encima del otro, nos quedaría algo así:
 |
| ffmpeg -f rawvideo -pixel_format gray -video_size 8x1 -framerate 60 -i input.dat -i v.avi -filter_complex [0]eq=brightness=1:contrast=6.1:gamma=10,scale=256:-1:flags=neighbor[k];[1][k]vstack v.mp4 |
¡Nada mal de momento! La sincronización de las pulsaciones en los pixeles de abajo es perfecta, pero ahora nos faltaria visualizarlo como un mando de NES. Para ello lo primero es dibujarnos nuestro mando de NES:
Ahora lo que haremos mediante el filtro geq es mapear las posiciones de los pixeles para que iluminen los botones correspondientes del mando que hemos dibujado. No hace falta complicarnos mucho con la forma exacta de los botones, luego haremos que iluminen solo las zonas grises con blend.
Ahora el resultado es el siguiente:
 |
| ffmpeg -f rawvideo -pixel_format gray -video_size 8x1 -framerate 60 -i input.dat -i controller.png -i v.avi -filter_complex [0]scale=256:128:flags=neighbor,eq=brightness=1:contrast=6.1:gamma=10,geq=g='if(gt(X,193),p(0,0),if(gt(X,163),p(32,0),if(gt(X,120),p(96,0),if(gt(X,90),p(64,0),if(gt(X,62),p(224,0),if(gt(X,48),if(gt(Y,77),p(160,0),if(lt(Y,64),p(128,0))),p(192,0)))))))':r=0:b=0[k];[k][1]blend=all_mode=hardlight[p];[2][p]vstack v.mp4 |
También podemos hacer que el mando aparezca sobre la imagen, e incluso que tenga un componente alpha. El resultado sería el siguiente:
 |
| ffmpeg -f rawvideo -pixel_format gray -video_size 8x1 -framerate 60 -i input.dat -loop 1 -i controller.png -i v.avi -filter_complex [0]scale=256:128:flags=neighbor,eq=brightness=1:contrast=6.1:gamma=10,geq=g='if(gt(X,193),p(0,0),if(gt(X,163),p(32,0),if(gt(X,120),p(96,0),if(gt(X,90),p(64,0),if(gt(X,62),p(224,0),if(gt(X,48),if(gt(Y,77),p(160,0),if(lt(Y,64),p(128,0))),p(192,0)))))))':r=0:b=0[k];[k][1]blend=all_mode=hardlight[p];[1]alphaextract[a];[p][a]alphamerge,scale=128:-1:flags=neighbor[pa];[2][pa]overlay=main_w-overlay_w:main_h-overlay_h:shortest=1 v.mp4 |
¿Que os ha parecido? ¿Que otras ideas teneis para implementar en FFMPEG?