Skip to main content

Command Palette

Search for a command to run...

Build a Screen Recorder in Python (pyautogui + OpenCV+win32api)

Updated
โ€ข5 min read
Build a Screen Recorder in Python (pyautogui + OpenCV+win32api)
A

Driven Data Science and Machine Learning enthusiast with hands-on experience in data analysis, predictive modeling, and Power BI visualization. Completed a Data Science internship at Codesoft, building strong technical foundations. With 2.5 years as a Shopify Executive and a background in system administration and malware analysis, I bring a broad IT skill set. Passionate about transforming complex data into actionable insights and contributing to innovative, fast-paced teams.

Recording your screen can be extremely useful for quick demos, bug reports, tutorials, or usability tests. In this short guide, you'll build a simple screen recorder in Python that:

  • captures screenshots,

  • writes them into a video file (MP4/AVI),

This is meant to be beginner-friendly and easy to adapt.


What you'll build

A small script (ScreenSnapper.py) that:

  • captures the primary display,

  • converts screenshots to frames for OpenCV,

  • saves the recording to a video file,

  • can be run from the command line with options.


Prerequisites

  • Windows (uses GetSystemMetrics from pywin32 in the example; you can adapt for other OSes).

  • Python 3.7+

  • Pip

Install the required packages (PowerShell):

python -m pip install --upgrade pip
python -m pip install opencv-python numpy pyautogui pywin32

The script (complete)

Save the following as ScreenSnapper.py. It contains a record_screen() function :

#!/usr/bin/env python3
"""
ScreenSnapper.py
Simple screen recorder with a small CLI.
"""

# Imports: libraries used in the script
import cv2               # OpenCV: for video writing and color conversion
import numpy as np       # NumPy: for array handling
import pyautogui         # pyautogui: to grab screenshots (returns a PIL Image)
import time              # time: to control duration and timestamps
from win32api import GetSystemMetrics  # Windows API: to get screen resolution

# Screen size 
# Get the width and height of the primary display (pixels)
# GetSystemMetrics(0) -> screen width, GetSystemMetrics(1) -> screen height
width = GetSystemMetrics(0)
height = GetSystemMetrics(1)
# Frame size for the video writer (width, height)
dimen = (width, height)

# Video writer setup
# FourCC is a 4-byte code that tells OpenCV which codec to use to compress video.
# 'XVID' is commonly used and works on many systems. Other options: 'MJPG', 'H264' (system dependent).
frmt = cv2.VideoWriter_fourcc(*"XVID")

# Create a VideoWriter object to save the video file.
# Parameters:
# - filename: where to save the video (relative to current working directory or absolute path)
# - fourcc: compression codec
# - fps: frames per second (how many frames we want recorded each second)
# - frameSize: the size (width, height) of each frame in pixels
# Note: We choose 20.0 fps here. The script currently captures screenshots as fast as possible and writes
# them; if you want an exact frame rate, see the comment below on sleeping to match fps.
output = cv2.VideoWriter("output.mp4", frmt, 20.0, dimen)

# Timing / duration
# Record for a fixed number of seconds. Change `dur` to make the recording longer or shorter.
start_time = time.time()
# duration in seconds
dur = 10  # change this to record longer/shorter
end_time = start_time + dur

# Capture loop
# Keep taking screenshots and writing them to the video until time runs out.
while True:
    # Take a screenshot using pyautogui. This returns a PIL Image in RGB format.
    image = pyautogui.screenshot()

    # Convert the PIL Image to a NumPy array (height, width, channels) in RGB order.
    frame_1 = np.array(image)

    # OpenCV expects images in BGR color order. Convert from RGB -> BGR so colors look correct in the saved video.
    # Use cv2.COLOR_RGB2BGR because pyautogui/PIL provide RGB arrays.
    frame = cv2.cvtColor(frame_1, cv2.COLOR_RGB2BGR)

    # Write the converted frame to the video file.
    output.write(frame)

    # If you want a stable frame rate (for example exactly 20 fps), you can add a small sleep here:
    # time.sleep(1 / 20.0)  # sleep for one frame at 20 fps
    # Note: adding sleep will limit CPU usage and stabilize the fps, but it also reduces the number of frames captured
    # when the system is fast enough to capture more. Choose based on your needs.

    # Check current time and stop when the duration has elapsed
    cr_time = time.time()
    if cr_time > end_time:
        break

# Finish 
# Release the VideoWriter to flush and close the output file properly
output.release()
print("Recording Completed Successfully")

# Tips and notes 
# - If colors look inverted or wrong in the saved video, try swapping the conversion (RGB/BGR) or inspect frame_1's channel order.
# - If the video file does not play, try changing the codec/fourcc and file extension (e.g., use 'MJPG' and 'output.avi').
# - For a CLI or configurable duration/output filename, we can add argparse to accept parameters from the command line.
# - For long recordings, consider writing to disk in smaller chunks or using compression that your system supports well.

How the script works (brief)

  • We use pyautogui.screenshot() to grab the current screen. It returns a PIL image in RGB color order.

  • Convert that image to a NumPy array, then convert RGB โ†’ BGR for OpenCV.

  • cv2.VideoWriter writes frames to a video file. We choose a codec with cv2.VideoWriter_fourcc.


Run examples (PowerShell)

Default (10 seconds):

python ScreenSnapper.py

Custom:

python ScreenSnapper.py --duration 20 --output my_recording.mp4 --fps 15

Notes:

  • Try lowering fps if your machine is slow.

  • If the saved video plays with odd colors, check the RGB/BGR conversion.


Common improvements and next steps

The basic script is intentionally simple. Here are a few improvements you can add:

  • Use argparse (already included) to expose more options (region cropping, backend choice).

  • A CLI for taking imputs in realtime.

  • Add a progress indicator or countdown in the terminal so you see remaining time.

  • Use a faster capture backend such as mss for higher frame rates and lower CPU overhead.

  • Support capturing a region of the screen instead of the full monitor (pyautogui.screenshot(region=(x, y, w, h)) or use mss).

  • Add an option to split long recordings into chunked files.


Troubleshooting

  • Missing packages? Install with pip as shown above.

  • If the video file won't play, try a different codec/extension:

    • MJPG + .avi often plays on more systems.
  • pyautogui.screenshot() can be slow on some systems; mss is faster.


Final thoughts

This simple recorder is a great starting point to learn how to capture the screen programmatically and how to combine small Python libraries to build useful tools.

If you'd like, I can:

  • Add live progress display,

  • Add region capture,

  • Update the script to use mss as an optional backend for better performance,

  • Or create a small GUI wrapper with Tkinter for interactive recording.