Geramos muitos GIFs em miniatura cuja qualidade não importa quase o tempo necessário para gerá-los. Gerar GIFs de alta qualidade com o ffmpeg é muito bem coberto, mas não estou tendo muita sorte em descobrir como gerar os de baixa qualidade o mais rápido possível.
O cálculo da paleta ocupa a maior parte do tempo de execução com o seguinte comando (extraído da resposta do filtro de várias cadeias aqui: Como criar com eficiência um gif de melhor paleta a partir de uma parte de vídeo diretamente da Web ):
ffmpeg -y -threads 8 -r 24 -f image2 -start_number 1 -i "frames.%04d.jpg" -filter_complex "fps=24,scale=150:-1:flags=fast_bilinear,split=2 [a][b]; [a] palettegen [pal] fifo [b]; [b] [pal] paletteuse" output.gif
O tempo de execução desse comando com 1000 quadros é de cerca de 72 segundos. Cerca de 67 segundos são a passagem da paleta e, em seguida, brilha na geração GIF real em cerca de 5 segundos. Eu gostaria de reduzir o tempo todo de execução o máximo possível e disposto a sacrificar muita qualidade de imagem por velocidade.
[b]
rótulo. De qualquer forma, o uso da paleta é cerca de 200⨉ mais lento a julgar por um teste rápido. Não usá-lo não é uma opção para você?ffmpeg -y -r 24 -f image2 -start_number 1 -i "frames.%04d.jpg" -filter:v "scale=150:-1:flags=fast_bilinear" output.gif
Os dois problemas com isso: 1) Ele economizou apenas 13 segundos (59 segundos em vez de 72) e 2 ) Não tenho 100% de certeza de que este comando elimina completamente o cálculo da paleta (apenas que o cálculo da paleta que eu estava especificando antes não está incluído).ffmpeg -i <input> <scale> <output.gif>
.Respostas:
Seu uso dos
palettegen
/paletteuse
filtros está tornando o comando mais lento. A maneira simples de obter um GIF de qualidade inferior seria:Com escala adicional:
Você também pode soltar quadros no GIF de saída, ou seja, provar os quadros, para que nem todos sejam processados. Por exemplo, para ter apenas 1 saída de FPS, usando um
fps
filtro:fonte
fps
filtro é nomeadafps
, portanto são equivalentes. Se sua fonte é 120fps, você precisa especificar-framerate 120 -i "frames…"
, porque o padrão para a entrada é 24.Fui encarregado de reduzir o tempo necessário para gerar um GIF animado o mais próximo possível de 30 quadros de comprimento a 150 pixels de largura. A maioria das seqüências que geramos tem menos de 1000 quadros. Tivemos uma sequência de 15.000 quadros e nossos nós de renderização estavam demorando 17 minutos para produzir esse GIF de 30 quadros, o que é inaceitavelmente lento.
Estávamos usando o ffmpeg como um desmuxador e canalizando para a imagemagick. Através de várias horas de experimentação, cheguei às seguintes conclusões:
O número de quadros de entrada que você solicita ao ffmpeg para processar é DE longe a entrada mais impactante em termos de velocidade de execução. Se usar o desmuxer concat para pular os quadros de entrada é uma opção, isso fará a maior diferença de desempenho. Ao tirar todos os quintos quadros, consegui reduzir o tempo total de computação para 1 minuto e 45 segundos com o escalonamento de lanczos de alta qualidade e o cálculo por paleta por quadro. A geração da miniatura de visualização de 30 quadros agora leva menos de 1 segundo .
O algoritmo de redimensionamento foi o próximo maior impactador de desempenho (mas um segundo distante). Usar fast_bilinear em vez de lanczos economizou 150 segundos de tempo de computação em todos os 15.000 quadros.
A variável menos impactante foi a computação em paleta, e isso variou com o algoritmo de redimensionamento. Mais de 15.000 quadros usando lanczos, economizamos cerca de 17 segundos de tempo de execução se eliminássemos o cálculo da paleta. Usando fast_bilinear, economizamos cerca de 75 segundos de tempo de execução.
Como o algoritmo de redimensionamento e a computação da paleta eram insignificantes, acabamos mantendo-os com a mais alta qualidade. Reduzimos nosso tempo de computação de 17 minutos para menos de 1 segundo, dizendo ao ffmpeg para pular a leitura dos arquivos de entrada.
RESUMO PRINCIPAL: SALTAR QUADROS DE ENTRADA vs SALTAR QUADROS DE SAÍDA
A razão pela qual nosso processo estava demorando tanto é que a queda de quadros não ajuda no tempo de execução ao usar o desmuxador image2. Se você mexer com a
-r
bandeira e ofps
filtro, afetará o número de quadros que aparecem no GIF final, mas o ffmpeg parece ainda fazer algo com todos os 15.000 quadros de entrada.A única maneira de encontrar o ffmpeg skip frames de entrada é usando o
concat
desmuxer.Aqui está como agora eu gero miniaturas GIF animadas de alta qualidade em minha máquina de desenvolvimento em menos de 1 segundo, ignorando os quadros de entrada:
fonte