
Today, we are going to try to understand how python library moviepy works. I had a requirement for video extraction, so moviepy seems to fit the bill perfectly.
Shamelessly copying from pypi, here is what it says,
MoviePy is a Python library for video editing: cutting, concatenations, title insertions, video compositing (a.k.a. non-linear editing), video processing, and creation of custom effects.
Installation
We will install moviepy in a virtual environment. For this project, we will use pip to create virtual environment. You can find more details for moviepy installation here.
$ python -m venv moviepytest $ . ./moviepytest/bin/activate (moviepytest)$ pip install moviepy
The commands above will create a virtual environment called moviepytest and install moviepy in it.
My requirement was fairly simple. I needed to read timing information from a database and extract clips based on the start and end time. Finally, I had to merge all these clips to create a mpeg file for output.
Moviepy makes creating this very simple. Let us look at the code for doing this workflow.
Video Extraction and Merge
Instead of a database, for this blog I just created a CSV file that has the start and end times listed. We will be extracting videos based on this file.
00:05, 00:15
00:20, 01:20
02:10, 02:45
03:10, 03:75
This file lists some start and end times. For example, the first line says start extracting from 5 second mark and continue extracting till 15 second mark. Similarly rest of the lines follow.
We use csv library to load this file.
def get_timings(self, flname): ins = [] with open(flname, newline='') as f: aline = csv.reader(f, delimiter=',') for cols in aline: ins.append(cols) return ins
Next step is to start extraction of the clips. We will extract clips using subclip function. In this case we are also adding the extracted clips to an array for future processing. Also, just for fun, I am randomly changing some subclip color to grayscale. Moviepy has a lot of special effects (fx package). The effects range from grayscale, resizing, luminosity change etc.
subclips = [] # Load video clip = VideoFileClip(vdo) print('Video length: %d' % clip.duration) # Extract clips first for tmng in tmngs: print('Extracting: %s' % tmng) # Make some clips black and white if (random.randint(1, 10) > 7): subclips.append(clip.subclip(tmng[0], tmng[1]).fx(blackwhite)) else: subclips.append(clip.subclip(tmng[0], tmng[1]))
Now that we have all the clips extracted, joining them and writing output mp4 file is just a matter of calling two functions.
merged = concatenate_videoclips(subclips) merged.write_videofile(vdo_out, fps=30, threads=10, codec="libx264")
See generated output.
Video length: 340 Extracting: ['00:05', ' 00:15'] Extracting: ['00:20', ' 01:20'] Extracting: ['02:10', ' 02:45'] Extracting: ['03:10', ' 03:75'] Moviepy - Building video rsc/belfort_out.mp4. MoviePy - Writing audio in belfort_outTEMP_MPY_wvf_snd.mp3 MoviePy - Done. Moviepy - Writing video rsc/belfort_out.mp4
Conclusion
This is a fairly short blog as it only touched the top of the iceberg. Moviepy supports a lot more features than what is covered here. One of the good examples that moviepy supports is face tracking. We can blur faces by tracking on moviepy. There are additional fx functions that can be done on the video. A lot of these fx will need ImageMagick installed for image processing.
I will finish this blog for today, as I am travelling and do not have much time for researching additional functionalities. Hope you find this blog useful. As usual, code will be on my github public repository. Ciao for now!