Saber la duración de un vídeo con ffmpeg
Podemos ver la información de un vídeo con:
ffmpeg -i video.mp4
que nos devuelve muchísima información, no sólo la duración. Si sólo queremos extraer la duración del vídeo, deberemos hacer tres cosas:
- Redirigir la salida a /dev/null para quedarnos sólo con la información del vídeo
- Extraer la línea donde aparece la duración. Lo haremos con
grep "Duration"
- Limpiar con
cut
todo lo que no sea estrictamente la duración
Veamos paso a paso las acciones a seguir.
Extraer la línea de la duración
ffmpeg -i fin.mp4 2>&1 > /dev/null | grep "Duration"
nos devuelve algo así:
Duration: 00:00:05.00, start: 0.000000, bitrate: 11 kb/s
Como vemos, la información que nos interesa, está en el campo 4 si tomamos como separador el espacio en blanco.
Extraer la numeración en bruto
El minutaje en bruto, al estar en el cuarto campo, lo podemos extraer con:
ffmpeg -i video.mp4 2>&1 > /dev/null | grep "Duration" | cut -d " " -f 4
que nos devolverá algo como esto (cambiará en función de la duración del vídeo):
00:00:05.00,
Dejar la duración limpia
Está casi bien la información. Pero si queremos apurar más, tendremos que quitar la «,» final o, según si nos interesa o no saber los fotogramas, lo anterior al «.«. Me voy a quedar con los fotogramas, por lo que escribiré:
ffmpeg -i video.mp4 2>&1 | grep "Duration" | cut -d " " -f 4 | cut -d "," -f 1
Y ahora sí que me devuelve la duración exacta:
00:00:05.00
Uso en un script
Si en lugar de querer mostrar por pantalla la duración, lo que queremos es extraer individualmente cada uno de los datos de horas, minutos, segundos y fotogramas en un script, podríamos hacerlo con algo así:
#!/bin/bash if [ $# -lt 1 ] then echo "It is necessary to indicate a parameter:" echo -e "\t $ duration video" exit 1 fi if [ ! -f $1 ] then echo "Write a file name to calculate its duration." exit 1 fi which ffmpeg 2>&1 > /dev/null if [ $? -ne 0 ] then echo "You don't have ffmpeg installed." which apt 2>&1 > /dev/null if [ $? -eq 0 ] then echo "You can install it with:" echo -e "\tsudo apt install ffmpeg" fi exit 1 fi duration=$(ffmpeg -i $1 2>&1 | grep "Duration" | cut -d " " -f 4 | cut -d "," -f 1) if [ -z $duration ] then echo "$1 it is not a video file." exit 1 else hours=$(echo $duration | cut -d ":" -f 1) minutes=$(echo $duration | cut -d ":" -f 2) seconds=$(echo $duration | cut -d ":" -f 3 | cut -d "." -f 1) frames=$(echo $duration | cut -d "." -f 2) echo "El vídeo $1 dura $duration, que son:" echo "$hours horas, $minutes minutos, $seconds segundos y $frames fotogramas." exit 0 fi
Explicación del código
Lo que iba a ser un pequeño ejemplo para ilustrar el post, se ha alargado un poco más de lo esperado. Pero así me da juego para explicar más cosas que pueden ayudar a desarrollar mejores scripts.
Líneas 3 – 8: Comprueba si el número de parámetros ($#) que ha escrito el usuario es mayor a 1. Si no lo ha hecho, le indica que necesita incluir, al menos, un parámetro. El valor ha de ser mayor que uno porque el primero siempre es el propio script.
Líneas 10 – 14: Comprueba si el primer parámetro recibido es un fichero. En caso de no serlo, lo indica por pantalla y termina la ejecución del script con un error (exit 1).
Líneas 16 – 27: Comprueba si está instalado ffmpeg. Si no lo está, avisa al usuario. Y si está instalado apt, indica al usuario cómo instalar ffmpeg usando apt.
Línea 29: Extrae la duración según lo indicado a lo largo de este artículo y la almacena en la variable duration.
Líneas 30 – 33: Si la variable duration estuviera vacía es porque el fichero que le pasamos a ffmpeg no es un fichero multimedia, por lo que se lo dice al usuario y sale del script con un error.
Líneas 35 – 38: Extrae las horas, minutos, segundos y fotogramas del vídeo en sus respectivas variables.
Líneas 40 – 41: Muestra por pantalla las horas, minutos, segundos y fotogramas del vídeo.
Línea 42: Si ha llegado el script hasta aquí, es que todo ha ido bien, por lo que devuelve 0 para que se guarde en $?