<?php

// ******************************************************************************
// zm_arc2video.php v1.1
// 2007, Rick Hodger <rick@fuzzi.org.uk>
//
// This script is intended to be used to archive events from ZoneMinder, and iss
// designed to run from the command line. It does the following:
//
//     1. Set all events with the archive flag.
//     2. Create video clips of all archived events in a specified path.
//     3. Optionally delete all video clips from ZoneMinder.
//     4. If not deleted, set 'zm_arc2video' in the notes field, so we don't 
//        create a video for that event on the next run.
//     5. Optionally turn the created videos into a ISO CD image, and delete the
//        videos.
//
// Videos: This script only knows how to use ffmpeg. Videos are created using the
//         mpeg4 codec, with a high bitrate, and 5 FPS. Feel free to change this
//         as you see fit.
// 
// Updates: In the event that a new version is released, this version will cease
//          to operate in case a critical flaw is found, or database structure
//          in ZM changes.
//
// Parameters: --skip-update :: Skip the check for new versions.
//
// ******************************************************************************

// Where you want to the finished video clips to be stored
$build_dir='/backup/events';

// Location of the ZoneMinder configuration file.
$zm_config='/etc/zm.conf';

// Delete archived events when done?
$del_events=true;

// Convert the videos into an ISO, set this to the name of the image you wish 
// to create, eg. image.iso
$make_iso=false;

// ****************** EDIT BELOW THIS LINE AT YOUR OWN RISK**********************

$version 1.1;

// spit out the greeting
echo "\nzm_arc2video.php v$version\n2007, Rick Hodger <rick@fuzzi.org.uk>, http://www.potato-people.com/\n\n";

// check for new version
if ($argc>&& $argv[1]==='--skip-update') {
} else {
    
$update=trim(implode('',@file('http://www.potato-people.com/versions/zm_arc2video.txt')));
    if (
$update $version) {
        die(
"New version available! Please update. (".number_format($update,1)." > ".number_format($version,1).")\n");
    }
}

// get dbase vars from the config file
if ($fp=@fopen($zm_config,'r')) {
    while(!
feof($fp)) {
        
$line=trim(fgets($fp,1024));
        if (!empty(
$line) && substr($line,0,1)!=='#') {
            list(
$key,$var)=explode('=',$line);
            switch(
$key) {
                case 
'ZM_PATH_WEB'$webpath=$var; break;
                case 
'ZM_DB_HOST'$sql_host=$var; break;
                case 
'ZM_DB_NAME'$sql_dbase=$var; break;
                case 
'ZM_DB_USER'$sql_user=$var; break;
                case 
'ZM_DB_PASS'$sql_pass=$var; break;
            }
        }
    }
} else {
    die(
"Could not read zm.conf!\n");
}

// connect to the dbase
if ($conn=mysql_connect($sql_host,$sql_user,$sql_pass)) {
    if (!
mysql_select_db($sql_dbase)) {
        die(
"Could not select database!\n");
    }
} else {
    die(
"Could not connect to MySQL server!\n");
}

// find events dir
$rs=mysql_query("SELECT Value FROM Config WHERE Name='ZM_DIR_EVENTS';");
if (
mysql_num_rows($rs) > 0) {
    list(
$x)=mysql_fetch_array($rs);
    
$zm_events="$webpath/$x";
} else {
    die(
"Could not find events directory!\n");
}

// find ffmpeg path
$rs=mysql_query("SELECT Value FROM Config WHERE Name='ZM_PATH_FFMPEG';");
if (
mysql_num_rows($rs) > 0) {
    list(
$ffmpeg)=mysql_fetch_array($rs);
    if (!
file_exists($ffmpeg)) {
        die(
"ffmpeg is not at the configured location! $ffmpeg\n");
    }
} else {
    die(
"Could not find ffmpeg!\n");
}

// get camera names
$cams=array();
$rs=mysql_query("SELECT Id,Name FROM Monitors ORDER by Id;");
if (
mysql_num_rows($rs) > 0) {
    while(list(
$id,$name)=mysql_fetch_array($rs)) {
        
$cams[$id]=$name;
        @
mkdir("$build_dir/$name");
    }
    echo 
"Found ".sizeof($cams)." camera(s)\n";
} else {
    die(
"No cameras found!\n");
}

// Move all events to Archived
mysql_query("UPDATE Events SET Archived=1;");
// Now select all archived events
$rs=mysql_query("SELECT MonitorId,Id,Name,StartTime FROM Events WHERE Archived=1 AND Notes!='zm_arc2video' ORDER BY MonitorID,Id;");
if (
mysql_num_rows($rs) > 0) {
    echo 
"Found ".mysql_num_rows($rs)." event(s)\n";
    
$i=1;
    echo 
"Processing: ";
    while(list(
$monitor,$id,$name,$startTime) = mysql_fetch_array($rs)) {
        echo 
str_pad($i,4,' ',STR_PAD_LEFT);
        
$startTime=str_replace(":","-",$startTime);
        
exec("$ffmpeg -r 5 -b 1800 -i \"$zm_events/$monitor/$id/%03d-capture.jpg\" \"$build_dir/".$cams[$monitor]."/$startTime.mp4\" 2>/dev/null");
        if (
$del_events==true) {
            
mysql_query("DELETE FROM Events WHERE id=$id;");
        } else {
            
mysql_query("UPDATE Events SET Notes='zm_arc2video';");
        }
        echo 
Chr(8).Chr(8).Chr(8).Chr(8);
        
$i++;
    }
    echo 
"\n";
    
// make an iso image?
    
if ($make_iso!=false) {
        echo 
"Creating ISO image...";
        
exec("/usr/bin/mkisofs -o $build_dir/$make_iso $build_dir >/dev/null");
        echo 
"DONE!\nDeleting videos...\n";
        foreach(
$cams as $id => $name) {
            
exec("rm -rf $build_dir/$name");
        }
        echo 
"DONE!";
    }
} else {
    die(
"No events found!\n");
}

// close mysql
mysql_close($conn);

?>