I’m trying to create a simple screen recorder with Python. This is the code
JavaScript
x
34
34
1
import cv2
2
import numpy as np
3
import pyautogui
4
import time
5
6
SCREEN_SIZE = (1920, 1080)
7
8
fourcc = cv2.VideoWriter_fourcc(*"MP4V")
9
out = cv2.VideoWriter("output.mp4v", fourcc, 20.0, (SCREEN_SIZE))
10
11
fps = 120
12
prev = 0
13
14
print('================= ScreenRecording Started =================')
15
16
while True:
17
time_elapsed = time.time() - prev
18
19
img = pyautogui.screenshot()
20
21
if time_elapsed > 1.0/fps:
22
prev = time.time()
23
frame = np.array(img)
24
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
25
out.write(frame)
26
27
if cv2.waitKey(100) & 0xFF == ord('q'):
28
break
29
else:
30
break
31
32
cv2.destroyAllWindows()
33
out.release()
34
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:
JavaScript
1
57
57
1
import cv2
2
import numpy as np
3
import pyautogui
4
import time
5
from threading import Thread
6
from pynput.keyboard import Key, Listener
7
8
esc_key_pressed = False # Global variable.
9
10
# Wait for Esc key to be pressed (and released).
11
def wait_for_esc_key():
12
global esc_key_pressed
13
# Collect events until released https://stackoverflow.com/questions/24072790/how-to-detect-key-presses
14
with Listener(on_press=None, on_release=lambda key: (False if key == Key.esc else True)) as listener:
15
listener.join()
16
esc_key_pressed = True
17
18
19
SCREEN_SIZE = (1920, 1080)
20
21
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
22
out = cv2.VideoWriter("output.mp4", fourcc, 20.0, (SCREEN_SIZE))
23
24
fps = 120
25
prev = 0
26
27
print('================= ScreenRecording Started =================')
28
print('Press Esc to end recording')
29
30
# Wait for Esc key in a thread (non-blocking wait).
31
wait_for_esc_key_thread = Thread(target=wait_for_esc_key)
32
wait_for_esc_key_thread.start()
33
34
#while True:
35
while (not esc_key_pressed):
36
time_elapsed = time.time() - prev
37
38
img = pyautogui.screenshot()
39
40
if time_elapsed > 1.0/fps:
41
prev = time.time()
42
frame = np.array(img)
43
44
if (frame.shape[0] != SCREEN_SIZE[1]) or (frame.shape[1] != SCREEN_SIZE[0]):
45
frame = cv2.resize(frame, SCREEN_SIZE) # Resize frame if size is not SCREEN_SIZE
46
47
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
48
out.write(frame)
49
50
#if cv2.waitKey(100) & 0xFF == ord('q'):
51
# break
52
time.sleep(0.001)
53
54
55
#cv2.destroyAllWindows()
56
out.release()
57