![Cómo crear una miniatura desde la mitad de un vídeo con FFmpeg](https://rvso.com/image/1330228/C%C3%B3mo%20crear%20una%20miniatura%20desde%20la%20mitad%20de%20un%20v%C3%ADdeo%20con%20FFmpeg.png)
¿Hay alguna manera de obtener una miniatura de video en FFmpeg?
Me gustaría tomar el fotograma del medio como video y usarlo como miniatura. Se desconoce la duración del vídeo.
También sería útil la posibilidad de especificar las dimensiones de la miniatura.
Respuesta1
Comando de una línea:
ffmpeg -i input.mp4 -vcodec mjpeg -vframes 1 -an -f rawvideo -ss `ffmpeg -i input.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d , | awk -F ':' '{print ($3+$2*60+$1*3600)/2}'` output.jpg
El subcomando obtiene la duración total del vídeo de entrada.
ffmpeg -i input.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d ,
Y canalícelo para awk
calcular la duración/2 de esta manera
echo '00:01:30.000' | awk -F ':' '{print ($3+$2*60+$1*3600)/2}'
Entonces le da esta opción entre segundos a -ss y listo.
Si desea especificar el tamaño, agregue la opción -s como esa WxH donde W y H son valores enteros (por ejemplo: -s 800x600 o -s svga) o lea la página de manual de ffmpeg para ver otras opciones o formatos disponibles.
Respuesta2
Aquí hay un método que usa:
ffprobe
para obtener la duraciónbc
para calcular la mitad de la duraciónffmpeg
para hacer la imagen en miniatura
Ejemplo:
input=input.mp4; ffmpeg -ss "$(bc -l <<< "$(ffprobe -loglevel error -of csv=p=0 -show_entries format=duration "$input")*0.5")" -i "$input" -frames:v 1 half.png
Respuesta3
En primer lugar, utilice siempre la última versión de FFmpeg.
Si tiene acceso a PHP, su pregunta está perfectamente respondida en Stack Overflow:¿Usar FFMpeg para obtener el fotograma medio de un vídeo?
$output = shell_exec("/usr/local/bin/ffmpeg -i {$path}");
preg_match('/Duration: ([0-9]{2}):([0-9]{2}):([^ ,])+/', $output, $matches);
$time = str_replace("Duration: ", "", $matches[0]);
$time_breakdown = explode(":", $time);
$total_seconds = round(($time_breakdown[0]*60*60) + ($time_breakdown[1]*60) + $time_breakdown[2]);
shell_exec("/usr/local/bin/ffmpeg -y -i {$path} -f mjpeg -vframes 1 -ss " . ($total_seconds / 2) . " -s {$w}x{$h} {$output_filename}";
Lo que hará es simplemente extraer la duración de la salida de FFmpeg y usarla para determinar el código de tiempo del fotograma medio.
Puede adaptarlo fácilmente a otros shells y simplemente insertarlo en el siguiente comando, donde el marco del medio está aproximadamente en 534
segundos:
ffmpeg -y -i input.mp4 -f mjpeg -vframes 1 -ss 534 thumbnail.jpg
Siempre puedes cambiar el tamaño con -s 480x320
o similar, dependiendo del tamaño que quieras, insertado en algún lugar después de la -i input.mp4
opción.
La solución anterior es un poco inexacta. Inmediatamente le dará un resultado, pero no podrá especificar qué fotograma desea. Si ya conoce el fotograma exacto que desea extraer, utilice el select
filtro, por ejemplo con el número de fotograma 12345
:
ffmpeg -i input.mp4 -filter:v select="eq(n\,12345)" -vframes 1 thumbnail.jpg
Tenga en cuenta que este comando puede tardar un poco, ya que debe saltar al marco especificado antes de poder extraerlo.
Respuesta4
La solución sencilla es:
ffmpeg -i l1.mp4 -ss 00:00:14.435 -vframes 1 out.png