¿Cómo obtener la duración del video en segundos?

70

¿Cómo puedo obtener la duración del video en segundos?

Lo que probé:

ffmpeg -i file.flv 2>&1 | grep "Duration"
  Duration: 00:39:43.08, start: 0.040000, bitrate: 386 kb/s


mediainfo file.flv | grep Duration
Duration : 39mn 43s

Esto está cerca, pero no es tan preciso, 2383 son 39.71 minutos

ffmpeg -i file.flv 2>&1 | grep "Duration"| cut -d ' ' -f 4 | sed s/,// | sed 's@\..*@@g' | awk '{ split($1, A, ":"); split(A[3], B, "."); print 3600*A[1] + 60*A[2] + B[1] }'
2383
usuario2783132
fuente

Respuestas:

36

Para obtener minutos, debes dividir 2383 segundos entre 60.

39.7167

y luego multiplique la parte fraccional .7167 por 60 para obtener los segundos restantes.

43.002

Entonces son 39 minutos, 43 segundos. La aplicación parece estar dándole un valor exacto.

Robert Harvey
fuente
97

Solo use ffprobedirectamente. No hay necesidad de sed, grep, etc Hay varios "duración" se puede adquirir (dependiendo de su entrada).

Duración del formato (contenedor)

$ ffprobe -v error -show_entries format=duration \
  -of default=noprint_wrappers=1:nokey=1 input.mp4

30.024000

Al agregar la -sexagesimalopción, se usará el formato de unidad de tiempo HORAS: MM: SS.MICROSECONDS:

0:00:30.024000

Duración de la transmisión de video

$ ffprobe -v error -select_streams v:0 -show_entries stream=duration \
  -of default=noprint_wrappers=1:nokey=1 input.mp4
30.000000

Los comandos anteriores son de FFmpeg Wiki: FFprobe Tips .

Con ffmpeg

Es posible que deba decodificar por completo la entrada si encuentra que la duración del contenedor o la secuencia falta o es inexacta (posiblemente debido a un archivo dañado o truncado).

$ ffmpeg -i input.mp4 -f null -
  …
  frame= 1587 fps=0.0 q=0.0 Lsize=N/A time=00:01:03.48 bitrate=N/A

En este ejemplo time=00:01:03.48es la duración:

Por supuesto, cuánto tiempo dependerá de la complejidad de la decodificación y la duración de su entrada y las capacidades de su computadora.

lema
fuente
Estos no funcionan para archivos .m2v, ¿tiene una solución para ellos también
Utdev
@utdev Consulte la ffmpegsección "Con ".
llogan
Su tercera solución me da un mal momento, mi video tiene una duración de 01:19:00 pero el comando me devuelve tiempo = 01: 09: 15.32, ¿tiene alguna
idea de
Muy útil la duración del flujo de medios. Gracias.
Somos Borg el
Para cualquiera que use avprobe, los parámetros son ligeramente diferentes: avprobe -v error -show_format_entry Duration. \ Sample.mp4
Brad
33

Si es así ffmpeg, también debería tener ffprobe:

ffprobe -i input.file -show_format | grep duration
ffprobe -i input.file -show_format -v quiet | sed -n 's/duration=//p'

Esto también dará fracciones de segundos, si ese es un problema, puede procesarlo más lejos con sed.

maldad
fuente
¿Cómo puedo eliminar la fracción de segundos?
Tina J
@TinaJ Simplemente canalícela printf, como | xargs printf %.0f: esto devolverá un valor entero.
Ilia Rostovtsev
3

Para mi ffmpeg-0.6.5-1.el6.rf.x86_64, para obtener solo el segundo, el formato del comando ffprobe es:

ffprobe <file> -show_format 2>&1 | sed -n 's/duration=//p' 
Sunry
fuente
¿Cómo puedo eliminar la fracción de segundos?
Tina J
3

Solución con mplayer que da segundos directamente:

mplayer -identify -frames 0 -vo null -nosound file.flv 2>&1 | awk -F= '/LENGTH/{print $2}'
micke
fuente
2
mediainfo --Output='General;%Duration%' file.flv

Esto genera la duración en milisegundos como un valor entero único. No hay necesidad de grep / cut / sed / ...

Josef Kufner
fuente
Gracias, esto era justo lo que estaba buscando. Se puede instalar en MacOS conbrew install mediainfo
Alex K
0

Me encontré con el problema de obtener algunos metadatos extraños e incorrectos de algunos archivos de video con los que estaba trabajando y no pude encontrar un patrón o cualquier tipo de manejo usando código y herramientas como ffmpeg, mp4box, ffprobe, mediainfo, mplayer, para obtener la duración real del video.

Identificar la duración real del video fue un requisito para un proyecto en el que estaba trabajando y la única forma en que siempre lo hice bien fue volver a codificar el archivo de video usando ffmpeg y forzar a los archivos codificados a ignorar los metadatos del archivo original, como:

ffmpeg -i INPUT_FILENAME -acodec copy -vcodec copy -map_metadata -1 OUTPUT_FILENAME"

(Esto podría ejecutarse más rápido de lo esperado. Me sorprendió, por el tipo de contenido y el entorno que estaba usando, el tiempo promedio fue de 2 segundos)

... y luego obtén la duración usando una herramienta a tu elección. Me gusta mediainfo, por cierto: - "mediainfo FILE --Inform =" Video;% Duration% "te da la duración en milisegundos.

satirio
fuente
No proporcionó más información o una mejor solución que otras respuestas
Sam
0

Si solo necesita consultar metadatos:

ffprobe -hide_banner -v quiet -show_streams -print_format flat video.mp4

[...]

streams.stream.0.duration="5221.146009"

[...]

Para que pueda analizarlo:

while read -r; do
  if [[ "$REPLY" =~ ^streams\.stream\.([0-9])+\.duration=\"([^"]+)\"$ ]]; then
    echo -E Duration of stream "${BASH_REMATCH[1]}": "${BASH_REMATCH[2]}"
  fi
done < <(ffprobe -hide_banner -v quiet -show_streams -print_format flat video.mp4)

Pero si desea obtener la duración efectiva del contenedor, debe decodificarlo:

AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2

Tomará un tiempo de CPU para decodificarlo, hasta que:

[...]

frame=130527 fps=53271 q=-1.0 Lsize=N/A time=01:27:01.12 bitrate=N/A speed=2.13e+03x
video:152014kB audio:40790kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

Entonces, puedes analizarlo:

if [[ "$(AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2 | head -n 1)" =~ \ time=([0-9]+):([0-9]{2}):([0-9]{2})\.([0-9]+) ]]; then
  declare duration=0 us="${BASH_REMATCH[4]}" t
  for t in "${BASH_REMATCH[@]:1:3}"; do
    ((duration *= 60))
    ((duration += ${t#0} ))
  done
  while [ ${#us} -lt 6 ]; do us+=0; done
  ((us >= 500000)) && ((duration++))
  ((duration)) || ((duration++))
fi
echo -E Duration: "$duration"
Luchostein
fuente
-6

Si desea una duración EXACTA, olvide FFmpeg. Solo proporciona una estimación basada en el tamaño del archivo y la tasa de bits promedio. ¡He encontrado, en algunos casos, el tiempo de duración estimado en 2 veces!

En Linux, si el archivo se crea y modifica solo durante dicha grabación de video, una solución alternativa sería usar el tiempo de creación y última modificación para calcular la duración, como en:

stat -c "%X %Y" video.mpg | awk '{print $2 - $1}'
codechimp
fuente
55
¿Dónde encontraste que ffmpeg es inexacto?
aleb
44
% X es la hora del último acceso. % Y es el tiempo desde la última modificación. Esto no dice nada sobre la duración del video.
Joe Hillenbrand
1
Esto parece ser un troll
George Chalhoub