91 lines
2.1 KiB
Python
91 lines
2.1 KiB
Python
import signal
|
|
import time
|
|
from pathlib import Path
|
|
|
|
import cv2
|
|
import numpy as np
|
|
from mss import mss
|
|
|
|
|
|
OUTPUT_FILE = Path("screen_recording.avi")
|
|
FPS = 20
|
|
MONITOR_NUMBER = 1
|
|
|
|
recording = True
|
|
|
|
|
|
def stop_recording(signum=None, frame=None):
|
|
global recording
|
|
recording = False
|
|
print("\nStopping recording safely...")
|
|
|
|
|
|
signal.signal(signal.SIGINT, stop_recording)
|
|
signal.signal(signal.SIGTERM, stop_recording)
|
|
|
|
|
|
def main():
|
|
global recording
|
|
|
|
with mss() as sct:
|
|
monitor = sct.monitors[MONITOR_NUMBER]
|
|
|
|
width = monitor["width"]
|
|
height = monitor["height"]
|
|
|
|
# Video codecs generally prefer even dimensions.
|
|
width -= width % 2
|
|
height -= height % 2
|
|
|
|
# MJPG inside AVI is more resistant to corruption than MP4.
|
|
fourcc = cv2.VideoWriter_fourcc(*"MJPG")
|
|
|
|
writer = cv2.VideoWriter(
|
|
str(OUTPUT_FILE),
|
|
fourcc,
|
|
FPS,
|
|
(width, height),
|
|
)
|
|
|
|
if not writer.isOpened():
|
|
raise RuntimeError("Could not open VideoWriter")
|
|
|
|
print(f"Recording {width}x{height} at {FPS} FPS")
|
|
print("Press Ctrl+C once to stop safely.")
|
|
|
|
frame_interval = 1.0 / FPS
|
|
next_frame_time = time.perf_counter()
|
|
|
|
try:
|
|
while recording:
|
|
screenshot = sct.grab(
|
|
{
|
|
"left": monitor["left"],
|
|
"top": monitor["top"],
|
|
"width": width,
|
|
"height": height,
|
|
}
|
|
)
|
|
|
|
frame = np.asarray(screenshot)
|
|
frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
|
|
|
|
writer.write(frame)
|
|
|
|
next_frame_time += frame_interval
|
|
sleep_time = next_frame_time - time.perf_counter()
|
|
|
|
if sleep_time > 0:
|
|
time.sleep(sleep_time)
|
|
else:
|
|
next_frame_time = time.perf_counter()
|
|
|
|
finally:
|
|
writer.release()
|
|
cv2.destroyAllWindows()
|
|
|
|
print(f"Recording saved safely: {OUTPUT_FILE.resolve()}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |