O FFmpeg pode capturar imagens de vídeos que podem ser usados como miniaturas para representar o vídeo. As formas mais comuns de fazer isso são capturadas no FFmpeg Wiki .
Mas não quero escolher quadros aleatórios em alguns intervalos. Encontrei algumas opções usando filtros no FFmpeg para capturar alterações de cena:
O filtro thumbnail
tenta encontrar os quadros mais representativos no vídeo:
ffmpeg -i input.mp4 -vf "thumbnail,scale=640:360" -frames:v 1 thumb.png
e o comando a seguir seleciona apenas os quadros que têm mais de 40% das alterações em comparação com as anteriores (e provavelmente são as mudanças de cena) e gera uma sequência de 5 PNGs.
ffmpeg -i input.mp4 -vf "select=gt(scene\,0.4),scale=640:360" -frames:v 5 thumb%03d.png
Crédito de informação para os comandos acima para Fabio Sonnati . O segundo parecia melhor, pois eu podia obter n imagens e escolher o melhor. Eu tentei e gerou a mesma imagem 5 vezes.
Um pouco mais de investigação me levou a:
ffmpeg -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.png
-vsync vfr
garante que você obtenha imagens diferentes. Isso ainda escolhe sempre o primeiro quadro do vídeo; na maioria dos casos, o primeiro quadro é de créditos / logotipo e não tem significado, então adicionei um -ss
3 para descartar os primeiros 3 segundos do vídeo.
Meu comando final é assim:
ffmpeg -ss 3 -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.jpg
Foi o melhor que pude fazer. Percebi que, como escolho apenas 5 vídeos, todos são principalmente do início do vídeo e podem perder cenas importantes que ocorrem mais tarde no vídeo.
Gostaria de escolher seu cérebro para outras opções melhores.
fonte
libopenjpeg
.. não tenho certeza se isso faz alguma diferença.mjpeg
codificador para mim também, e também verifiqueijpegoptim
eexiv2
, os quais funcionam bem para mim com todos os resultados JPG dos seus comandos de exemplo.Respostas:
Que tal procurar, idealmente, o primeiro quadro de mudança de> 40% em cada um dos cinco intervalos de tempo, em que o intervalo de tempo é o 1º, 2º, 3º, 4º e 5º 20% do vídeo.
Você também pode dividi-lo em seis intervalos de tempo e desconsiderar o primeiro para evitar créditos.
Na prática, isso significaria definir os fps para um número baixo ao aplicar sua verificação de mudança de cena e seu argumento para lançar o primeiro trecho do vídeo.
...algo como:
fonte
Unable to find a suitable output format for 'fps=fps=1/600'
. A solução é adicionar-vf
antes que o argumento (ver stackoverflow.com/questions/28519403/ffmpeg-command-issue )Definir significado é difícil, mas se você quiser criar N miniaturas de maneira eficiente, abrangendo todo o arquivo de vídeo, é isso que eu uso para gerar miniaturas na produção com o conteúdo carregado pelo usuário.
Pseudo-código
Onde:
ffmpeg -i <movie>
sozinha ouffprobe
com bom gravador de saída JSONSimplesmente o quadro acima anota o quadro-chave central de cada partição do filme. Por exemplo, se o filme tiver 300s e você quiser 3 miniaturas, será necessário um quadro-chave após 50s, 150s e 250s. Para 5 miniaturas, seriam 30s, 90s, 150s, 210s, 270s. Você pode ajustar N, dependendo da duração do filme D, que, por exemplo, um filme de 5 minutos terá 3 miniaturas, mas mais de 1 hora terá 20 miniaturas.
atuação
Cada chamada do
ffmpeg
comando acima leva uma fração de segundo (!) Para ~ 1GB H.264. Isso ocorre porque ele salta instantaneamente para a<time>
posição (lembre-se-ss
antes-i
) e pega o primeiro quadro-chave, que é praticamente o JPEG completo. Não há tempo perdido para renderizar o filme para corresponder à posição exata do tempo.Pós-processamento
Você pode misturar acima com
scale
ou qualquer outro método de redimensionamento. Você também pode remover quadros de cores sólidas ou tentar misturá-los com outros filtros, comothumbnail
.fonte
-ss N
para antes-i
é uma dica incrível. obrigado!Certa vez, fiz algo semelhante, mas exportei todos os quadros do vídeo (em 1 qps) e os comparei com um utilitário perl que achei que calcula a diferença entre as imagens. Comparei cada quadro às miniaturas anteriores e, se fosse diferente de todas as miniaturas, adicionei-o à coleção de miniaturas. A vantagem aqui é que, se o seu vídeo passar da cena A para B e retornar para A, o ffmpeg exportará 2 quadros de A.
fonte
Tente isto
Usando este comando, sou capaz de gerar o número necessário de miniaturas que são representativas de todo o vídeo.
fonte
fps
ser(no_of_frames_req * fps_of_vid) / total_video_frames
?Aqui está o que eu faço para gerar uma miniatura periódica para os fluxos m3u8 ao vivo usarem como pôster. Eu descobri que executar uma tarefa ffmpeg contínua apenas para gerar miniaturas consome toda a minha CPU, então, em vez disso, executo um cronjob a cada 60 segundos que gera todas as miniaturas para meus fluxos.
Se você precisar fazer mais de 60 segundos (limitação do cronjob), poderá fazer um
while
loop no seu script e ele será executado para sempre. Basta adicionar asleep 30
para alterar a frequência para 30 segundos. Porém, não recomendo fazer isso com um grande número de vídeos, pois a execução anterior pode não ser concluída antes do início da próxima.Idealmente, com o cronjob, eu apenas o executo a cada 5 minutos.
fonte