¿Cómo extraer el tiempo de duración de la salida de ffmpeg?

Para obtener mucha información sobre un archivo de medios, uno puede hacer

ffmpeg -i  

donde dará salida a muchas líneas, una en particular

 Duration: 00:08:07.98, start: 0.000000, bitrate: 2080 kb/s 

Me gustaría dar salida solo a 00:08:07.98 , así que bash

 ffmpeg -i file.mp4 | grep Duration| sed 's/Duration: \(.*\), start/\1/g' 

Pero imprime todo, y no solo la longitud.

Incluso ffmpeg -i file.mp4 | grep Duration ffmpeg -i file.mp4 | grep Duration produce todo.

¿Cómo obtengo solo la duración de la duración?

ffmpeg está escribiendo esa información en stderr , no en stdout . Prueba esto:

 ffmpeg -i file.mp4 2>&1 | grep Duration | sed 's/Duration: \(.*\), start/\1/g' 

Observe la redirección de stderr a stdout : 2>&1

EDITAR:

Su statement sed tampoco está funcionando. Prueba esto:

 ffmpeg -i file.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d , 

Puedes usar ffprobe :

 ffprobe -i  -show_entries format=duration -v quiet -of csv="p=0" 

Saldrá la duración en segundos, como:

 154.12 

Agregar la opción -sexagesimal dará como resultado la duración en horas: minutos: segundos.microsegundos :

 00:02:34.12 

Desde mi experiencia, muchas herramientas ofrecen los datos deseados en algún tipo de tabla / estructura ordenada y también ofrecen parámetros para recostackr partes específicas de esos datos. Esto se aplica, por ejemplo, a smartctl, nvidia-smi y ffmpeg / ffprobe, también. Simplemente hablando: a menudo no hay necesidad de canalizar datos o abrir subcapas para tal tarea.

Como consecuencia, usaría la herramienta adecuada para el trabajo; en ese caso, ffprobe devolvería el valor de duración sin procesar en segundos, luego uno podría crear el formato de hora deseado por su cuenta:

 $ ffmpeg --version ffmpeg version 2.2.3 ... 

El comando puede variar dependiendo de la versión que esté utilizando.

 #!/usr/bin/env bash input_file="/path/to/media/file" # Get raw duration value ffprobe -v quiet -print_format compact=print_section=0:nokey=1:escape=csv -show_entries format=duration "$input_file" 

Una explicación:

“-v quiet”: no genera nada más que el valor de datos sin formato deseado

“-print_format”: utiliza un formato determinado para imprimir los datos

“compact =”: utiliza un formato de salida compacto

“print_section = 0”: no imprima el nombre de la sección

“: nokey = 1”: no imprima la clave de la clave: par de valores

“: escape = csv”: escapar del valor

“-show_entries format = duration”: Obtenga entradas de un campo denominado duration dentro de una sección llamada format

Referencia: páginas del manual de ffprobe

En el caso de un parámetro de solicitud, es más simple utilizar mediainfo y su formato de salida de esta manera (para la duración; respuesta en milisegundos)

 amber ~ > mediainfo --Output="General;%Duration%" ~/work/files/testfiles/+h263_aac.avi 24840 
 ffmpeg -i abc.mp4 2>&1 | grep Duration | cut -d ' ' -f 4 | sed s/,// 

da salida

HH: MM: SS.milisecs

Recomiendo usar el formato json, es más fácil de analizar

 ffprobe -i your-input-file.mp4 -v quiet -print_format json -show_format -show_streams -hide_banner { "streams": [ { "index": 0, "codec_name": "aac", "codec_long_name": "AAC (Advanced Audio Coding)", "profile": "HE-AACv2", "codec_type": "audio", "codec_time_base": "1/44100", "codec_tag_string": "[0][0][0][0]", "codec_tag": "0x0000", "sample_fmt": "fltp", "sample_rate": "44100", "channels": 2, "channel_layout": "stereo", "bits_per_sample": 0, "r_frame_rate": "0/0", "avg_frame_rate": "0/0", "time_base": "1/28224000", "duration_ts": 305349201, "duration": "10.818778", "bit_rate": "27734", "disposition": { "default": 0, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaird": 0, "visual_impaird": 0, "clean_effects": 0, "attached_pic": 0 } } ], "format": { "filename": "your-input-file.mp4", "nb_streams": 1, "nb_programs": 0, "format_name": "aac", "format_long_name": "raw ADTS AAC (Advanced Audio Coding)", "duration": "10.818778", "size": "37506", "bit_rate": "27734", "probe_score": 51 } } 

puede encontrar la información de duración en la sección de formato, funciona tanto para video como para audio

Para aquellos que quieran realizar los mismos cálculos sin software adicional en Windows, aquí está el script para el script de línea de comandos:

 set input=video.ts ffmpeg -i "%input%" 2> output.tmp rem search " Duration: HH:MM:SS.mm, start: NNNN.NNNN, bitrate: xxxx kb/s" for /F "tokens=1,2,3,4,5,6 delims=:., " %%i in (output.tmp) do ( if "%%i"=="Duration" call :calcLength %%j %%k %%l %%m ) goto :EOF :calcLength set /A s=%3 set /A s=s+%2*60 set /A s=s+%1*60*60 set /A VIDEO_LENGTH_S = s set /A VIDEO_LENGTH_MS = s*1000 + %4 echo Video duration %1:%2:%3.%4 = %VIDEO_LENGTH_MS%ms = %VIDEO_LENGTH_S%s 

La misma respuesta publicada aquí: Cómo recortar los últimos N segundos de un video TS

La mejor solución: cortar la exportación, obtener algo así como 00: 05: 03.22

 ffmpeg -i input 2>&1 | grep Duration | cut -c 13-23 

Simplemente haría esto en C ++ con un archivo de texto y extraería los tokens. ¿Por qué? No soy un experto en terminales de Linux como los demás.
Para configurarlo, haría esto en Linux …

ffmpeg -i 2>&1 | grep "" > mytext.txt

y luego ejecuta alguna aplicación C ++ para obtener los datos necesarios. Tal vez extraer todos los valores importantes y volver a formatearlo para su posterior procesamiento mediante el uso de tokens. Tendré que trabajar en mi propia solución y la gente se burlará de mí porque soy un novato de Linux y no me gusta mucho el guion.

Argh. Olvídalo. Parece que tengo que sacar las telarañas de mi progtwigción C y C ++ y usar eso en su lugar. No conozco todos los trucos de shell para que funcione. Esto es lo lejos que llegué.

ffmpeg -i myfile 2>&1 | grep "" > textdump.txt

y luego, probablemente, extrajera la duración con una aplicación C ++ extrayendo tokens.

No estoy publicando la solución porque no soy una buena persona en este momento

Actualización: tengo mi enfoque para obtener esa marca de tiempo de duración

Paso 1: obtener la información multimedia en un archivo de texto
`ffprobe -i myfile 2>&1 | grep "" > textdump.txt`
O
`ffprobe -i myfile 2>&1 | awk '{ print }' > textdump.txt`

Paso 2: acceda a la información necesaria y extráigala
cat textdump.txt | grep "Duration" | awk '{ print $2 }' | ./a.out
Observe el a.out. Ese es mi código C para cortar la coma resultante porque la salida es algo así como 00: 00: 01.33,
Aquí está el código C que toma stdin y genera la información correcta necesaria. Tuve que tomar las señales mayores y menores para ver.

#include stdio.h #include string.h void main() { //by Admiral Smith Nov 3. 2016 char time[80]; int len; char *correct; scanf("%s", &time); correct = (char *)malloc(strlen(time)); if (!correct) { printf("\nmemory error"); return; } memcpy(correct,&time,strlen(time)-1); correct[strlen(time)]='/0'; printf("%s", correct); free(correct); }

Ahora los formatos de salida correctamente como 00: 00: 01.33

Puedes intentar esto:

 /* * Determine video duration with ffmpeg * ffmpeg should be installed on your server. */ function mbmGetFLVDuration($file){ //$time = 00:00:00.000 format $time = exec("ffmpeg -i ".$file." 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//"); $duration = explode(":",$time); $duration_in_seconds = $duration[0]*3600 + $duration[1]*60+ round($duration[2]); return $duration_in_seconds; } $duration = mbmGetFLVDuration('/home/username/webdir/video/file.mov'); echo $duration; 

ffmpeg ha sido sustituido por avconv: simplemente sustituye avconb por la respuesta de Louis Marascio.

 avconv -i file.mp4 2>&1 | grep Duration | sed 's/Duration: \(.*\), start.*/\1/g' 

Nota: ¡el adicional. * Después de comenzar a tener tiempo solo!