24 11 2021
class VideoRecord:
    def __init__(self, video_name, video_dir, logger=None):
        self.flag = False
        self.video_name = video_name
        self.date_str = datetime.datetime.now().strftime('%Y-%m-%d')
        self.datetime_str = datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S')
        self.video_dir = video_dir
        self.video_path = \
            r'{video_dir}\{date_str}\{video_name}\{datetime_str}.avi'.format(
                video_dir=self.video_dir,
                date_str=self.date_str,
                video_name=self.video_name,
                datetime_str=self.datetime_str,
            )
        self.logger = logger
        self.start_time = None
        self.final_time = None

    def video_record(self):  # 录入视频
        screen = ImageGrab.grab()  # 获取当前屏幕
        width, high = screen.size  # 获取当前屏幕的大小
        fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')  # MPEG-4编码,文件后缀可为.avi .asf .mov等
        createPath(self.video_dir)
        createPath(os.path.dirname(self.video_path))
        video = cv2.VideoWriter(self.video_path, fourcc, 15, (width, high))  # (文件名,编码器,帧率,视频宽高)
        self.logger.info('录制开始')
        self.start_time = time.time()
        while True:
            if self.flag:
                self.logger.info('录制结束')
                self.final_time = time.time()
                video.release()  # 释放
                time.sleep(1)
                self.video_info()
                break
            im = ImageGrab.grab()  # 图片为RGB模式
            imm = cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR)  # 转为opencv的BGR模式
            video.write(imm)  # 写入
            # time.sleep(5) # 等待5秒再次循环

    def on_press(self, key):  # 监听按键
        if key == keyboard.Key.home:
            self.logger.info('捕获到用户输入录屏终止按键 录屏终止')
            self.flag = True  # 改变
            return False  # 返回False,键盘监听结束!

    def video_info(self):  # 视频信息
        self.logger.info('打印录屏信息')
        video = cv2.VideoCapture(self.video_path)  # 记得文件名加格式不要错!
        fps = video.get(cv2.CAP_PROP_FPS)
        frame_sum = video.get(cv2.CAP_PROP_FRAME_COUNT)
        size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
        self.logger.info('帧率:{:.1f}'.format(fps))
        self.logger.info('帧数:{:.1f}'.format(frame_sum))
        self.logger.info('分辨率:{}'.format(size))
        self.logger.info('视频时间:{:.3f}秒'.format(int(frame_sum) / fps if frame_sum else 0))
        self.logger.info('录制时间:{:.3f}秒'.format((self.final_time - self.start_time)))
        if frame_sum == 0:
            self.logger.info('推荐帧率:0.00')
        else:
            self.logger.info(
                '推荐帧率:{:.2f}'.format((fps * ((int(frame_sum) / fps) / (self.final_time - self.start_time)))))

    def keyboard_join(self):
        with keyboard.Listener(on_press=self.on_press) as listener:
            if self.flag:
                listener.join()
            else:
                listener.join()


def video_record_decorator(video_name=None):  # video_name=None, logger=None
    from PythonCode import Setting
    from functools import wraps
    def wrapper(func):
        def inner(*args, **kwargs):
            video_record = VideoRecord(video_name, Setting.VIDEO_RECORD_DIR, args[0].logger)
            record_th = threading.Thread(target=video_record.video_record)
            record_th.setDaemon(True)
            record_th.start()
            ret = func(*args, **kwargs)
            time.sleep(5)
            video_record.flag = True
            record_th.join()
            return ret

        return inner

    return wrapper

 

延伸阅读
  1. Python 根据设置储存限制定期删除录屏等大文件
    < /body> < /html>