Como criar uma miniatura do meio de um vídeo com FFmpeg

Como criar uma miniatura do meio de um vídeo com FFmpeg

Existe uma maneira de obter uma miniatura de vídeo no FFmpeg?

Gostaria de pegar o quadro intermediário como o vídeo e usá-lo como miniatura. A duração do vídeo é desconhecida.

A capacidade de especificar as dimensões da miniatura também seria útil.

Responder1

Comando de uma linha:

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

O subcomando obtém a duração total do vídeo de entrada

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

E canalize para awkcalcular a duração/2 assim

echo '00:01:30.000' | awk -F ':' '{print ($3+$2*60+$1*3600)/2}'

Então dê isso entre segundos para a opção -ss e pronto.

Se você quiser especificar o tamanho, adicione a opção -s como WxH onde W e H são valores inteiros (ex: -s 800x600 ou -s svga) ou leia a página de manual do ffmpeg para ver outras opções ou formatos disponíveis.

Responder2

Aqui está um método usando:

  • ffprobepara obter a duração
  • bcpara calcular metade da duração
  • ffmpegpara fazer a imagem em miniatura

Exemplo:

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

Responder3

Em primeiro lugar, use sempre a versão mais recente do FFmpeg.

Se você tiver acesso ao PHP, sua pergunta será perfeitamente respondida no Stack Overflow:Usar o FFMpeg para obter o quadro intermediário de um 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}"; 

O que ele fará é apenas extrair a duração da saída do FFmpeg e usá-la para determinar o timecode do quadro intermediário.

Você pode facilmente adaptar isso a outros shells e simplesmente inserir no seguinte comando, onde o quadro intermediário está aproximadamente em 534segundos:

ffmpeg -y  -i input.mp4 -f mjpeg -vframes 1 -ss 534 thumbnail.jpg

Você sempre pode alterar o tamanho com -s 480x320ou similar, dependendo do tamanho desejado, inserido em algum lugar após a -i input.mp4opção.


A solução acima é um pouco imprecisa. Ele fornecerá um resultado imediatamente, mas você não poderá especificar qual quadro deseja. Se você já sabe o quadro exato que deseja extrair, use o selectfiltro, por exemplo, com o número do quadro 12345:

ffmpeg -i input.mp4 -filter:v select="eq(n\,12345)" -vframes 1 thumbnail.jpg

Observe que este comando pode demorar um pouco, pois precisa pular para o quadro especificado antes de extraí-lo.

Responder4

Solução simples é:

 ffmpeg -i l1.mp4 -ss 00:00:14.435 -vframes 1 out.png

informação relacionada