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:

  1. Redirigir la salida a /dev/null para quedarnos sólo con la información del vídeo
  2. Extraer la línea donde aparece la duración. Lo haremos con grep "Duration"
  3. 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 $?

 

Deja una respuesta

Tu dirección de correo electrónico no será publicada.