Jump to content

Frozen pixels on screen detection


ManualIT
 Share

Recommended Posts

Is there anyway that Autoit can detect a video that has been frozen on screen for a certain time?

 

I have a program that records videos from my surveillance cameras, unfortunately after an update, sometimes the recording and live feed freezes on one of the cameras displayed on screen.

The program has to be restarted, so I wrote a script that it restarts the program and then starts recording on each camera, but only if i physically notice that it has been frozen.

So it would be great if all this can be done automatically.

 

 

Edited by ManualIT
Link to comment
Share on other sites

PixelCheckSum would probably work for this. If the checksum is the same for a length of time you could use that as a detection method.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Thanks for the quick reply @BrewManNH

I searched for PixelCheckSum and found this example:

#include <MsgBoxConstants.au3>

; Wait until something changes in the region 0,0 to 50,50

; Get initial checksum
Local $iCheckSum = PixelChecksum(0, 0, 50, 50)

; Wait for the region to change, the region is checked every 100ms to reduce CPU load
While $iCheckSum = PixelChecksum(0, 0, 50, 50)
    Sleep(100)
WEnd

MsgBox($MB_SYSTEMMODAL, "", "Something in the region has changed!")

I understand that this example only detects for movements that happen on the screen from no movement.

I have never used this function before, also i have very basic knowledge of autoit, so i would really appreciate it if you or anyone else can help on this.

Edited by ManualIT
Link to comment
Share on other sites

  • Moderators

@ManualIT Are you running your cameras off of a Windows Server? I did work for a customer recently that had a similar problem with their security cameras; I simply wrote a script that looked at the folder that the feed was being saved off to on the SAN. If the folder did not grow in size over the course of 60 seconds (I'm sure you know how quickly these things eat up storage) it was safe to assume something was wrong and bounce it. Much easier than trying to go after pixels.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

1 hour ago, JLogan3o13 said:

@ManualIT Are you running your cameras off of a Windows Server? I did work for a customer recently that had a similar problem with their security cameras; I simply wrote a script that looked at the folder that the feed was being saved off to on the SAN. If the folder did not grow in size over the course of 60 seconds (I'm sure you know how quickly these things eat up storage) it was safe to assume something was wrong and bounce it. Much easier than trying to go after pixels.

@JLogan3o13 Yes indeed i am, that sounds like a pretty good idea, i would really appreciate it if you can share the script.

 

The paths are like this (2 cameras):

\\SERVER\Cameras\FrontDoor_03983\20181001\Video
\\SERVER\Cameras\BackDoor_65432\20181001\Video

 

It saves a video every 15 minutes and it creates a folder on each different day, like if it's the second day of October, new path would be:

\\SERVER\Cameras\FrontDoor_03983\20181002\Video
\\SERVER\Cameras\BackDoor_65432\20181002\Video

and so on..

Edited by ManualIT
Link to comment
Share on other sites

  • Moderators

I will dig and see if I have a copy of the script; most times when I leave a contract they keep the scripts - only recently have I been putting in a clause about me owning all of my IP.  But the concept is pretty simple (pseudo):

$folder = "\\<server1>\DeptData\Technical Services\System Engineers\Scripts\JLoTest"
ConsoleWrite(Round((DirGetSize($folder) /1024), 2) & "KB" & @CRLF)

Take a look at DirgetSize in the help file. You can run it in a loop (converting bytes to KB/MB/GB/TB as desired) and, if it doesn't grow for x amount of time, take other action.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

14 minutes ago, JLogan3o13 said:

I will dig and see if I have a copy of the script; most times when I leave a contract they keep the scripts - only recently have I been putting in a clause about me owning all of my IP.  But the concept is pretty simple (pseudo):

$folder = "\\<server1>\DeptData\Technical Services\System Engineers\Scripts\JLoTest"
ConsoleWrite(Round((DirGetSize($folder) /1024), 2) & "KB" & @CRLF)

Take a look at DirgetSize in the help file. You can run it in a loop (converting bytes to KB/MB/GB/TB as desired) and, if it doesn't grow for x amount of time, take other action.

I really appreciate it, but i just realized it might not work well with my situation, because i noticed that the file size of the video doesn't increase while it is recording, it only saves a video every 15 minutes, it can't be set any lower than that.

I know that the script can be written to check the folder size every 15 minutes, but i'd rather have it checked every 1 or 2 minutes at the most.

 

Link to comment
Share on other sites

  • Moderators

That makes sense, I have seen a couple of systems that fill up in memory to a certain point and then write the cache out to disk. Do you see that cycle of memory use on the server (build up, build up, release, repeat)? If so, that may be a way to do it as well.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

43 minutes ago, JLogan3o13 said:

That makes sense, I have seen a couple of systems that fill up in memory to a certain point and then write the cache out to disk. Do you see that cycle of memory use on the server (build up, build up, release, repeat)? If so, that may be a way to do it as well.

Just checked, unfortunately it doesn't.

But i just realized another thing mate, i tried running your code above on a loop, it does not show any increase of file size, however, when i have the folder of the video recording opened in explorer, the autoit console shows the file size increasing every second.

EDIT: And it has to be focused on the video's thumbnail that is being recorded. :blink:

EDIT2: or if each time i open the recorded videos folder's properties, the console will show the file size increase only once
So perhaps write a script that auto opens the folder's properties every minute?

Edited by ManualIT
Link to comment
Share on other sites

  • Moderators

Hmmm...odd. I just did a quick test with increasing the size of a file in a directory (5MB per second) and am seeing the change in the script immediately.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

3 minutes ago, JLogan3o13 said:

Hmmm...odd. I just did a quick test with increasing the size of a file in a directory (5MB per second) and am seeing the change in the script immediately.

Yeah it is odd, but does the file size show as 0 bytes in explorer though?
Just when you highlight it

 

Mine shows 0 bytes, but when i check it's properties, it shows the actual file size, and will increase every time i check it.

Link to comment
Share on other sites

I still need help on this, i think the only solution for my situation is using the function PixelCheckSum to detect the camera when it freezes.

So here's my idea, how about that the function PixelCheckSum keeps checking for on screen movements on a loop, if there's a movement (camera is live on screen) the script keeps looping, but when the camera freezes, which means the script doesn't detect a movement from a point on screen, so then it runs my other script that restarts the camera program and starts recording again.

You guys think this can be done with the PixelCheckSum function?

Link to comment
Share on other sites

  • 2 years later...
On 10/1/2018 at 7:26 AM, BrewManNH said:

PixelCheckSum would probably work for this. If the checksum is the same for a length of time you could use that as a detection method.

It works fine if the image being monitored is on the active window.

Is there a way to make PixelCheckSum work on a window behind another window? Somehow it fails even if the hwnd parameter is used when the region of pixels to sum is covered by another window.

Link to comment
Share on other sites

No, unless you design your own PixelCheckSum using _WinAPI_PrintWindow.  If you put something together and it is working, please, post the code you have created.

Link to comment
Share on other sites

Made one.

#include <GDIPlus.au3>
#include <Crypt.au3>

Example()

Func Example()
  If Not WinExists("[CLASS:Notepad]") Then
    Run("Notepad")
    WinWait("[CLASS:Notepad]")
  EndIf
  Local $hWnd = WinGetHandle("[CLASS:Notepad]")
  Local $hTimer = TimerInit()
  Local $dPCS = _PixelCheckSum($hWnd, 10, 10, 200, 200)
  ConsoleWrite(TimerDiff($hTimer) & "/" & $dPCS & @CRLF)
EndFunc   ;==>Example

Func _PixelCheckSum($hWnd, $iLeft, $iTop, $iRight, $iBottom, $bStart = True)
  Local $hDC_Capture = _WinAPI_GetDC($hWnd)
  Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
  Local $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $iRight, $iBottom)
  Local $hObject = _WinAPI_SelectObject($hMemDC, $hHBitmap)
  _WinAPI_PrintWindow($hWnd, $hMemDC)
  If $bStart Then _GDIPlus_Startup()
  Local $hBMP = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
  Local $iWidth = $iRight - $iLeft, $iHeight = $iBottom - $iTop
  Local $tStruct = _GDIPlus_BitmapLockBits($hBMP, $iLeft, $iTop, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32ARGB)

  Local $tPixel = DllStructCreate("byte arr[" & $iWidth * $iHeight * 4 & "]", $tStruct.Scan0)
  Local $dRet = _Crypt_HashData($tPixel.arr, $CALG_MD5)

  _GDIPlus_BitmapUnlockBits($hBMP, $tStruct)
  _GDIPlus_BitmapDispose($hBMP)
  If $bStart Then _GDIPlus_Shutdown()
  _WinAPI_SelectObject($hMemDC, $hObject)
  _WinAPI_DeleteDC($hMemDC)
  _WinAPI_ReleaseDC($hWnd, $hDC_Capture)
  _WinAPI_DeleteObject($hHBitmap)
  Return $dRet
EndFunc   ;==>_PixelCheckSum

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...