0

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))
 
Tiger-222
  • 6,677
  • 3
  • 47
  • 60

1 Answers1

0

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.

jmerizia
  • 51
  • 3
  • but i noticed it has increased the play back speed of the file – code by Abhishek Bharti Jul 27 '20 at 11:49
  • @codebyAbhishekBharti You should take a look at the `waitKey` function, which takes a minimum wait time in milliseconds (https://docs.opencv.org/3.4.10/d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7) -- If you change the VideoWriter fps, you only modify the playback speed, not the recording speed. So, you should play with the `waitKey` parameter so that you read at 30 fps as well. I'll update the answer accordingly. – jmerizia Jul 28 '20 at 02:11
  • bro the screen recorded by this code is not playing the video generated – code by Abhishek Bharti Jul 28 '20 at 15:25
  • It works just fine when I set my screen resolution properly. If `SCREEN_SIZE` is not set to your computer's resolution, you'll have to resize the frame before writing it to the VideoWriter. i.e., add `frame = cv2.resize(frame, SCREEN_SIZE)` before `out.write(frame)`. Otherwise, another problem could be that you don't have the necessary codecs installed for playing XVID videos, which is out of the scope of this question. Look into `ffmpeg`. – jmerizia Jul 29 '20 at 22:55