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 thumbnailtenta encontrar os quadros mais representativos no vídeo:
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.
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:
-vsync vfrgarante 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 -ss3 para descartar os primeiros 3 segundos do vídeo.
Meu comando final é assim:
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.
— d33pika
Exemplos de comandos agradáveis. FWIW, não tive problemas com as imagens JPEG geradas pelo FFmpeg no OS X (10.8, FFmpeg 1.1 e abaixo). Seu penúltimo comando funciona bem para mim - o mesmo acontece com o último - e nenhum desses resulta em arquivos JPG em branco. Eu compilei com libopenjpeg.. não tenho certeza se isso faz alguma diferença.
Obrigado slhck. Editou a pergunta com detalhes de configuração / versão do ffmpeg. Não atualizei para 1.1 nesta máquina. Vou fazer isso e ver se isso altera algum resultado.
Então você está no Ubuntu? Você pode experimentar a versão mais recente do Git Master a partir de uma compilação estática ou compilando-se e executando novamente? Ou o mais recente estável. Acabei de verificar, ele usa o mjpegcodificador para mim também, e também verifiquei jpegoptime exiv2, os quais funcionam bem para mim com todos os resultados JPG dos seus comandos de exemplo.
Eu atualizei e funciona agora! Eu acho que a versão anterior tinha alguns erros.
Você pode seguir em frente e publicar a solução - nova versão, de preferência com o link para o changelog, mostrando o bug que você encontrou e posteriormente corrigido com a nova versão?
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.
Imagens totalmente em preto e branco são captadas. Como evito isso?
Existem filtros para detectar quadros e seqüências em preto deles ( ffmpeg.org/ffmpeg-filters.html#blackframe ou ffmpeg.org/ffmpeg-filters.html#blackdetect ). Você não consegue trabalhar com nenhum deles em uma linha única em crescimento, mas definitivamente deve poder remover os quadros pretos (etapa separada) e extrair miniaturas do vídeo resultante.
Quanto aos quadros brancos, agora está ficando complicado, mas ainda parece que existe uma maneira: 1. retirar os quadros pretos 2. negar (o branco fica preto) 3. retirar os quadros brancos 4. negar novamente 5. extrair miniaturas (Se você conseguir retirar os quadros em preto ou branco, especialmente em uma linha, poderá publicá-lo aqui? Posso adicioná-lo à resposta para futuros leitores. ... ou, na verdade, você pode criar uma nova pergunta e responder Eu definitivamente iria votar novamente.)
Para evitar imagens chatas, como preto e branco comum: gere mais miniaturas do que você precisa, compacte-as com jpeg e escolha as imagens com tamanho de arquivo maior. Isso funciona surpreendentemente bem por si só para obter miniaturas decentes.
Este comando não funcionou, recebi um erro Unable to find a suitable output format for 'fps=fps=1/600'. A solução é adicionar -vfantes 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.
D - duração do vídeo lida ffmpeg -i <movie>sozinha ou ffprobecom bom gravador de saída JSON
N - número total de miniaturas que você deseja
X - número da miniatura, de 1 a N
T - ponto no tempo da miniatura
Simplesmente 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.
Cada chamada do ffmpegcomando acima leva uma fração de segundo (!) Para ~ 1GB H.264. Isso ocorre porque ele salta instantaneamente para a <time>posição (lembre-se -ssantes -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.
Você pode misturar acima com scaleou qualquer outro método de redimensionamento. Você também pode remover quadros de cores sólidas ou tentar misturá-los com outros filtros, como thumbnail.
uau mudar -ss Npara antes -ié uma dica incrível. obrigado!
— Apinstein 18/03/16
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.
Quais fatores você usou para comparar 2 imagens?
Infelizmente, não me lembro, foi há muito tempo. Você precisa decidir primeiro qual método de comparação usar e, em seguida, faça alguns testes para encontrar o fator correto. Isso não deve demorar muito.
Só estou pensando em voz alta aqui, mas essa opção não é pior? Ao comparar duas imagens exportadas do vídeo, você já perdeu algumas informações. Quero dizer, é mais fácil calcular a similaridade das informações do codec do que das duas imagens, não é? Recentemente, estive pesquisando alguns algoritmos / bibliotecas para comparar imagens e elas não funcionam tão bem quanto se pode exigir.
Bem, com o ffmpeg você pode extrair quadros sem perda de qualidade usando o sinalizador same_quality. Se você usar informações de codec, precisará verificar se não obtém apenas os Iframes. De qualquer forma, esse utilitário perl funcionou bem para mim e é muito configurável. Veja aqui: search.cpan.org/~avif/Image-Compare-0.3/Compare.pm
Usando este comando, sou capaz de gerar o número necessário de miniaturas que são representativas de todo o vídeo.
Não seria a fórmula correta para fpsser (no_of_frames_req * fps_of_vid) / total_video_frames?
— Flolilo 31/08/19
Estou procurando uma solução oposta: selecione mais quadros de períodos em que a câmera é mais estável e não se move? (onde a diferença entre os quadros sucessivos é menor, não maior). Existe uma maneira de fazer isso?
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 whileloop no seu script e ele será executado para sempre. Basta adicionar a sleep 30para 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.