Showing posts with label images. Show all posts
Showing posts with label images. Show all posts

Sunday, October 27, 2019

Making Slideshows w/FFMpeg

Browsing Reddit or StackOverflow and you come across numerous posts asking how to generate slideshows with FFMpeg.  Seems a common interest and incredibly easy with the right tools.  FFMpeg is one of the said tools,the other....makefiles.

There are few utilities that are truly hated in this industry, makefiles seem to be one of them.  Despite it's poor reputation, make is a perfect utility for many image and video processing pipelines.  I blame it's bad reputation on the hacks that claim to maintain them.  Make is the perfect utility, it's dependency engine is a perfect match for creating videos from input media.

This short little makefile will convert all JPGs in the current directory into subvideos of 1 sec durations, then concat them together into a long video and finally adding audio.

$ cat Makefile 
SRCS=${wildcard *.jpg}
SIZES=$(subst .jpg,.jpg.size,${SRCS})
CLIPS=$(subst .jpg,.mp4,${SRCS})
SlideDuration=1
FPS=25

all: video.mp4

video.mp4: slideshow.mp4 audio.aac
${SH} ffmpeg -i slideshow.mp4 -i audio.aac -shortest -strict -2 $@

audio.aac:
${SH} youtube-dl -f best https://www.youtube.com/watch?v=IYbE2coMZPc
${SH} ffmpeg -i Íslandsklukkur\ \(Instrumental\ Icelandic\ Folk\ Music\)-IYbE2coMZPc.mp4 -vn -codec copy audio.aac

slideshow.mp4: ${CLIPS}
${SH} for f in `echo $^`; do echo "file '$$f'" >> filelist.txt; done;
${SH} ffmpeg -y -f concat -i filelist.txt -codec copy $@
${RM} filelist.txt

%.mp4: %.jpg video.size background.jpg
${SH} ffmpeg -y -loop 1 -i background.jpg -i $< -filter_complex "overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" -r $(FPS) -vframes $(shell echo $(FPS)*$(SlideDuration) | bc) -an $@

video.size: ${SIZES}
${SH} echo $(shell cat *.size | cut -f 1 -d 'x' | sort -un | tail -1)x$(shell cat *.size | cut -f 2 -d 'x' | sort -un | tail -1) > $@

%.jpg.size: %.jpg
${SH} mogrify -auto-orient $<
${SH} identify $< | cut -f 3 -d ' ' > $@

background.jpg: video.size
${SH} convert -size $(shell cat $<) xc:black $@

clean: 
${RM} *.mp4 *.size background.jpg *.aac

This makefile works for an arbitrary list of image sizes, it first auto-orients images (portrait/landscape) as it's not uncommon to have phone images mis-oriented.  It then generates a *.jpg.size file that contains the image dimensions.  These files are used next by the video.size target, which generates the maximum image size...this allows creating the video to match the largest of the images.  Next, a background jpg image is created of said dimensions.  Next, each image is converted into a 1 sec video which is then concatenated into the slideshow.mp4 file.  Finally, an audio video is created by downloading a video from Youtube and the audio is extracted, then applied to the slideshow mp4 file to get the final video.

I dumped our Iceland photo archive into the directory to test and it spit out the following video;


Monday, April 22, 2019

FFMpeg Blending










FFMpeg can blend two input files which allows for a gradual transition from one to the other.  This post will demonstrate how this can be done with two image files or video files.  Let's get started.

Blending Images

Let's snag a couple images to show how blending can be used in transitioning from one to the other.  More specifically, we're grabbing one image and cropping them to form two images.


$ wget https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Bush-Arnie-morph.jpg/300px-Bush-Arnie-morph.jpg -O src.jpg
$ convert -crop 100x300+0+0 src.jpg s1.jpg
$ convert -crop 100x300+200+0 src.jpg s2.jpg




Next, let's generate a 5 second video using the two source images.  Notice the A/B coefficients are relative to time finally capping at 1 when there remains 1 second of video left.  The blending coefficients define how much of one or the other video frame is blended.



$ ffmpeg -loop 1 -i s1.jpg -loop 1 -i s2.jpg -filter_complex "[1:v][0:v]blend=all_expr='A*(if(gte(T,$((5-1))),1,T/$((5-1))))+B*(1-(if(gte(T,$((5-1))),1,T/$((5-1)))))'" -t 5 foo.mp4



The result;

Blending Videos

We can provide a similar effect on videos.  Let's grab a source video and split it into two videos that we'll blend between.


$ youtube-dl -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' -o src.mp4 https://www.youtube.com/watch?v=-sUXMzkh-jI
$ ffmpeg -i src.mp4 -ss 10 -t 5 -an vid1.mp4
$ ffmpeg -i src.mp4 -ss 60 -t 5 -an vid2.mp4



Let's blend the videos in the same manner as our images;


$ ffmpeg -i vid1.mp4 -i vid2.mp4 -filter_complex "[1:v][0:v]blend=all_expr='A*(if(gte(T,$((5-1))),1,T/$((5-1))))+B*(1-(if(gte(T,$((5-1))),1,T/$((5-1)))))'" foo00.mp4





There you are, the most fun you can have while blending short of making margaritas.

Cheers.