Basic slide show from images - 2020
Because I have image files with different resolutions, I need to make them to have the same size. So, I run the following script for around 43 files (e01.jpg-e39.jpg). The output png files' resolution is set to 480x360 and with the same name as input files:
import os import subprocess def resize_files(fname): # ffmpeg -i a.jpg -vf scale=640:480 a.png out_fname = fname.replace('jpg','png') #print out_fname subprocess.call(['ffmpeg', '-i', fname, '-vf', 'scale=640:480', out_fname ]) def listFiles(dir): basedir = dir subdirlist = [] for item in os.listdir(dir): fullpath = os.path.join(basedir,item) if os.path.isdir(fullpath): print 'dir item=',fullpath subdirlist.append(fullpath) else: print 'file item=',fullpath if item.endswith('.jpg'): resize_files(fullpath) for subdir in subdirlist: listFiles(subdir) if __name__ == '__main__': listFiles('.');
So, the code will generate files with the same resolution. (e01.png-e39.png).
Now, it's time to create a video (using the encoder libx264) from series of numerically sequential images such as e01.png, e02.png, e03.png, etc.
As explained in Create a video slideshow from images , we can specify two frame rates:
- The rate according to which the images are read, by setting -r before -i. The default for reading input is -r 25 which will be set if no -r is specified.
- The output frame rate for the video stream by setting -r after -i, or by using the fps filter. If we want the input and output frame rates to be the same, then just declare an input -r and the output will inherit the same value.
By using a separate -r (frames per second) for the input and output we can control the duration at which each input is displayed and tell ffmpeg the frame rate we want for the output file. If the input -r is lower than the output -r then ffmpeg will duplicate frames to reach our desired output frame rate. If the input -r is higher than the output -r then ffmpeg will drop frames to reach your desired output frame rate.
ffmpeg -r 1/5 -i e%02d.png -c:v libx264 -r 30 -pix_fmt yuv420p EinsteinSlideShow.mp4
- -r 1/5: each image will have a duration of 5 seconds (the inverse of 1/5 frames per second).
- e%02d.png: sequential image input.
- -c:v: video coder.
- libx264: encoder library.
- -r 30: will have a frame rate of 30 fps by duplicating the frames accordingly.
- -pix_fmt yuv420p: pixel format.
"Y'UV420p is a planar format, meaning that the Y', U, and V values are grouped together instead of interspersed. The reason for this is that by grouping the U and V values together, the image becomes much more compressible. When given an array of an image in the Y'UV420p format, all the Y' values come first, followed by all the U values, followed finally by all the V values." - wiki.
"By default when using libx264, and depending on your input, ffmpeg will attempt to avoid color subsampling. Technically this is preferred, but unfortunately almost all video players, excluding FFmpeg based players, and many online video services only support the YUV color space with 4:2:0 chroma subsampling. Using the options -pix_fmt yuv420p or -vf format=yuv420p will maximize compatibility." - ffmpeg.org.
- EinsteinSlideShow.mp4: output video file name.
To display the slide show for several browsers, we need to convert mp4 to webm and ogv:
ffmpeg -i EinsteinSlideShow.mp4 EinsteinSlideShow.webm ffmpeg -i EinsteinSlideShow.mp4 EinsteinSlideShow.ogv
Here is the slide show:
Get all the files including each slide picture and the output slideshow files: SlideShow.zip.
Or the output slide show:
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization