Crie vídeo com 5 imagens com o efeito fadeIn / out no ffmpeg

27

Com 5 imagens, tenho que criar um vídeo de 60 segundos em ffmpeg, cada imagem deve ser exibida por 15 segundos. após 15 segundos, a primeira imagem deve desaparecer e a segunda imagem deve desaparecer, depois que a segunda imagem desaparecer, a terceira imagem desaparecer ... etc. Por favor, me guie como posso conseguir isso usando os comandos ffmpeg.

user384847
fonte
4
O que você tentou e depois podemos ajudá-lo? Este fórum não é do tipo "por favor, me responda sem fazer nenhum trabalho". Com isso dito, fornecerei o link para a documentação do ffmpeg fade - ffmpeg.org/ffmpeg-filters.html#fade #
6111 Mike Diglio

Respostas:

49

Dip / fade para preto

Role para baixo para o método crossfade.

exemplo desaparecer

Exemplo em que cada imagem é exibida por 5 segundos e cada uma desaparece por 1 segundo. Cada entrada de imagem tem a mesma largura, altura e proporção de amostra. Se eles variam em tamanho, veja o exemplo nº 3 abaixo.

Saída MP4

ffmpeg \
-loop 1 -t 5 -i input0.png \
-loop 1 -t 5 -i input1.png \
-loop 1 -t 5 -i input2.png \
-loop 1 -t 5 -i input3.png \
-loop 1 -t 5 -i input4.png \
-filter_complex \
"[0:v]fade=t=out:st=4:d=1[v0]; \
 [1:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" out.mp4

Com áudio

O mesmo que acima, mas com áudio:

ffmpeg \
-loop 1 -t 5 -i input0.png \
-loop 1 -t 5 -i input1.png \
-loop 1 -t 5 -i input2.png \
-loop 1 -t 5 -i input3.png \
-loop 1 -t 5 -i input4.png \
-i audio.m4a \
-filter_complex \
"[0:v]fade=t=out:st=4:d=1[v0]; \
 [1:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" -map 5:a -shortest out.mp4

Para imagens de entrada com tamanhos variados ou arbitrários

Como o primeiro exemplo, mas com imagens de entrada que variam em largura x altura. Eles serão preenchidos para caber em uma caixa de 1280x720:

ffmpeg \
-loop 1 -t 5 -i input0.png \
-loop 1 -t 5 -i input1.png \
-loop 1 -t 5 -i input2.png \
-loop 1 -t 5 -i input3.png \
-loop 1 -t 5 -i input4.png \
-filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=out:st=4:d=1[v0]; \
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" out.mp4

Veja os exemplos em Redimensionando vídeos para caber no player de tamanho estático, se você deseja cortar (preencher a tela) em vez de teclado (caixa de correio / coluna) ou se deseja impedir o aumento de escala.

Saída GIF

Adiciona os filtros de Como converto um vídeo em GIF usando ffmpeg, com qualidade razoável?

ffmpeg \
-framerate 10 -loop 1 -t 5 -i input0.png \
-framerate 10 -loop 1 -t 5 -i input1.png \
-framerate 10 -loop 1 -t 5 -i input2.png \
-framerate 10 -loop 1 -t 5 -i input3.png \
-framerate 10 -loop 1 -t 5 -i input4.png \
-filter_complex \
"[0:v]fade=t=out:st=4:d=1[v0]; \
 [1:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
 [2:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
 [3:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
 [4:v]fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
 [v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,split[v0][v1]; \
 [v0]palettegen[p];[v1][p]paletteuse[v]" -map "[v]" out.gif

Use a -loopopção de saída para controlar o número de vezes que o GIF faz um loop. O padrão é loop infinito se esta opção não for usada. Um valor de -1é sem loop.

Opções e filtros usados:

  • -t para definir a duração em segundos de cada entrada.

  • -loop 1 faz um loop na imagem, caso contrário, ela teria a duração de 1 quadro.

  • -frameratepara definir a taxa de quadros da imagem de entrada (o padrão quando não declarado é 25). Útil para criar GIF.

  • escala com pad para ajustar as imagens de entrada em um tamanho específico e uniforme (usado no exemplo nº 3).

  • desaparecer para desaparecer dentro e fora. dé a duração do desbotamento. sté quando começa.

  • concat para concatenar (ou "ingressar") em cada imagem.

  • formato para gerar um esquema de subamostragem de croma compatível com players não baseados em FFmpeg se estiver emitindo MP4 e codificando com libx264 (o codificador padrão para saída MP4, se for suportado por sua compilação).

  • dividir para fazer cópias de uma saída de filtro. Necessário pelos filtros da paleta * para fazer tudo em um comando.

  • palettegen e paletteuse para criar GIF com boa aparência.


Crossfade

exemplo de crossfade

Exemplo em que cada imagem é exibida por 5 segundos e cada uma possui um crossfade que dura 1 segundo. Cada entrada de imagem tem a mesma largura, altura e proporção de amostra. Se eles variam em tamanho, adapte o exemplo nº 3 acima.

Saída MP4

ffmpeg \
-loop 1 -t 5 -i 1.png \
-loop 1 -t 5 -i 2.png \
-loop 1 -t 5 -i 3.png \
-loop 1 -t 5 -i 4.png \
-loop 1 -t 5 -i 5.png \
-filter_complex \
"[1]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+4/TB[f0]; \
 [2]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+8/TB[f1]; \
 [3]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+12/TB[f2]; \
 [4]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+16/TB[f3]; \
 [0][f0]overlay[bg1];[bg1][f1]overlay[bg2];[bg2][f2]overlay[bg3]; \
 [bg3][f3]overlay,format=yuv420p[v]" -map "[v]" -movflags +faststart out.mp4

Com áudio

ffmpeg \
-loop 1 -t 5 -i 1.png \
-loop 1 -t 5 -i 2.png \
-loop 1 -t 5 -i 3.png \
-loop 1 -t 5 -i 4.png \
-loop 1 -t 5 -i 5.png \
-i music.mp3 \
-filter_complex \
"[1]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+4/TB[f0]; \
 [2]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+8/TB[f1]; \
 [3]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+12/TB[f2]; \
 [4]format=yuva444p,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+16/TB[f3]; \
 [0][f0]overlay[bg1];[bg1][f1]overlay[bg2];[bg2][f2]overlay[bg3]; \
 [bg3][f3]overlay,format=yuv420p[v]" -map "[v]" -map 5:a -shortest -movflags +faststart out.mp4

Faça o crossfade entre dois vídeos com áudio

Selecione 5 segundos de cada entrada e adicione um crossfade de 1 segundo:

ffmpeg -i input0.mp4 -i input1.mp4 -filter_complex \
"[0:v]trim=start=5:end=10,setpts=PTS-STARTPTS[v0];
 [1:v]trim=start=12:end=17,setpts=PTS-STARTPTS+4/TB,format=yuva444p,fade=st=4:d=1:t=in:alpha=1[v1];
 [v0][v1]overlay,format=yuv420p[v];
 [0:a]atrim=start=5:end=10,asetpts=PTS-STARTPTS[a0];
 [1:a]atrim=start=12:end=17,asetpts=PTS-STARTPTS[a1];
 [a0][a1]acrossfade=d=1[a]" \
-map "[v]" -map "[a]" output.mp4

Saída GIF

ffmpeg \
-framerate 10 -loop 1 -t 5 -i 1.png \
-framerate 10 -loop 1 -t 5 -i 2.png \
-framerate 10 -loop 1 -t 5 -i 3.png \
-framerate 10 -loop 1 -t 5 -i 4.png \
-framerate 10 -loop 1 -t 5 -i 5.png \
-filter_complex \
"[1]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+4/TB[f0]; \
 [2]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+8/TB[f1]; \
 [3]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+12/TB[f2]; \
 [4]format=rgba,fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+16/TB[f3]; \
 [0][f0]overlay[bg1];[bg1][f1]overlay[bg2];[bg2][f2]overlay[bg3];[bg3][f3]overlay,split[v0][v1]; \
 [v0]palettegen[p];[v1][p]paletteuse[v]" -map "[v]" out.gif

Use a -loopopção de saída para controlar o número de vezes que o GIF faz um loop. O padrão é loop infinito se esta opção não for usada. Um valor de -1é sem loop.

llogan
fonte
1
@ LordNeckbeard, obrigado por esta resposta, usei-a para outro exemplo. Tenho entendido bem que o número seguinte -tno -loop 1 -t 1 -i 001.pngdefine a duração de quadros individuais, e que os números seguintes T/dentro de filter_complexbloco define a duração da transição? E a duração do quadro neste exemplo é contada, incluindo a duração da transição ou não?
Cincplug
1
@ Nisarg Isso não parece ser a saída completa e não sei ao certo qual é o comando dos dois que você exibiu anteriormente. De qualquer forma, tente adicionar -preset ultrafast.
Llogan 6/08/16
1
@LordNeckbeard Preciso combinar um conjunto de imagens, clipes de vídeo e uma faixa de áudio para criar um único arquivo de vídeo (de preferência ogg, mas que é menos relevante neste momento). Além disso, preciso criar alguns efeitos de transição entre imagens adjacentes. Existe alguma maneira de fazer o script de toda essa tarefa usando ffmpeg e / ou outras ferramentas de linha de comando? O objetivo é automatizar a tarefa por meio de uma interface de linha de comando.
Usuário Web
1
As transições do @WebUser provavelmente serão mais fáceis de usar melt.
Llogan 23/08/16
2
A abordagem ffmpeg está funcionando bem para mim; obrigado! Uma dica para os novatos na página; na concat=n=9parte do comando, 9vem das 5 imagens no exemplo + 4 transições entre as imagens. Se você estiver lidando com um número diferente de imagens, precisará ajustá-lo de acordo.
Jim Miller
4

Eu escrevi um script bash geral que leva no caminho para uma pasta de imagens e gera um vídeo crossfade com ffmpeg:

https://gist.github.com/anguyen8/d0630b6aef6c1cd79b9a1341e88a573e

O script essencialmente analisa as imagens em uma pasta e imprime um comando semelhante à resposta do @LordNeckbeard acima, e executa o comando. Esse script ajuda quando você tem muitas imagens em uma pasta e não deseja digitar manualmente um comando deprimente.

anh_ng8
fonte
Desculpe, mas seu script falha com o ffmpeg 3.0.1, com as entradas # 0 a # 4 e ele retorna: "Índice de arquivo inválido 5 na descrição do filtro"
Krzysztof Bociurko
TobySpeight: bom ponto, editei a resposta para ficar mais claro. Basicamente, a idéia principal já é dada por @LordNeckbeard acima. Este script apenas generaliza para muitas imagens.
Anh_ng8