Win10 用户锁屏后开始监控

需求

离开电脑,锁屏后,开启摄像头,记录视频
防止有人动电脑

未实现的功能:上传视频到云

效果

为了节省存储空间,画面相当糊

源码

import sys
import time

import cv2

from PyQt5.QtCore import Qt, QThread,pyqtSignal
from PyQt5.QtWidgets import *
import win32api
import win32con
import win32gui
import win32ts

import os
WM_WTSSESSION_CHANGE = 0x2B1
WTS_SESSION_LOCK = 0x7
WTS_SESSION_UNLOCK = 0x8 


class WndProcHookMixin:
    def __init__(self):
        self.msgDict = {}

    def hookWndProc(self):
        self.oldWndProc = win32gui.SetWindowLong(self.winId(), win32con.GWL_WNDPROC, self.localWndProc)

    def unhookWndProc(self):
        win32api.SetWindowLong(self.winId(), win32con.GWL_WNDPROC, self.oldWndProc)

    def addMsgHandler(self, messageNumber, handler):
        self.msgDict[messageNumber] = handler

    def localWndProc(self, hWnd, msg, wParam, lParam):
        if msg in self.msgDict:
            if self.msgDict[msg](wParam, lParam) == False:
                return

        if msg == win32con.WM_DESTROY: 
            self.unhookWndProc()

        return win32gui.CallWindowProc(self.oldWndProc, hWnd, msg, wParam, lParam)


class Window(QWidget, WndProcHookMixin):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)    
        #self.show() 不显示窗口

        self.my_thread = MyThread()#实例化线程对象
        self.my_thread.start()
        

        win32ts.WTSRegisterSessionNotification(self.winId(), win32ts.NOTIFY_FOR_ALL_SESSIONS)
        self.addMsgHandler(WM_WTSSESSION_CHANGE, self.on_session)
        self.hookWndProc()

    def on_session(self, wParam, lParam):
         
      

        event, session_id = wParam, lParam
        if event == WTS_SESSION_LOCK:
            self.my_thread.record=1 #用户锁屏了,告诉另一个线程开始摄像

        if event == WTS_SESSION_UNLOCK:
            self.my_thread.record=0 #用户解锁了,告诉另一个线程结束摄像

            

class MyThread(QThread):#线程类
    def __init__(self):
        super(MyThread, self).__init__()
        self.record=0
    def run(self): #线程执行函数        
        formerOut=False       #是否已经开始拍摄的标志
        path='D:/Monitor/'    #存储视频的目录
        if not os.path.exists(path):
            os.makedirs(path)
        while True:        
            if self.record==1 : 
                if formerOut==False:
                    cap = cv2.VideoCapture(0)
                    fourcc = cv2.VideoWriter_fourcc(*'XVID')
                    fps = cap.get(cv2.CAP_PROP_FPS)
                    size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), \
                            int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

                    #为了节省存储空间,将画质降低
                    resize=(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)/4), \
                            int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)/4))
                    beginTime=time.strftime("%m_%d_%H_%M_%S", time.localtime())
                    savePath=path+beginTime+'.avi'  #视频存储路径
                    print(savePath)
                    out = cv2.VideoWriter(savePath, fourcc, fps, resize)
                    formerOut=out
                ret, frame = cap.read()
                frame = cv2.flip(frame, 1)#水平镜像
                cv2.putText(frame,time.strftime("%m-%d %H:%M:%S", time.localtime()),(0,30),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),2)
                frame=cv2.resize(frame, resize, interpolation=cv2.INTER_AREA)
                # show a frame
                #cv2.imshow("capture", frame)
                out.write(frame)
            else :
                if not formerOut==False:
                    out.release()
                    endTime=time.strftime("_to_%m_%d_%H_%M_%S", time.localtime())
                    newPath=path+beginTime+'_'+endTime+'.avi'
                    try:
                        os.rename(savePath,newPath) #重命名,加上视频结束时间
                    except:
                        pass 
                    cap.release()
                    cv2.destroyAllWindows() 
                    formerOut=False
if __name__ == '__main__': 
    app = QApplication(sys.argv)   
    win = Window()
    sys.exit(app.exec_())


posted @ 2019-05-09 15:19  灰太狼的喜羊羊  阅读(1620)  评论(0编辑  收藏  举报