Search code examples
pythonnumpyopencvpyautoguipython-mss

How to increase the fps of screen recorder in cv2


I have written a code to record the screen recorder using python but when i see the output then i found that its fps is very low .Is there any better code than mine to increase the fps of the screen recorder. If yes then please reply. Here is mine code:-

import cv2
import numpy as np
import pyautogui
import datetime
# display screen resolution, get it from your OS settings
SCREEN_SIZE = (1366, 768)
# define the codec
fourcc = cv2.VideoWriter_fourcc(*"XVID")
# create the video write object
now = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
out = cv2.VideoWriter("screen recorder"+now+".avi", fourcc, 5.0, (SCREEN_SIZE))
while True:
    img = pyautogui.screenshot()
    frame = np.array(img)
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    out.write(frame)
    cv2.imshow("screenshot", frame)
    # if the user clicks q, it exits
    if cv2.waitKey(1) == ord("q"):
        break
cv2.destroyAllWindows()
out.release()
img = pyautogui.screenshot(region=(0, 0, 300, 400))
 

Solution

  • The third parameter to the cv2.VideoWriter constructor is the frame rate (https://docs.opencv.org/3.4/dd/d9e/classcv_1_1VideoWriter.html#ac3478f6257454209fa99249cc03a5c59). Currently, you have it set to 5.0. For example, for 30 fps, instantiate the VideoWriter with:

    out = cv2.VideoWriter("screen recorder"+now+".avi", fourcc, 30.0, (SCREEN_SIZE))
    

    EDIT: In order to also read in images at the correct framerate, we can pause the while loop using the waitKey function. We can re-write the OP's code like so:

    import cv2
    import numpy as np
    import pyautogui
    import datetime
    import time
    # display screen resolution, get it from your OS settings
    SCREEN_SIZE = (1366, 768)
    FRAME_RATE = 30.0  # desired frame-rate
    # define the codec
    fourcc = cv2.VideoWriter_fourcc(*"XVID")
    # create the video write object
    now = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
    out = cv2.VideoWriter("screen recorder"+now+".avi", fourcc, FRAME_RATE, (SCREEN_SIZE))
    while True:
        st = time.time()  # collect start time
        img = pyautogui.screenshot()
        frame = np.array(img)
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        out.write(frame)
        cv2.imshow("screenshot", frame)
        en = time.time()  # collect end time
        # calculate time to wait before next frame:
        delay = max(0, (1 / FRAME_RATE - (en - st)) * 1000)  
        # if the user clicks q, it exits
        if cv2.waitKey(delay) == ord("q"):
            break
    cv2.destroyAllWindows()
    out.release()
    img = pyautogui.screenshot(region=(0, 0, 300, 400))
    

    Note: If collecting the frames is too slow (requires more than 1 / FRAMERATE seconds), then you may want to reduce the frame rate or the resolution.