Reputation: 457
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?
Upvotes: 1
Views: 162
Reputation: 32134
There are several implementation issues:
"output.mp4v"
is not a valid mp4
file extension in the current context."output.mp4"
"MP4V"
is case sensitive and suppposed to be "mp4v"
.else:
, break
at the end of the loop may break the loop after one frame.cv2.waitKey
is not working without using cv2.imshow
(without an open windows).q
is pressed.out.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()
Upvotes: 1