Créez une vidéo avec 5 images avec effet fadeIn / out dans ffmpeg

27

Avec 5 images, je dois créer une vidéo de 60 secondes dans ffmpeg, chaque image doit s'afficher pendant 15 secondes. après 15 secondes, la première image doit apparaître en fondu et la deuxième image doit apparaître en fondu, après cette deuxième image doit disparaître, la troisième image doit apparaître en fondu, etc. Veuillez me guider comment puis-je y parvenir à l'aide des commandes ffmpeg.

user384847
la source
4
Qu'avez-vous essayé et ensuite nous pouvons vous aider? Ce forum n'est pas un forum de type "veuillez me donner la réponse sans faire de travail". Cela dit, je vous fournirai le lien vers la documentation de ffmpeg fade - ffmpeg.org/ffmpeg-filters.html#fade
Mike Diglio

Réponses:

49

Dip / fondu au noir

Faites défiler vers le bas pour la méthode de fondu.

exemple de fondu

Exemple où chaque image affichée pendant 5 secondes et chacune a un fondu qui dure 1 seconde. Chaque entrée d'image a la même largeur, hauteur et rapport d'aspect d'échantillon. S'ils varient en taille, voir l'exemple n ° 3 ci-dessous.

Sortie 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

Avec audio

Comme ci-dessus mais avec audio:

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

Pour des images d'entrée de tailles variables ou arbitraires

Comme le premier exemple, mais avec des images d'entrée qui varient en largeur x hauteur. Ils seront rembourrés pour tenir dans une boîte 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

Voir les exemples dans Redimensionner des vidéos pour qu'elles tiennent dans un lecteur de taille statique si vous souhaitez recadrer (remplir l'écran) au lieu de pad (boîte aux lettres / pilier), ou si vous voulez empêcher la mise à l'échelle.

Sortie GIF

Ajoute les filtres de Comment convertir une vidéo en GIF en utilisant ffmpeg, avec une qualité raisonnable?

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

Utilisez l' -loopoption de sortie pour contrôler le nombre de boucles GIF. La valeur par défaut est boucle infinie si cette option n'est pas utilisée. Une valeur de -1n'est pas une boucle.

Options et filtres utilisés:

  • -t pour régler la durée en secondes de chaque entrée.

  • -loop 1 boucle l'image sinon elle aurait une durée de 1 image.

  • -frameratepour définir le taux de trame de l'image d'entrée (par défaut lorsque non déclaré est 25). Utile pour créer des GIF.

  • mettre à l'échelle avec un tampon pour adapter les images d'entrée dans une taille spécifique et uniforme (utilisée dans l'exemple # 3).

  • fondu pour fondre en avant et en arrière. dest la durée du fondu. stc'est quand ça commence.

  • concatène pour concaténer (ou "joindre") chaque image.

  • format pour sortir un schéma de sous-échantillonnage chromatique compatible avec les lecteurs non basés sur FFmpeg si la sortie MP4 et le codage avec libx264 (l'encodeur par défaut pour la sortie MP4 s'il est pris en charge par votre build).

  • fractionner pour faire des copies d'une sortie de filtre. Nécessaire par les filtres de palette * pour tout faire en une seule commande.

  • palettegen et paletteuse pour faire de beaux GIF.


Fondu enchaîné

exemple de fondu enchaîné

Exemple où chaque image affichée pendant 5 secondes et chacune a un fondu enchaîné qui dure 1 seconde. Chaque entrée d'image a la même largeur, hauteur et rapport d'aspect d'échantillon. S'ils varient en taille, adaptez l'exemple # 3 ci-dessus.

Sortie 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

Avec audio

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

Fondu enchaîné entre deux vidéos avec audio

Sélectionnez un segment de 5 secondes dans chaque entrée et ajoutez un fondu enchaîné de 1 seconde:

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

Sortie 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

Utilisez l' -loopoption de sortie pour contrôler le nombre de boucles GIF. La valeur par défaut est boucle infinie si cette option n'est pas utilisée. Une valeur de -1n'est pas une boucle.

llogan
la source
1
@LordNeckbeard, merci pour cette réponse, je l'ai utilisé pour un autre exemple. Ai-je bien compris que le nombre suivant -tdans -loop 1 -t 1 -i 001.pngdéfinit la durée des images individuelles et que les nombres suivant T/dans le filter_complexbloc définissent la durée de la transition? Et la durée de la trame dans cet exemple est-elle comptée, y compris la durée de la transition ou non?
courant
1
@Nisarg Cela ne semble pas être la sortie complète et je ne sais pas de quelle commande il s'agit des deux que vous avez affichées plus tôt. Quoi qu'il en soit, essayez d'ajouter -preset ultrafast.
llogan
1
@LordNeckbeard J'ai besoin de combiner un ensemble d'images, de clips vidéo et une piste audio pour créer un seul fichier vidéo (de préférence ogg, mais c'est moins pertinent à ce stade). De plus, je dois créer des effets de transition entre des images adjacentes. Existe-t-il un moyen de créer un script pour cette tâche en utilisant ffmpeg et / ou d'autres outils de ligne de commande? L'objectif est d'automatiser la tâche via une interface de ligne de commande.
Utilisateur Web
1
@WebUser Transitions sera probablement plus facile à utiliser melt.
llogan
2
L'approche ffmpeg fonctionne bien pour moi; Merci! Un conseil pour les nouveaux arrivants sur la page; dans la concat=n=9partie de la commande, le 9provient des 5 images de l'exemple + 4 transitions entre les images. Si vous gérez un nombre différent d'images, vous devrez l'ajuster en conséquence.
Jim Miller
4

J'ai écrit un script bash général qui prend un chemin vers un dossier d'images et produit une vidéo de fondu enchaîné avec ffmpeg:

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

Le script examine essentiellement les images dans un dossier et imprime une commande similaire à la réponse de @LordNeckbeard ci-dessus, et exécute la commande. Ce script est utile lorsque vous avez de nombreuses images dans un dossier et que vous ne voulez pas saisir manuellement une commande d'une longueur déprimante.

anh_ng8
la source
Désolé, mais votre script échoue avec ffmpeg 3.0.1, avec les entrées # 0 à # 4, il renvoie: "Index de fichier 5 non valide dans la description du filtre"
Krzysztof Bociurko
TobySpeight: bon point, j'ai édité la réponse pour être plus clair. Fondamentalement, l'idée principale est déjà donnée par @LordNeckbeard ci-dessus. Ce script se généralise simplement à de nombreuses images.
anh_ng8