Annotating Video Clips With MoviePy
Published: Jul 31, 2021
Last updated: Jul 31, 2021
This is Day 12 of the #100DaysOfPython challenge.
This post will use the MoviePyworkingoutloud.dev
Prerequisites
Getting started
Let's create the hello-moviepy
directory and install Pillow.
# Make the `hello-moviepy` directory $ mkdir hello-moviepy $ cd hello-moviepy # We will write everything in main.py $ touch main.py # Add this stage, you will need to add you video clip - I added mine to the `hello-moviepy` directory $ cp path/to/wol-dev.mp4 . # Init the virtual environment $ pipenv --three $ pipenv install moviepy
At this stage, we can write our script to annotate the video.
Annotating the video
As an example, here is a Gif of my video that I am editing:
Original video
The video is a short clip of my workingoutloud.dev
From watching the video, there are three things that are essentially in the demo:
- Viewing tasks and subtasks.
- Sorting subtasks.
- Opening the current goals.
These occur at the 0:00, 0:03 and 0:06 second mark respectively.
We can add in some captions for each of these easily thanks to MoviePy.
In main.py
, add the following:
from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip video = VideoFileClip("wol-dev.mp4")
In the above code, we simply import the required modules and then we create a VideoFileClip
object from the video file (relative to the project root directory).
We now want to create a TextClip
object for each of the three points in the video.
According to the MoviePy TextClip docsTextClip
constructor can take some relevant arguments around the text, font, color and font size.
The TextClip
instance itself then has access to methods to set the position, duration and start time. We will abstract our sensible defaults into a function and implement this:
def text_clip(text: str, duration: int, start_time: int = 0): """Return a description string on the bottom-left of the video Args: text (str): Text to show duration (int): Duration of clip start_time (int, optional): Time in video to start at (in seconds). Defaults to 0. Returns: moviepy.editor.TextClip: A instance of a TextClip """ return (TextClip(text, font="Arial", fontsize=24, color='black') .set_position((20, video.h - 44)) .set_duration(duration) .set_start(start_time)) # Make the text. Many more options are available. text_clip_one = text_clip("Create tasks and subtasks", 3) text_clip_two = text_clip("Sort subtasks by table header", 3, 3) text_clip_three = text_clip("View goals", 3, 6)
After writing out the helper method, we are creating three TextClip
instances for each of our different annotations that we wish to add to the video.
Finally, we can compose them all together into a CompositeVideoClip
object and write out the video file.
I am also writing out a
.gif
file to use as a preview of the video on this post.
# Overlay text on video result = CompositeVideoClip( [video, text_clip_one, text_clip_two, text_clip_three]) result.write_videofile("wol_dev_edited.mp4", fps=25) result.write_gif("wol_dev_edited.gif", fps=8)
We can now run our script with python main.py
. There will be some progress bars to indicate the progress.
After the script has completed, we can now see wol_dev_edited.mp4
and wol_dev_edited.gif
in the hello-moviepy
directory.
The outcome looks like so:
Annotated video
Summary
Today's post demonstrated how to use the MoviePy
package to add some text captions to a video programmatically.
I will be hoping to make use of this to help annotate some of my videos that I am working through to save some time in future.
The final code looks like so:
from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip video = VideoFileClip("wol-dev.mp4") def text_clip(text: str, duration: int, start_time: int = 0): """Return a description string on the bottom-left of the video Args: text (str): Text to show duration (int): Duration of clip start_time (int, optional): Time in video to start at (in seconds). Defaults to 0. Returns: moviepy.editor.TextClip: A instance of a TextClip """ return (TextClip(text, font="Arial", fontsize=24, color='black') .set_position((20, video.h - 44)) .set_duration(duration) .set_start(start_time)) # Make the text. Many more options are available. text_clip_one = text_clip("Create tasks and subtasks", 3) text_clip_two = text_clip("Sort subtasks by table header", 3, 3) text_clip_three = text_clip("View goals", 3, 6) # Overlay text on video result = CompositeVideoClip( [video, text_clip_one, text_clip_two, text_clip_three]) result.write_videofile("wol_dev_edited.mp4", fps=25) result.write_gif("wol_dev_edited.gif", fps=8)
Resources and further reading
Photo credit: element5digital
Dennis O'Keeffe
Melbourne, Australia
1,200+ PEOPLE ALREADY JOINED ❤️️
Get fresh posts + news direct to your inbox.
No spam. We only send you relevant content.
Annotating Video Clips With MoviePy
Introduction