Reputation: 4039
I'm developing a screen capture tool, this tools aims to help software developers understand how users ended up crashing the application. The idea is to start screen capture once the mouse starts moving and stop it after 5 minutes the mouse didn't move. screen capture works fine through subprocess with ffmpeg, the only remaining problem (except for the application crashes) is to start and stop the screen capture. How can I do this? ideally it would work with condition variable but even a loop which tests if the mouse moved in the last second would do. Is there any chance python supports something like OnMouseMove()
?
Upvotes: 2
Views: 3165
Reputation: 4039
After considering my alternatives I think this the right way to handle my problem, please note I've updated the code to support remote desktop disconnect by checking if the GetCursorPos()
throws an exception, also please note that when closing the remote desktop ffmpeg
outputs
[dshow @ ] real-time buffer full! frame dropped!
But the output file looks fine to me. This script was tested on Windows server 2012
# http://ffmpeg.zeranoe.com/builds/
# http://www.videohelp.com/tools/UScreenCapture
# http://sourceforge.net/projects/pywin32/files/pywin32/
import time, win32api, threading, subprocess, datetime, string, winerror
StopRecordingTimeout = 10
def captureFunction():
pos = None
proc = None
counter = 0
while True:
time.sleep(1)
exceptFlag = False
try:
newPos = win32api.GetCursorPos()
if pos == None:
pos = newPos
except Exception as e:
if e[0] == winerror.ERROR_ACCESS_DENIED:
exceptFlag = True
if newPos != pos and proc != None:
# mouse moved and we are recording already so just make sure the time out counter is zero
counter = 0
elif newPos != pos and proc == None:
# mouse moved and recording didn't start already
fileName = filter(lambda x : x in string.digits, str(datetime.datetime.now()))
fileName = 'output' + fileName + '.flv'
print 'start recording to ' + fileName
proc = subprocess.Popen('ffmpeg -f dshow -i video=UScreenCapture ' + fileName)
elif proc != None and (newPos == pos or exceptFlag):
# mouse didn't moved and recording already started
if counter < StopRecordingTimeout and not exceptFlag:
counter = counter + 1
print 'stop recording in ' + str(StopRecordingTimeout - counter) + ' seconds'
elif exceptFlag or counter >= StopRecordingTimeout:
print 'stop recording'
proc.terminate()
proc = None
counter = 0
pos = newPos
print 'start'
captureThread = threading.Thread(target = captureFunction)
captureThread.start()
captureThread.join()
print 'end'
Upvotes: 2
Reputation:
A loop + pywin32, like this:
import win32api
from time import sleep
count = 0
savedpos = win32api.GetCursorPos()
while(True):
if count>20*5: # break after 5sec
break
curpos = win32api.GetCursorPos()
if savedpos != curpos:
savedpos = curpos
print "moved to " + str(savedpos)
sleep(0.05)
count +=1
Upvotes: 4
Reputation: 28405
wxPython gives you access to a whole set of OnMouse events that you can bind to.
Upvotes: 3