Sequência de imagens FFMPEG com várias durações

16

Digamos que eu tenho um arquivo mp3 de 1 minuto. E eu tenho 20 imagens png. Quero combinar essas imagens e um áudio em um arquivo de vídeo, mas não quero que cada imagem dure 3 segundos na tela, quero que algumas imagens durem 5 segundos, outras 1 segundo etc.

A única maneira de pensar é apenas copiar as imagens que devem durar mais tempo, por exemplo, para que a imagem1, a imagem2, a imagem3 sejam exatamente iguais, isso me dá 3x mais tempo no vídeo.

No entanto, isso consome muito tempo e espaço. Existe alguma opção / parâmetro no ffmpeg que me permita fazer isso?

Flot2011
fonte
Como você descobriu, o ffmpeg deve exibir cada imagem pelo mesmo comprimento. Se você quiser variar a duração, terá que duplicar as imagens antecipadamente ou criar vídeos separados com a duração desejada e concatená-los. Talvez alguns outros usuários têm melhores ideias, mas este tipo de tarefa pode ser mais fácil com um editor como o Kdenlive, etc.
llogan
Estou fazendo isso a partir do script php, então editor não é o que estou procurando.
Flot2011

Respostas:

21

Usando o ffmpeg 2.0, existem algumas maneiras de fazer isso:

  1. Um método é usar os tempos de modificação do arquivo. Primeiro, defina o tempo de modificação dos arquivos de imagem para que cada arquivo de imagem tenha um tempo de modificação maior que o anterior; a diferença horária é a duração da imagem anterior (com 1 segundo de resolução). Em seguida, use a opção desmuxer image2 -ts_from_file 1. Por exemplo:

    touch -t 01010000.00 image01.png
    touch -t 01010000.03 image02.png
    touch -t 01010000.08 image03.png
    ...
    ffmpeg -ts_from_file 1 -i image%2d.png -i audio.mp3 -c:a copy -vf fps=25 out.avi
    
  2. Outro método é usar o concatdesmuxer , que leva uma lista de arquivos para concatenar, com durações opcionais. Primeiro, crie um arquivo listando suas imagens e durações com a seguinte aparência:

    ffconcat version 1.0
    file image01.png
    duration 3
    file image02.png
    duration 5
    file image03.png
    

    Em seguida, forneça esse arquivo como entrada para ffmpeg. Por exemplo:

    ffmpeg -i in.ffconcat -i audio.mp3 -c:a copy -vf fps=25 out.avi
    

Pode ser necessário duplicar o último arquivo após a duração final. -c:a copycopia o áudio mp3 como está; se você quiser convertê-lo em outro codec de áudio, poderá especificar isso em vez de copy. Você também pode especificar um codec de vídeo diferente -c:vou um formato de pixel diferente -pix_fmt, como -c:v libx264 -pix_fmt yuv420p. -vf fps=25fará a taxa de quadros de saída 25 fps. Se o seu áudio for mais longo e você desejar cortá-lo após as imagens, use a -shortestopção

mark4o
fonte
Alguma idéia de por que isso simplesmente não parece funcionar (quero dizer, eu segui a segunda opção (e tentei primeiro) até a letra, mas ela apenas exibe um vídeo preto sem imagens ou as imagens piscam apenas para um quadro, não vários segundos, conforme especificado no arquivo ffconcat.
sup
@sup: Isso ainda funciona para mim. Se o vídeo estiver em preto, talvez o seu player não seja compatível com o formato de vídeo que você está usando; tente em -c:v libx264 -profile:v baseline -pix_fmt yuv420p out.mp4vez de out.avi ou tente outro player, como mpv ou ffplay. Verifique também se você está usando uma versão atual do FFmpeg e duplique o último nome do arquivo de imagem após a duração final.
Mark4o 27/07/2015
Hum, estranho, você usa mpv e a compilação estática ffmpeg baixada do ffmpeg.org, e apenas ignora as durações. De qualquer forma, eu encontrei outra maneira de fazer isso, por isso não é tão importante: ffmpeg.org/pipermail/ffmpeg-user/2015-July/027702.html
sup
1

Assumindo ffmpeg -i in.ffconcat -vf fps=25 out.avi

(2018: conteúdo do arquivo in.ffconcat) - funciona:

ffconcat versão 1.0
arquivo text.png
duração 30.0
arquivo text.png

enquanto isso não

ffconcat versão 1.0
arquivo text.png
duração 30.0

ou seja, no segundo caso

ffprobe out.avi -show_entries format=duration -v 0

[FORMATO]
duration = 0.040000
[/FORMATO]
Darek Adamkiewicz
fonte