linux - examples - ffmpeg video converter
¿Cómo extraer el tiempo de duración de la salida de ffmpeg? (12)
Argh. Olvídalo. Parece que tengo que sacar las telarañas de mi programació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
Para obtener mucha información sobre un archivo de medios, uno puede hacer
ffmpeg -i <filename>
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 intento
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?
Desde mi experiencia, muchas herramientas ofrecen los datos deseados en algún tipo de tabla / estructura ordenada y también ofrecen parámetros para recopilar 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
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
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;
Puedes usar ffprobe
:
ffprobe -i <file> -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
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_impaired": 0,
"visual_impaired": 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
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.
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 declaración sed
tampoco está funcionando. Prueba esto:
ffmpeg -i file.mp4 2>&1 | grep Duration | awk ''{print $2}'' | tr -d ,
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!
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
ffmpeg -i abc.mp4 2>&1 | grep Duration | cut -d '' '' -f 4 | sed s/,//
da salida
HH: MM: SS.milisecs