Gostaria de gerar uma visualização gif para meu aplicativo e fazê-lo em meu servidor usando FFMPEG.
Deve gerar um gif obtendo 10 frames para cada vídeo, mas sem usar um diretório temporário (ou arquivos temporários relacionados a cada frame), se possível.
Em relação a esta resposta emsuperusuário.com, deveria gerar um gif usando cada frame, não é isso que preciso.
Parece estranho, mas o efeito que preciso é algo que você pode ver em muitos sites pornográficos (não me lembro qual deles)
Responder1
Se eu entendi você corretamente,este artigo no Wiki do FFmpeg chamado "Crie uma imagem em miniatura a cada X segundos do vídeo"mostra que o FFmpeg não pode fazer o que você deseja (sem alguns cálculos automatizados).
O wiki diz que essa -vf "fps=fps=XYZ"
é a sua melhor chance - ela criará uma miniatura/quadro a cada XYZ
quadro do vídeo original. Se você realmente deseja 10 fotos por vídeo e todas elas têm durações diferentes, você pode primeiro ler a contagem total de quadros e depois calcular o fps necessário com um script:
XYZ=wanted_frames_times_actual_fps/total_frames_of_vid
wanted_frames_times_actual_fps
sendo, por exemplo, ( 10*25
PAL) ou 10*30
(NTSC) no seu caso e total_frames_of_vid=(hh*3600+mm*60+ss)*25+ff
, onde hh
significa horas, mm
significa minutos, ss
significa segundos e ff
significa quadros (após o último segundo contado).Exemplo de cálculo: um timecode de 01:35:45:24
(ou 01:35:45.960
nos termos do FFmpeg, já que o FFmpeg não usa quadros, mas milissegundos) a 25 quadros por segundo se assemelha a 143.649 quadros no total.
Esta solução pode funcionar - você só precisa encontrar uma maneira de obter o tempo total do vídeo (por exemplo, via ffprobe) e seu fps (se não conseguir um código de tempo adequado) e então armazenar essas informações como uma variável chamada $total_frames_of_vid
.
Encontrei outra abordagem sobre isso na seção "Veja também" do Wiki, com link para uma pergunta de superusuário chamada "Miniaturas significativas para um vídeo usando FFmpeg"que sugere usar:
ffmpeg -hide_banner -i <YOUR_VIDEO> -vf "select=gt(scene\,0.8)" -frames:v 10 -vsync vfr -vf "fps=fps=1/200" -y out%03d.png
(Modifiquei um pouco o código - mudei o codec de imagem para PNG e mudei os valores para -frames:v
e fps
. Também mudei as imagens de saída para terem três dígitos em seus nomes.)
e, em seguida, recodificando-os em seu GIF.
Esta solução também precisa de algum cálculo ou trabalho manual, pois os valores de todas as opções (e principalmente fps
precisam ser alterados de acordo com a duração do vídeo. Ou seja, tentei o código original do superusuário com um vídeo de 35 minutos - e só consegui 5 frames dele .