Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/bin/bash
# Anh Nguyen <anh.ng8@gmail.com>
# 2016-04-30
# MIT License
# This script takes in images from a folder and make a crossfade video from the images using ffmpeg.
# Make sure you have ffmpeg installed before running.
# The output command looks something like the below, but for as many images as you have in the folder.
# See the answer by LordNeckbeard at:
# http://superuser.com/questions/833232/create-video-with-5-images-with-fadein-out-effect-in-ffmpeg/1071748#1071748
#
#
# ffmpeg \
# -loop 1 -t 1 -i 001.png \
# -loop 1 -t 1 -i 002.png \
# -loop 1 -t 1 -i 003.png \
# -loop 1 -t 1 -i 004.png \
# -loop 1 -t 1 -i 005.png \
# -filter_complex \
# "[1:v][0:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b1v]; \
# [2:v][1:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b2v]; \
# [3:v][2:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b3v]; \
# [4:v][3:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b4v]; \
# [0:v][b1v][1:v][b2v][2:v][b3v][3:v][b4v][4:v]concat=n=9:v=1:a=0,format=yuv420p[v]" -map "[v]" out.mp4
#----------------------------------------------------------------
# SETTINGS
input_dir="/path/to/your/folder" # Replace this by a path to your folder /path/to/your/folder
n_files=10 # Replace this by a number of images
files=`ls ${input_dir}/*.jpg | head -${n_files}` # Change the file type to the correct type of your images
output_file="video.mp4" # Name of output video
crossfade=0.9 # Crossfade duration between two images
#----------------------------------------------------------------
# Making an ffmpeg script...
input=""
filters=""
output="[0:v]"
i=0
for f in ${files}; do
input+=" -loop 1 -t 1 -i $f"
next=$((i+1))
if [ "${i}" -ne "$((n_files-1))" ]; then
filters+=" [${next}:v][${i}:v]blend=all_expr='A*(if(gte(T,${crossfade}),1,T/${crossfade}))+B*(1-(if(gte(T,${crossfade}),1,T/${crossfade})))'[b${next}v];"
fi
if [ "${i}" -gt "0" ]; then
output+="[b${i}v][${i}:v]"
fi
i=$((i+1))
done
output+="concat=n=$((i * 2 - 1)):v=1:a=0,format=yuv420p[v]\" -map \"[v]\" ${output_file}"
script="ffmpeg ${input} -filter_complex \"${filters} ${output}"
echo ${script}
# Run it
eval "${script}"
@DavidOliver

This comment has been minimized.

Copy link

commented Jul 9, 2016

Hi @anguyen8. Thanks for this script.

Between each crossfade there is a pause of a second or two where the image is shown. How can I remove this please? I'm trying to fade multiple eight-second exposures of polar lights into each other to improve the sense of slowish movement.

Edit: I'm now accomplishing what I need to do with G'MIC.

@jeffehobbs

This comment has been minimized.

Copy link

commented Aug 20, 2016

Great script! Really helps with those complicated ffmpeg filter config statements.

@anguyen8

This comment has been minimized.

Copy link
Owner Author

commented Sep 21, 2016

@DavidOliver: probably you got your solution by now. But I'd say it's the crossfade of 0.9 that you can tweak.

@kosar

This comment has been minimized.

Copy link

commented Oct 1, 2016

@DavidOliver: I would appreciate if you could post how you did this in G'MIC. As far as I can tell it is not easy to do. I tried posting a question to their Google Group.
@anguyen8: I did something similar to this using Powershell -- I will try this now, using a *nix system.
EDIT: here is my super early super hacky version of this in Powershell. https://github.com/kosar/miv

@hasnhasan

This comment has been minimized.

Copy link

commented Jan 31, 2017

I'm getting an error. Could you help ?

Invalid file index 5 in filtergraph description [1:v][0:v]blend=all_expr='A*(if(gte(T,0.9),1,T/0.9))+B*(1-(if(gte(T,0.9),1,T/0.9)))'[b1v]; [2:v][1:v]blend=all_expr='A*(if(gte(T,0.9),1,T/0.9))+B*(1-(if(gte(T,0.9),1,T/0.9)))'[b2v]; [3:v][2:v]blend=all_expr='A*(if(gte(T,0.9),1,T/0.9))+B*(1-(if(gte(T,0.9),1,T/0.9)))'[b3v]; [4:v][3:v]blend=all_expr='A*(if(gte(T,0.9),1,T/0.9))+B*(1-(if(gte(T,0.9),1,T/0.9)))'[b4v]; [5:v][4:v]blend=all_expr='A*(if(gte(T,0.9),1,T/0.9))+B*(1-(if(gte(T,0.9),1,T/0.9)))'[b5v]; [0:v][b1v][1:v][b2v][2:v][b3v][3:v][b4v][4:v]concat=n=9:v=1:a=0,format=yuv420p[v].

@iBobik

This comment has been minimized.

Copy link

commented Mar 1, 2017

On line 46 I changed time to -t 15, so one image will be there shown for 15 seconds, but it prints very long output like this:

[Parsed_blend_5 @ 0x7fcdff606900] [framesync @ 0x7fcdff606ec8] Buffer queue overflow, dropping.
[Parsed_concat_8 @ 0x7fcdff609660] Buffer queue overflow, dropping.
[Parsed_blend_5 @ 0x7fcdff606900] [framesync @ 0x7fcdff606ec8] Buffer queue overflow, dropping.
[Parsed_concat_8 @ 0x7fcdff609660] Buffer queue overflow, dropping.
[Parsed_blend_5 @ 0x7fcdff606900] [framesync @ 0x7fcdff606ec8] Buffer queue overflow, dropping.
[Parsed_concat_8 @ 0x7fcdff609660] Buffer queue overflow, dropping.

Do you know how to fix it?

@MotionDesignStudio

This comment has been minimized.

Copy link

commented Apr 10, 2017

How can I control the display length of time for each image? Changing this input+=" -loop 1 -t 1 -i $f" to input+=" -loop 1 -t 15 -i $f" only makes the second image display 30 seconds and the third 45 seconds. So it adds 15 seconds to each image.

@KalpeshJadvani

This comment has been minimized.

Copy link

commented Apr 25, 2017

can you tell me how i can add mp3 file in this command ... plz i have done this script but i could not add mp3 file in this complex command ....

@ZuzooVn

This comment has been minimized.

Copy link

commented Jul 15, 2017

@anguyen8: can you add more animation for ffmpeg slideshow?

@spiralofhope

This comment has been minimized.

Copy link

commented Apr 20, 2018

The URL can be shortened:

http://superuser.com/questions/833232/create-video-with-5-images-with-fadein-out-effect-in-ffmpeg/1071748#1071748
=>
http://superuser.com/questions/833232#1071748
@gcrowder1

This comment has been minimized.

Copy link

commented Dec 7, 2018

Thank you friends, your script successfully solved my problem. If the image size is different, an error will occur. But the problem is not big, I have processed the image to the same size. Thanks again

@shakram02

This comment has been minimized.

Copy link

commented Apr 24, 2019

Thank you so much, worked like a charm 🙏.
I converted it to python if anyone is interested, here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.