53 lines
1.6 KiB
Bash
53 lines
1.6 KiB
Bash
#!/bin/sh
|
|
|
|
# Need at least an outfile and two images for this command to make sense.
|
|
if [ $# -lt 3 ]
|
|
then
|
|
echo USAGE: "$0" OUTFILE IMAGES...
|
|
echo Create simple slideshow video with blend effect between images.
|
|
echo
|
|
echo OUTFILE is video file to create, .mkv extension is recommended.
|
|
echo IMAGES is a sequence of images for the slideshow.
|
|
exit
|
|
fi
|
|
|
|
# 30 fps, so this means each original image corresponds to one second of video.
|
|
frames_per_image=30
|
|
fps=30
|
|
|
|
out="$1"
|
|
shift
|
|
|
|
# Create a temporary directory to store the frames in.
|
|
dir=$(mktemp -d)
|
|
|
|
# Iterate through the images keeping track of the previous one to be blended
|
|
# with the current one.
|
|
num=0 # frame number
|
|
prev='' # previous image or empty string if none
|
|
for image in "$@"
|
|
do
|
|
# If there is a previous image, blend with it.
|
|
if [ -f "$prev" ]
|
|
then
|
|
for fade_amount in $(seq 1 $((frames_per_image - 1)))
|
|
do
|
|
# Use bc for math to get decimals.
|
|
composite -blend "$(echo "$fade_amount/$frames_per_image*100" | bc -lq)" "$image" "$prev" "$dir/image$num"".png"
|
|
num=$((num + 1))
|
|
done
|
|
fi
|
|
# Always in include the actual image as one of the frames.
|
|
# Use convert so any image format will work.
|
|
convert "$image" "$dir/image${num}.png"
|
|
num=$((num + 1))
|
|
# Remember this image for the next iteration.
|
|
prev="$image"
|
|
done
|
|
|
|
# Encode the video from the frames.
|
|
# -pix_fmt yuv420p is normal pixel format, but default is yuv444p which
|
|
# ffmpeg warns might not be supported by all players.
|
|
ffmpeg -f image2 -i "$dir/image%d.png" -pix_fmt yuv420p -r "$fps" "$out"
|
|
# Delete the temporary directory with the frames.
|
|
rm -rf "$dir" |