Whether you want to measure the quality of the video or make estimates of storage requirements and streaming bandwidth, understanding video dimensions is a fundamental aspect of working with digital video.
Here are three methods for fetching a video file’s dimensions in Python:
- Using OpenCV
- Using FFmpeg (ffprobe)
- Using Moviepy
To demonstrate, I will use the “sample.mp4” video in this practical:
Method 1: Using OpenCV
The OpenCV is a computer vision library that is helpful when you are doing advanced video processing using Python.
We will create a custom function that will accept the video file and open using the cv2.VideoCapture() method. Then, extract the dimensions using .get(cv2.CAP_PROP_FRAME_WIDTH) for the width of the video and .get(cv2.CAP_PROP_FRAME_HEIGHT) for the height of the video. Finally, release the video using .release() method.
Decision Tree Diagram
The above decision tree diagram visualizes the successful path to get the dimensions of the video and in case the file doesn’t exist or can’t be opened, it will handle the various exceptions related to that.
Install the opencv-python library using the command below:
pip install opencv-python
Code example
Let’s write a Python code that implements the diagram:
import cv2 import os # Creating a custom function that returns dimensions def get_video_dimensions_cv2(video_path): try: # Check if the video file exists if not os.path.exists(video_path): raise FileNotFoundError(f"Video file '{video_path}' not found.") # Open the video file video = cv2.VideoCapture(video_path) if not video.isOpened(): raise Exception("Error opening video file.") # Get width and height of the video width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)) # Release the video object video.release() # Return the video dimensions return width, height # Handling FileNotFoundError exception except FileNotFoundError as e: print(f"File Error: {e}") except Exception as e: print(f"An error occurred: {e}") finally: if 'video' in locals() and video.isOpened(): video.release() # Defining sample video video_path = "sample.mp4" # Calling the custom function width, height = get_video_dimensions_cv2(video_path) if width and height: print(f"Video dimensions: {width}x{height}")
Output
Video dimensions: 2160x3840
You can see from the above output that the width is 2160 and the height is 3840.
The OpenCV library is not only helpful in getting dimensions but also for fetching the total number of frames, video duration, and FPS. Furthermore, it can handle a variety of video formats and returns accurate and reliable information about input files.
However, it can become complex compared to other methods and requires a learning curve.
If you are already using OpenCV for image and video processing then it is an ideal choice since you don’t need other packages to get the dimensions.
The time complexity for this operation is O(1).
The space complexity for this operation is O(1).
Method 2: Using FFMpeg(ffprobe)
The FFMpeg is an open-source library to edit audio and video files. We can use the “subprocess” module to execute the ffprobe commands to get the dimensions.
We will create a custom function that will accept a video file, check the necessary validation of the file, construct the FFprobe command, run the FFprobe command, and Parse JSON output.
Decision Tree Diagram
The above decision tree describes the conditional flow of checking a video file’s existence, executing the FFprobe command, and getting the output in pictorial representation.
Before you go for the code, you must install the FFMpeg library. I am using Mac but if you are using Linux or Windows, figure out how to install it using quick search.
brew install ffmpeg
Code example
import subprocess import json import os # Custom function def get_video_dimensions_ffprobe(video_path): try: # Check if the video file exists if not os.path.exists(video_path): raise FileNotFoundError(f"Video file '{video_path}' not found.") # Constructing FFprobe command to extract width and height of the video cmd = ['ffprobe', '-v', 'error', '-select_streams', 'v:0', '-count_packets', '-show_entries', 'stream=width,height', '-of', 'json', video_path] # Run the command result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Check if the command ran successfully if result.returncode != 0: raise Exception(f"FFprobe error: {result.stderr.decode('utf-8')}") # Parsing the JSON output try: data = json.loads(result.stdout) width = int(data['streams'][0]['width']) height = int(data['streams'][0]['height']) except (KeyError, IndexError, ValueError) as e: raise Exception(f"Error parsing FFprobe output: {e}") return width, height except FileNotFoundError as e: print(f"File Error: {e}") except Exception as e: print(f"An error occurred: {e}") # Defining the sample video video_path = "sample.mp4" # Calling the custom function width, height = get_video_dimensions_ffprobe(video_path) # Conditionally checking width and height if width and height: print(f"Video dimensions: {width}x{height}")
Output
Video dimensions: 2160x3840
The ffprobe is an efficient way depending on the size of the video. Furthermore, it can handle any video format and provides detailed information.
However, you need to install FFmpeg on your machine, and depends on the subprocess module which is considered the less Pythonic way.
The time complexity is O(1).
The space complexity is O(1).
Method 3: Using Moviepy
The moviepy is a specific third-party library in Python that is used to edit video, audio, and other multimedia operations.
We will create a custom function that loads the video using the VideoFileClip() function, captures the dimensions using clip.w, clip.h properties, and finally close the video using the .close() method.
Decision Tree Diagram
The above diagram image illustrates the step-by-step logic of using the moviepy library to load a video and get its width and height.
You can install the moviepy library using the command below:
pip install moviepy
Code example
from moviepy.editor import VideoFileClip import os # Custom function to process the video # Using moviepy library def get_video_dimensions_moviepy(video_path): try: # Checking if the video file exists if not os.path.exists(video_path): raise FileNotFoundError(f"Video file '{video_path}' not found.") # Loading the video clip try: clip = VideoFileClip(video_path) except Exception as e: raise Exception(f"Error loading video file: {e}") # Getting the width and height of the video width, height = clip.w, clip.h # Closing the video clip clip.close() return width, height except FileNotFoundError as e: print(f"File Error: {e}") except Exception as e: print(f"An error occurred: {e}") finally: # Ensuring the video clip is closed even in case of an error if 'clip' in locals(): clip.close() # Example sample video video_path = "sample.mp4" width, height = get_video_dimensions_moviepy(video_path) if width and height: print(f"Video dimensions: {width}x{height}")
Output
Video dimensions: 2160x3840
The usage of the moviepy library is a pure Python solution. Furthermore, it provides an easy API and is helpful in various video editing tasks. However, it is the slowest method among the three and an overkill if you are using it for getting dimensions and not other tasks.
Time complexity is O(1).
Space complexity is O(1).
Execution time measurement
I undertook experiments to measure the duration of each method and concluded that OpenCV is the fastest method and moviepy is the slowest method. Here is the bar chart that proves my point:
The above bar chart depicts that OpenCV took 0.12s to execute, the FFprobe approach took 0.238s, and the slowest approach moviepy took 1.671s.