Desktop Screen Recording and Monitoring

Add any particular hints or tricks you have found to help with your ZoneMinder experience.
Post Reply
User avatar
snake
Posts: 337
Joined: Sat May 21, 2016 2:20 am

Desktop Screen Recording and Monitoring

Post by snake »

Zoneminder can record the desktop of a user's computer. All that is required is to serve images or video of the desktop on the LAN. It's doesn't have to be HTTP and MJPEG/RTSP. It can be SMB mapped to the ZM server, and then read as File type in ZM. I started with Windows computers, as most small businesses use this OS. If you have GNULinux desktops to record, it's likely easier.

Axis has a guide here: https://www.axis.com/files/tech_notes/D ... apture.pdf which seems to cover everything with VLC and MJPEG... However that guide does NOT work for Windows 10. I tested it in server 2008 and 10. It works in 2008 no problem, but in 10 it opens a video window on the desktop. This is not acceptable.

I have a solution here: https://steakwiki.com/index.php/Windows ... Monitoring
I'll copy the relevant parts to the next post. This solution is not perfect, and I'm hoping someone else will have ideas. It will work for taking a screenshot of a Win10 desktop every couple of seconds using built in tools. The load is not great, but if you span the screenshots out over time it's less noticable.
User avatar
snake
Posts: 337
Joined: Sat May 21, 2016 2:20 am

Re: Desktop Screen Recording and Monitoring

Post by snake »

Use this powershell script

Code: Select all

[cmdletbinding()]            
param(            
  [string]$Width,            
  [string]$Height,            
  [String]$FileName = "Screenshot"  ,
  [string]$path2 = "c:\LOCATIONTOSAVE\"          

)            
#Function to take screenshot. This function takes the width and height of the screen that # #has            
#to be captured            

function Take-Screenshot{            
[cmdletbinding()]            
param(            
 [Drawing.Rectangle]$bounds,             
 [string]$path            
)             
   $bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height            
   $graphics = [Drawing.Graphics]::FromImage($bmp)            
   $graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)            
   $bmp.Save($path)            
   $graphics.Dispose()            
   $bmp.Dispose()            
}            

#Function to get the primary monitor resolution.            
#This code is sourced from             
# https://techibee.com/powershell/powershell-script-to-get-desktop-screen-resolution/1615            

function Get-ScreenResolution {            
 $Screens = [system.windows.forms.screen]::AllScreens                        
 foreach ($Screen in $Screens) {            
  $DeviceName = $Screen.DeviceName            
  $Width  = $Screen.Bounds.Width            
  $Height  = $Screen.Bounds.Height            
  $IsPrimary = $Screen.Primary                        
  $OutputObj = New-Object -TypeName PSobject            
  $OutputObj | Add-Member -MemberType NoteProperty -Name DeviceName -Value $DeviceName            
  $OutputObj | Add-Member -MemberType NoteProperty -Name Width -Value $Width            
  $OutputObj | Add-Member -MemberType NoteProperty -Name Height -Value $Height            
  $OutputObj | Add-Member -MemberType NoteProperty -Name IsPrimaryMonitor -Value $IsPrimary            
  $OutputObj                        
 }            
}            

#Main script begins            

#By default captured screenshot will be saved in %temp% folder            
#You can override it here if you want  
#orig          
#$Filepath = join-path $env:temp $FileName 
#edit
$Filepath = join-path $path2 $FileName           

[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")            
[void] [Reflection.Assembly]::LoadWithPartialName("System.Drawing")            

if(!($width -and $height)) {            

 $screen = Get-ScreenResolution | ? {$_.IsPrimaryMonitor -eq $true}            
 $Width = $screen.Width            
 $Height = $screen.height            
}            

$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, $Screen.Width, $Screen.Height)            

Take-Screenshot -Bounds $bounds -Path "$Filepath.png"            
#Now you have the screenshot
Call it every 1 minute in task scheduler with this .vbs script (must use vbs to be quiet, and not open a cmd window)

Code: Select all

Dim index, count
count = 3
'Loop every 15 seconds because we can't do more than every minute with task scheduler
For index = 1 To count
 command = "powershell.exe -nologo -command C:\SCRIPTHERE"
 set shell = CreateObject("WScript.Shell")
 shell.Run command,0
'this is in milliseconds
 WScript.Sleep 15000
Next
In order for this type of script to take a screenshot, it must run as the user "only when he is logged in" per the task scheduler settings. Do not run this in task scheduler as SYSTEM, or whether or not the user is logged in. Note that this script is best suited for single user workstations. It may work if you make multiple tasks, though if you have multiple users, not sure.

Grab Images via SMB
At this point, you have an updating file which is a screenshot. Map the SMB drive to the recording server to grab the file without installing anything. Another option is to use apache w/authentication (or without).

Later I'll document the last steps of this, as it pertains to ZM: Mapping the SMB drive, and setting file type source for a monitor.

References:
https://techibee.com/powershell/powersh ... sktop/1626
https://superuser.com/questions/293445/ ... 10-seconds
Post Reply