Creando videos desde series de imagenes en Gnome /linux con Ffmpeg.
Tags: bash, video, ffmpeg, screenrecording
Published: 2022-06-17 03:44:00

Tengo una maquina muy antigua que ya no puede hacer screenrecording sin que se pierda grabacion de audio, el resultado es horrendo y ya lo intente en todos los software de grabación de pantalla, kooha, obs, etc.

Pero necesito hacer grabaciones de pantalla, en mi caso, lo mas importante es el audio, por lo que pense si se podria generar video a partir de una serie de archivos de imagen. 

Yo uso el manejador de pantalla Gnome, en el cual cuando oprimes la tecla [prt scr] genera archivos de imagen en png, con un noombre de archivo que al final pasa una estampa de fecha y hora. 

```
Screenshot from 2022-06-17 21-23-10
Screenshot from 2022-06-17 21-23-10
Screenshot from 2022-06-17 21-23-10
Screenshot from 2022-06-17 21-23-10

```
Esata pista puede darnos el tiempo para a partir de una serie de capturas de pantalla generar un video con la famosa utileria de video Ffmpeg mesclandolos con grabaciones de audio. 

(El resultado del experimento en este video:)

{% youtube wVFsY3yX8WQ %}
https://youtu.be/wVFsY3yX8WQ

Los archivos de las capturas o fotografias de la pantalla quedan en este formato: el prefijo "Screenshot from" y luego se registra la fecha y la hora con precision de segundos de cuando fue tomada la captura de pantalla. 

Asi que pense en que si seria viable recrear el video simplemente regenerando con ayuda de esas estampas de tiempo las duraciones entre una imagen y la siguiente. 

Mi mejor intento hasta ahora se los comparto:


1) Hacer las capturas de pantalla, de preferencia no lo hagan antes de media noche, por que el escript solo toma en cuenta las horas no los dias, Gnome las guarda en automatico en Pictures/Screenshots
2) copiar el script bash prepvideo.sh que a continuacion les comparto, sirve para crear la lista y las duraciones, restando el tiempo de la toma de la primera imagen del tiempo de toma de cada imagen
3) Ahora si, ejecutar ffmpeg con el demux concat, tambien les comparto la instruccion a continuacion. 


Esto es prepvideo.sh

O lo puedes descargar en github:
https://github.com/jmrsuarez/prepvideo.sh

```
# with a bash for loop

# limpieza de la lista 
rm list.txt
# tiempo inicial

#Modo feo pero funcional para obtener el tiempo inicial

files=(*.png)

echo "Instante inicial"
echo "${files[0]}"

f=${files[0]}
echo "*** INICIO EN"
echo "${f}"

HORAS="$((10#${f:27:2}*3600))"
MINUTOS="$((10#${f:30:2}*60))"
SEGUNDOS="${f:33:2}"
echo "*************************" 
echo "convertido todo a segundo"
echo "*************************"

TINICIAL="$((HORAS+MINUTOS+SEGUNDOS))"
echo "TIEMPO INICIAL ${TINICIAL}" 
echo "*****************************"
echo "Ahora listando todo lo demas"


echo  "ffconcat version 1.0" >> list.txt;
for f in *.png; do 
#echo "file '$f'"  >> list.txt; 
echo "'$f'"

#echo "duration  '${f:27:8}'"  >> list.txt;
HORAS="$((10#${f:27:2}*3600))"
MINUTOS="$((10#${f:30:2}*60))"
SEGUNDOS="${f:33:2}"
echo "terminado de guardar en las variables"
echo "${HORAS}"



TDURACION="$(((HORAS+MINUTOS+SEGUNDOS)-TINICIAL))"

#echo "horas en segundos ${HORAS}" >> list.txt;
#echo "minutos en segundos   ${MINUTOS}" >> list.txt;
#echo "segundos ${SEGUNDOS}" >> list.txt;

if [[ $TDURACION -gt 0 ]]
then
echo  mayor que 0
echo "duration ${TDURACION}" >> list.txt; 

fi


echo "file '$f'"  >> list.txt; 

done

echo "duration 3" >> list.txt;
```

Una vez salvado el archivo anterior en prepvideo.sh, lo ejecutamos con el comando bash prepvideo.sh y este programita lo que nos genera es un archivo llamado list.txt que contiene todos los nombres de las imagenes y si tiempo de duracion calculado con las timestamps que vienen en el mismo nombre de cada archivo. 

4). Por utilmo, ejecutamos ahora si el comando ffmpeg, cambiamos el archivo mp3 que es la entrada de audio y a 'renderear' el video!

```
ffmpeg -safe 0 -i list.txt  -i audio.mp3 -shortest  -c:a copy -vf fps=25 outcr.avi
```

Listo, ahora podemos ver el video, que en este caso es el archivo outrcr.avi.


---

Estoy investigando mas metodos de producir video con equipo lento y anticuado, otra opcion seria usar Scrot para sacar captura de pantalla una vez cada 10 segundos o algo asi con timestamp y luego reconvertir a video con el mismo metodo que ya indique, pero todavia no termino de investigar esto, por lo pronto les dejo las ligas sobre scrot.

https://askubuntu.com/questions/50958/how-to-take-a-screenshot-every-n-second

https://opensource.com/article/17/11/taking-screen-captures-linux-command-line-scrot

---


A continuación varias links y notas sobre el tema. 


[https://trac.ffmpeg.org/wiki/Concatenate](Concatenar)

Mi primer intento fue hacer esto:

```
ffmpeg -pattern_type glob -i "Screenshot*.png"  -i 'Ultimate 8bit Electro Gaming Music Mix 2020 Chiptune Music Mix.mp3' -shortest  -c:a copy -vf fps=25 out3.avi
```

Y si, convierte la serie de imagenes, las mescla con mi archivo de audio en mp3, pero no toma en cuenta los timestamp, ahora bien, estoy investigando como hacer que tome en cuenta los timestamp,  es trabajo en proceso, por lo pronto, les paso los links que estoy encontrando alrededor de comandos que podrian ser utiles para resolver esto.


* Descubri que se usa -shortest para recortar la salida a el tamaño mas corto, en mi caso es el video el que es mas corto casi siempre.

* Image2 demux, es lo que usamos para convertir series de imagenes a video.

https://ffmpeg.org/ffmpeg-formats.html

* Este es la respuesta en stackoverflow que me ha resultado mas util, luego viene un link con una traducción al español

[https://superuser.com/questions/617392/ffmpeg-image-sequence-with-various-durations](https://superuser.com/questions/617392/ffmpeg-image-sequence-with-various-durations)

https://www.enmimaquinafunciona.com/pregunta/55177/secuencia-de-imagenes-ffmpeg-con-varias-duraciones

* Vamos a tener que usar en esto bash avanzado

https://tldp.org/LDP/abs/html/string-manipulation.html


Y varias links mas interesantes para terminar este proyecto.

https://ottverse.com/create-video-from-images-using-ffmpeg/

https://www.linuxtopia.org/online_books/advanced_bash_scripting_guide/loops1.html

http://ffmpeg.org/ffmpeg-formats.html#image2-1

https://superuser.com/questions/1525130/ffmpeg-using-timestamp-images-only-during-duration


Con estos links aprendi sobre bash ya mas avanzado y sobre ffmpeg.


para depurar en nano
https://askubuntu.com/questions/73444/how-to-show-line-numbering-in-nano-when-opening-a-file



errores

https://stackoverflow.com/questions/38996925/ffmpeg-concat-unsafe-file-name

intro a bash
https://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-5.html

substrings en bash
https://stackoverflow.com/questions/428109/extract-substring-in-bash

bash avanzado
https://linuxize.com/post/bash-functions/
https://unix.stackexchange.com/questions/232384/argument-string-to-integer-in-bash


condicionales en bash
https://atareao.es/tutorial/scripts-en-bash/condicionales-en-bash/

El primer archivo de un directorio
https://unix.stackexchange.com/questions/583156/getting-the-first-file-in-a-directory-in-bash


Ffmpeg de secuencia de imagenes a video
https://superuser.com/questions/617392/ffmpeg-image-sequence-with-various-durations