Skip to content

DEBUG:root:gdi32.GetDIBits() failed. after a couple of minutes of recording #268

@lorenzopreda

Description

@lorenzopreda

General information:

  • OS name: Windows
  • OS version: 10
  • OS architecture: 64 bits
  • Resolutions:
    • Monitor 1: 1920x1080
  • Python version: 3.10
  • MSS version: 9.1.0

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions