I’m trying to create a simple screen recorder with Python. This is the code
import cv2 import numpy as np import pyautogui import time SCREEN_SIZE = (1920, 1080) fourcc = cv2.VideoWriter_fourcc(*"MP4V") out = cv2.VideoWriter("output.mp4v", fourcc, 20.0, (SCREEN_SIZE)) fps = 120 prev = 0 print('================= ScreenRecording Started =================') while True: time_elapsed = time.time() - prev img = pyautogui.screenshot() if time_elapsed > 1.0/fps: prev = time.time() frame = np.array(img) frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) out.write(frame) if cv2.waitKey(100) & 0xFF == ord('q'): break else: break cv2.destroyAllWindows() out.release()
It doesn’t give any error while it’s going, and it creates a .mp4v file correctly, however when I try to watch the video that was supposed to be recorded, it can’t be opened. I tried with VLC and other apps but it’s unsupported everywhere.
Can someone tell me why?
Advertisement
Answer
There are several implementation issues:
- As far
"output.mp4v"
is not a validmp4
file extension in the current context.
Change the file name to"output.mp4"
"MP4V"
is case sensitive and suppposed to be"mp4v"
.- As gerda commented, the frame size may not be 1920×1080.
- The
else:
,break
at the end of the loop may break the loop after one frame. cv2.waitKey
is not working without usingcv2.imshow
(without an open windows).
The loop is not terminated whenq
is pressed.
The code may never reach toout.release()
.
Based on the following post, I tried to create a portable code that waits for Esc key, without root privilege in Linux.
The solution I found (waiting for Esc) seem a bit complicated… You may try other solutions.
Code sample:
import cv2 import numpy as np import pyautogui import time from threading import Thread from pynput.keyboard import Key, Listener esc_key_pressed = False # Global variable. # Wait for Esc key to be pressed (and released). def wait_for_esc_key(): global esc_key_pressed # Collect events until released https://stackoverflow.com/questions/24072790/how-to-detect-key-presses with Listener(on_press=None, on_release=lambda key: (False if key == Key.esc else True)) as listener: listener.join() esc_key_pressed = True SCREEN_SIZE = (1920, 1080) fourcc = cv2.VideoWriter_fourcc(*"mp4v") out = cv2.VideoWriter("output.mp4", fourcc, 20.0, (SCREEN_SIZE)) fps = 120 prev = 0 print('================= ScreenRecording Started =================') print('Press Esc to end recording') # Wait for Esc key in a thread (non-blocking wait). wait_for_esc_key_thread = Thread(target=wait_for_esc_key) wait_for_esc_key_thread.start() #while True: while (not esc_key_pressed): time_elapsed = time.time() - prev img = pyautogui.screenshot() if time_elapsed > 1.0/fps: prev = time.time() frame = np.array(img) if (frame.shape[0] != SCREEN_SIZE[1]) or (frame.shape[1] != SCREEN_SIZE[0]): frame = cv2.resize(frame, SCREEN_SIZE) # Resize frame if size is not SCREEN_SIZE frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) out.write(frame) #if cv2.waitKey(100) & 0xFF == ord('q'): # break time.sleep(0.001) #cv2.destroyAllWindows() out.release()