Resized videos can take up less memory space and require less processing power to handle large batches of videos. Smaller videos are also easy to transmit from one location to another.
Here are two essential ways to resize a video in Python:
- Using moviepy
- Using FFmpeg via subprocess
To illustrate the process, I will use the following “sample.mp4” video in this practical.
The original size of the above video is (2160 X 3840). We will resize this video to (640 X 480).
Method 1: Using moviepy
The moviepy library is designed for video editing tasks such as resizing, cutting, and adding effects.
As illustrated in the above decision-tree diagram, we first check whether the input video file exists. We load the video using the VideoFileClip() function if it does.
Furthermore, we resized the video based on the specified height.
At last, save the resized video file in your output directory and close the video resources.
To implement the above diagram in the program, we need to install the “moviepy” library:
pip install moviepy
Code example
from moviepy.editor import VideoFileClip
# Custom function that accepts @input_path, @output_path, @height, and @width
def resize_video(input_path, output_path, width=None, height=None):
try:
# Loading the video
clip = VideoFileClip(input_path)
# Get original size
original_width, original_height = clip.size
print(f"Original video size: {original_width}x{original_height}")
# Check if both width and height are provided for resizing
if width is not None and height is not None:
# Resizing the video by specifying both width and height
resized_clip = clip.resize(newsize=(width, height))
elif width is not None:
# Resizing based only on width (moviepy will keep the aspect ratio)
resized_clip = clip.resize(width=width)
elif height is not None:
# Resizing based only on height (moviepy will keep the aspect ratio)
resized_clip = clip.resize(height=height)
else:
# If neither width nor height is provided, no resizing is done
resized_clip = clip
# Get resized size
resized_width, resized_height = resized_clip.size
print(f"Resized video size: {resized_width}x{resized_height}")
# Writing the result to a file
resized_clip.write_videofile(
output_path, codec='libx264', audio_codec='aac')
print(f"Video resized successfully. Saved as '{output_path}'.")
except FileNotFoundError as e:
print(f"File Error: {e}")
except Exception as e:
print(f"An error occurred: {e}")
finally:
# Ensuring resources are released
if 'clip' in locals():
clip.close()
if 'resized_clip' in locals():
resized_clip.close()
# Example usage
resize_video('sample.mp4', './output/resized.mp4', width=640, height=480)
Output
Original video size: 2160x3840 Resized video size: 640x480 Moviepy - Building video ./output/resized_video.mp4. MoviePy - Writing audio in resized_videoTEMP_MPY_wvf_snd.mp4 MoviePy - Done. Moviepy - Writing video ./output/resized_video.mp4 Moviepy - Done ! Moviepy - video ready ./output/resized_video.mp4 Video resized successfully. Saved as './output/resized.mp4'.
You can see from the above output that the input video is resized to 640X480.
The MoviePy library supports a wide range of video formats, codecs, and advanced editing features. However, it can be prolonged for larger videos and relies on FFmpeg and other libraries. So, FFmpeg must be installed on your system to work with moviepy.
The time complexity is O(N) because it depends on the size of the video, which is N.
The space complexity is O(N) and can take more memory if the video size is large.
Method 2: Using FFMpeg with subprocess
FFMpeg is a robust command-line tool for processing videos and other multimedia files. Python provides a subprocess module that allows you to create a command for FFMpeg to resize the video.
In the above diagram, we first check if the file exists.
If it does, we then create an FFmpeg command and execute it to resize the image. If the process fails, then it will display the error.
import subprocess
import os
# Custom function to get video dimensions using ffprobe (part of FFmpeg)
def get_video_dimensions(file_path):
try:
# Use ffprobe to get video width and height
command = [
'ffprobe',
'-v', 'error',
'-select_streams', 'v:0',
'-show_entries', 'stream=width,height',
'-of', 'csv=p=0:s=x',
file_path
]
# Run the ffprobe command
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Check if the command was successful
if result.returncode != 0:
raise Exception(f"ffprobe error: {result.stderr.decode('utf-8')}")
# Extract and return the dimensions as a tuple (width, height)
width, height = map(int, result.stdout.decode('utf-8').strip().split('x'))
return width, height
except Exception as e:
print(f"An error occurred while retrieving video dimensions: {e}")
return None, None
# Custom function that will accept input file, output file path, new height, and new width
def resize_video_ffmpeg(input_file, output_file, new_width, new_height):
try:
# Check if the input video file exists
if not os.path.exists(input_file):
raise FileNotFoundError(f"Input video file '{input_file}' not found.")
# Get the original dimensions
original_width, original_height = get_video_dimensions(input_file)
if original_width and original_height:
print(f"Original video size: {original_width}x{original_height}")
# Build the FFmpeg command to resize the video
command = [
'ffmpeg',
'-i', input_file,
'-vf', f'scale={new_width}:{new_height}',
output_file
]
# Run the FFmpeg command
result = subprocess.run(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Check if the FFmpeg command was successful
if result.returncode != 0:
raise Exception(f"FFmpeg error: {result.stderr.decode('utf-8')}")
# Get the new dimensions of the resized video
resized_width, resized_height = get_video_dimensions(output_file)
if resized_width and resized_height:
print(f"Resized video size: {resized_width}x{resized_height}")
except FileNotFoundError as e:
print(f"File Error: {e}")
except Exception as e:
print(f"An error occurred: {e}")
# Calling the function
resize_video_ffmpeg('sample.mp4', 'resized_ffmpeg.mp4', 640, 480)
Output
Original video size: 2160x3840 Resized video size: 640x480
The FFMpeg with subprocess approach is fast, efficient, and supports a wide range of video formats. However, the command line does not provide the same level of control as the moviepy library, and its behavior may vary across different operating systems.
I highly recommend this approach if you want to process the video quickly using batch processing.
Time measurement for executing each approach
I ran a time-tracking experiment for each method and created a bar chart like the one below:
As you can see from the above bar chart, the fastest method is FFmpeg with a subprocess module with 4.45s, and the slowest method is movies with 10.48s, as expected.



