Using MoviePy to Average Videos

I was playing about using ImageMagick to average videos in the style discussed in an old blog from @patdavid on photo averaging, (useful for pseudo long exposure shots).

As mentioned in the blog ImageMagick has a nasty habit of loading all off the video at once so it is necessary to split into frames first, which uses a lot of disk space, and even then it will be necessary to batch the images to make things manageable.

Being a great fan of Python I decided to see if I could batch process by iterating over the frames one at a time and accumulating and of course it is possible but you still have all of those files, and all of that disk space.

Say hello to two very useful python libraries, (currently only available for Python 2):

  • MoviePy: A Python module for video editing, note this library has a few dependencies and also uses FFMPEG but will download it on first use if it is not already available
  • youtube-dl: A command-line program to download videos from YouTube.com and other video sites used to demo this process.

I decided to try to replicate the results of processing Die Antwoord - “I Fink You Freeky“ so downloaded from You Tube with:
> youtube-dl https://youtu.be/8Uee_mcxvrw -f mp4
[youtube] 8Uee_mcxvrw: Downloading webpage
[youtube] 8Uee_mcxvrw: Downloading video info webpage
[youtube] 8Uee_mcxvrw: Extracting video information
[download] Destination: ‘I FINK U FREEKY’ by DIE ANTWOORD (Official)-8Uee_mcxvrw.mp4
[download] 100% of 31.72MiB in 00:05

Then I was able to process the video with the following python code:

from moviepy.editor import *
clip = VideoFileClip("'I FINK U FREEKY' by DIE ANTWOORD (Official)-8Uee_mcxvrw.mp4")
fps= 2.0 # take 2 frame per second seems like a fast enough sample rate
nframes = clip.duration*fps # total number of frames used
total_image = sum(clip.iter_frames(fps,dtype=float,progress_bar=True))  # Calculate the totals
average_image = ImageClip(total_image/ nframes)  # Average
average_image.save_frame('Freeky.png')  # Save it.

Less than two minutes later I had the result:

I was working on Windows 10 but the above should work on most platforms - all of the software is free, gratis & open source.

4 Likes

Interesting. Your method is probably the better or simpler one. I would like to point out that I recall there being a way to manage how the buffer is handled in IM so that the memory load is not as severe and a way to load an image only when it is needed. For that, you might want to check the documentation or ask on their forum. They are very nice people.

1 Like

@David_Tschumperle actually solved this problem for me in G’MIC nicely by having a running average be computed as each frame is loaded, then releasing the memory for it once added to the stack. For mean averages it’s super fast and easy to use. I’d love to play with what you’ve produced when I get a moment to breath! Thank you for sharing! :smiley:

1 Like

Like @patdavid said, G’MIC has a bunch of commands that pertain to your query. Also see A guide about computing the temporal average/median of video frames with G’MIC.

1 Like

What an excellent choice of source material!

1 Like