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_())