General information:
Description of the warning/error
I'm trying to generate a perpetual screen recorder that splits videos every n minutes. I got the error DEBUG:root:gdi32.GetDIBits() failed. after a couple of minutes that the script is running, like the grab command cannot take screenshots anymore.
Here is my code:
import configparser
import ctypes
import time
import cv2 as cv
import mss
import numpy as np
import win32gui
from PIL import Image
import customtkinter as tk
import os
import logging
import sys
import os.path
from threading import Thread
def get_path(filename):
if hasattr(sys, "_MEIPASS"):
return os.path.join(sys._MEIPASS, filename)
else:
return filename
def stoprec():
global recording
recording = False
def get_cursor():
cursor_img = Image.open(get_path("cursor.png"))
pixdata = cursor_img.load()
width, height = cursor_img.size
for y in range(height):
for x in range(width):
if pixdata[x, y] == (0, 0, 0, 255):
pixdata[x, y] = (0, 0, 0, 0)
pos_win = (0, 0)
try:
pos_win = win32gui.GetCursorPos()
except Exception as ex:
logging.debug(ex)
print(ex)
ratio = ctypes.windll.shcore.GetScaleFactorForDevice(0) / 100
cursor_pos = (round(pos_win[0] * ratio), round(pos_win[1] * ratio))
return cursor_img, cursor_pos
def screenshot():
global recording, rgb_frame
monitor = {'top': 0, 'left': 0, 'width': 1920, 'height': 1080}
while recording:
time.sleep(0.05)
with mss.mss() as sct:
try:
screen = sct.grab(monitor)
except Exception as ex:
logging.debug(ex)
print(ex)
else:
img = Image.frombytes("RGB", screen.size, screen.bgra, "raw", "BGRX")
cursor, pos = get_cursor()
img.paste(cursor, pos, cursor)
frame = np.array(img)
rgb_frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
sct.close()
def record():
global recording, rgb_frame, writer
start_acq = time.time()
start_split = time.time()
while recording:
if time.time() - start_acq >= spf:
start_acq = start_acq + spf
writer.write(rgb_frame)
if time.time() - start_split >= split:
start_acq = time.time()
start_split = time.time()
writer.release()
cv.destroyAllWindows()
print('Video Split ' + str(time.strftime('%d/%m/%Y - %H:%M')))
writer = cv.VideoWriter(
str(save_path) + '\\' + str(label) + ' ' + str(time.strftime('%d-%m-%Y_%H-%M')) +
'.' + str(ext), four_char_code, fps, screensize)
print('Video Ended ' + str(time.strftime('%d/%m/%Y - %H:%M')))
writer.release()
cv.destroyAllWindows()
if __name__ == "__main__":
logging.basicConfig(filename="log.txt", level=logging.DEBUG)
img_init = Image.open(get_path("cursor.png"))
frame_init = np.asarray(img_init)
rgb_frame = cv.cvtColor(frame_init, cv.COLOR_BGR2RGB)
recording = True
config = configparser.ConfigParser()
config.read_file(open('config.txt'))
save_path = config.get('data', 'save_path')
label = config.get('data', 'label')
fps = float(config.get('data', 'fps'))
codec = config.get('data', 'codec')
ext = config.get('data', 'extension')
split = float(config.get('data', 'split'))
spf = 1 / fps
screensize = (1920, 1080)
four_char_code = cv.VideoWriter_fourcc(*str(codec))
writer = cv.VideoWriter(str(save_path) + '\\' + str(label) + ' ' + str(time.strftime('%d-%m-%Y_%H-%M')) + '.' +
str(ext), four_char_code, fps, screensize)
tk.set_appearance_mode("System") # Modes: system (default), light, dark
tk.set_default_color_theme("blue") # Themes: blue (default), dark-blue, green
window = tk.CTk()
window.title('ScreenVideo')
window.geometry('350x300')
stop = tk.CTkButton(master=window, text="Stop Recording", width=150, height=50, command=stoprec)
stop.place(relx=0.5, rely=0.5, anchor='center')
window.protocol('WM_DELETE_WINDOW', stoprec)
t1 = Thread(target=screenshot)
t2 = Thread(target=record)
t1.start()
t2.start()
while recording:
window.update()
t2.join()
t1.join()
window.destroy()`
### Full message
DEBUG:root:gdi32.GetDIBits() failed.
Thank you in advance
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too