How to use a video file as a Source

From ZoneMinder Wiki
Revision as of 23:01, 30 November 2021 by Kitkat (talk | contribs) (Created page with "There was [ a question on the forums] a while ago asking whether it was possible to test zones against stored events, w...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

There was a question on the forums a while ago asking whether it was possible to test zones against stored events, which interested me, and I've cobbled together a fairly reliable method of doing it with PHP and FFMpeg.


Create a file named replay-test.php in your server's web root (not the ZM root), paste this into it, fixing the source video and ffmpeg paths to suit your installation, and save it. On CentOS the web root is /var/www/html so you'd do something like, sudo nano /var/www/html/replay-test.php


// Change this to point to your source video file
$infile = "/home/zoneminder/events/1/2021-11-30/173016/173016-video.mp4";

// Whether to loop the video
// Use -1 for infinite,
// 0 for single-shot,
// 1 for 1 loop (two 'plays'), etc.
// Anything other than -1 will throw errors in the ZM log as
// it fails to capture and restarts the zmc process
$loopcount = -1;

// Path to ffpmeg - try 'which ffmpeg' at the CLI to find yours
$ffmpeg = "/usr/bin/ffmpeg";

// No variables defined below here

// Got a filename as a parameter?
if( !empty($_GET['f']) ) {
		$infile = $_GET['f'];

// Can we read the file?
if( !is_readable($infile) ) {
		header("HTTP/1.1 500 Internal Server Error (can't read $f)");

// Don't allow max_execution_time to kill us

// Tell the client what we're sending
header( "Content-Type: video/mp4" );

// Send it...
passthru( $ffmpeg." -stream_loop ".$loopcount." -re -i '".$infile."' -vcodec copy -an -vsync 0 -f mp4 -movflags frag_keyframe+empty_moov - 2>/dev/null");



You can test the stream by opening it in a browser or media player such as MPC-HC or VLC:

Setting up the monitor in ZM

Set up a new monitor in ZM with a Source Type of FFMpeg, a Source Path of http://localhost/replay-test.php, and TCP as the Method.

That's it - You should be good to go and ZM should start capturing :)


The video is passed straight through rather than being transcoded so playback quality will be exactly as it was recorded in the file.

The best results will probably be obtained with videos that used Camera Passthrough as the writer because then ZM will see the same thing as it did the first time - other methods will be lossy and although the differences may be imperceptible to us, machines will spot them. If you must use an encoder then try to use a low CRF, such as 19 or even 17 to avoid too much degradation.

You can change the file to be replayed without editing the PHP by adding a ?f=/path/to/file.mp4 query string to the Source Path in the Monitor configuration (e.g. http://localhost/replay-test.php?f=/home/zoneminder/events/1/2021-11-30/173016/173016-video.mp4).

If you change the source video path in the PHP or if you overwrite the video file then you'll have stop and restart the monitor in ZM.

I find that the loop tends to stick at the end before restarting, but that could very well be the way my video is encoded and it may not happen to you.

I suggest using sources with fairly long (a few frames or so) intros and outros without much happening in them to avoid spurious detection at the wraparound where the scene might change significantly (in ZM terms).

Comments, criticisms, and questions are welcome in the forum thread

I think that's all for now - Good luck!