Uploading Logitech Alert Security Video to Dropbox using PHP

Some time ago my house was broken into. My wife had left for a quick walk at a nearby park with our dog and within 30 minutes, at 10:30 in the morning, some people broke through our side-entry garage door and stole anything electronic that they could carry, as well as loaded weapons in a small safe. When my wife came home they escaped out the garage door again, leaving the house a mess. After this incident we decided to get some security cameras.

We chose the Logitech Alert system because they were semi-wireless and had a handy Android and website internet utility provided by Logitech. The system includes a master unit which connects to a network switch and each camera includes a wireless powerline connection (plugs into wall outlet, data is sent wirelessly) with a cable to the camera. The cameras can be loaded with a micro SD card in case the cables are broken and the internet is knocked out. The system can be configured to send a picture to your email address, however these pictures tend to be a bit blurry so Logitech also provides short video feeds.

The problem is Logitech didn’t originally include a way to store these video feeds offsite. If your computer was stolen then your videos were gone forever, and all images of the thieves. Now Logitech has updated their software to include a Dropbox feature, however it comes at a price. Here’s a simple solution that does not come at a price and only requires you to run a scheduled task or cron job every 2 minutes.

Setup

Configure Logitech Alert to store the videos in a folder. In Windows this is as easy as choosing a folder on a rather large drive (I’ve devoted 300GB to video storage). In Linux you will need to run a Windows VM, Wine won’t work for this. Within the Windows VM you can map a Linux shared folder to the Z: drive, for example. Each video file is about 5MB for 30 seconds. 300GB is about 21 days worth of video.

I’ve chosen a folder in my Linux machine called “/home/myuser/Videos/Security Cameras/Logitech Alert Recordings”. In the Windows VM it’s called “Z:\Logitech Alert Recordings”.

Install PHP (Windows) on your computer. For Linux you will have to install php-cli (for Debian-based Linux: sudo apt-get install php5-cli).

Setup Dropbox and point it to a “Dropbox” folder. Create a “Security Cameras” folder beneath this folder.

The Script

Note: scroll past the script to see how to configure the scheduling options.

This PHP script pushes the latest 2GB (about) worth of video to Dropbox’s free account. Dropbox allows up to 2GB in its free accounts, I’ve chosen to fill about 1875MB of the 2000MB. This is 375 of the latest files. The script will first do a cleanup operation on the old files before uploading the new ones.

There are 3 variables which control the entire file (Windows will use different folder paths):

$sourceFolder = "/home/myuser/Videos/Security Cameras/Logitech Alert Recordings"; //the videos folder

$dropboxFolder = "/home/myuser/Dropbox/Security Cameras"; //omit the trailing slashes

$numberOfFiles = 375; //2000MB / 5MB = 400 files. Subtract 25 files to maintain adequate folder space.

// = 3.125 hours of video

Once these variables are configured the script should work. I recommend placing this script in your “/home/myuser/Videos/Security Cameras” folder. I’ve named mine

“sync.php”.

sync.php:

$sourceFolder = "/home/myuser/Videos/Security Cameras/Logitech Alert Recordings";

$dropboxFolder = "/home/myuser/Dropbox/Security Cameras"; //omit the trailing slashes

$numberOfFiles = 375; //2000MB / 5MB = 400 files. Subtract 25 files to maintain adequate folder space. // = 3.125 hours

//finds all mp4s in the recording directory for all cameras.

//the result is a list of files where each line reads:

// /dir/filename.mp4 2011-03-27+05:25:45.1833860010

//(that's a tab between the filename and date)

$filearray = scan_directory_recursively($sourceFolder,'mp4');

//sort that shit.

$dates = array();

foreach($filearray as $key=>$file){

    $dates[$key] = $filearray[$key]['created']; //position 5 (path, name, extension, size, created)

} array_multisort($dates,SORT_DESC,$filearray); //sort it

$filearray = array_splice($filearray,0,$numberOfFiles); //remove excess files

//loop through files to copy

$filesToCopy = array();

$fileNameArray = array();

foreach($filearray as $file){

    //split the /folder/file path to extract the filename

    $fileArr = explode("/",$file['path']);

    $filename = $fileArr[count($fileArr)-1];

    $newfilename = date('Y-m-d\TH:i:s',$file['created']).' - '.$filename;

    //an array for the new filename

    $fileNameArray[] = $newfilename;

    //an array for the full path

    $filesToCopy[] = $file['path'];

}

$dropFiles = scan_directory_recursively($dropboxFolder);

$dropFileNames = array();

foreach($dropFiles as $file){

    $dropFileNames[] = $file['name'];

}

//the difference of the file lists should be all files that must be deleted from the drop directory

$diff = array_diff($dropFileNames,$fileNameArray);

//remove each file that doesn't belong in the drop directory.

foreach($diff as $file){

    echo "Deleting {$file}...\n";

    unlink("{$dropboxFolder}/{$file}");

}

if(count($diff) > 0){

    echo "\n";

}

//scan the dir again!

$dropFiles = scan_directory_recursively($dropboxFolder);

$dropFileNames = array();

foreach($dropFiles as $file){

    $dropFileNames[] = $file['name'];

} //the difference of the file lists should be all files that must be deleted from the drop directory

$diff = array_diff($fileNameArray,$dropFileNames);

foreach($diff as $key=>$file){

    echo "Copying {$file}...\n";

    copy($filesToCopy[$key],$dropboxFolder.'/'.$file);

}

function scan_directory_recursively($directory, $filter=FALSE) {

    $directory_tree = array();

    // if the path has a slash at the end we remove it here

    if(substr($directory,-1) == '/')
    {
            $directory = substr($directory,0,-1);
    }

    // if the path is not valid or is not a directory ...

    if(!file_exists($directory) || !is_dir($directory))
    {
            // ... we return false and exit the function

            return FALSE;

    // ... else if the path is readable

    }elseif(is_readable($directory))
    {
            // we open the directory

            $directory_list = opendir($directory);

            // and scan through the items inside

            while (FALSE !== ($file = readdir($directory_list)))
            {
                    // if the filepointer is not the current directory

                    // or the parent directory

                    if($file != '.' && $file != '..')
                    {
                            // we build the new path to scan

                            $path = $directory.'/'.$file;

                            // if the path is readable

                            if(is_readable($path))
                            {
                                    // we split the new path by directories

                                    $subdirectories = explode('/',$path);

                                    // if the new path is a directory

                                    if(is_dir($path))
                                    {
                                            // add the directory details to the file list

                                            $directory_tree = array_merge((array)$directory_tree,scan_directory_recursively($path, $filter));

                                    // if the new path is a file

                                    }elseif(is_file($path))
                                    {
                                            // get the file extension by taking everything after the last dot

                                            $extension = end(explode('.',end($subdirectories)));

                                            // if there is no filter set or the filter is set and matches

                                            if($filter === FALSE || $filter == $extension)
                                            {
                                                    // add the file details to the file list

                                                    $directory_tree[] = array(

                                                            'path'      => $path,

                                                            'name'      => end($subdirectories),

                                                            'extension' => $extension,

                                                            'size'      => filesize($path),

                                                            'kind'      => 'file',

                                                            'created'   => filemtime($path));

                                            }

                                    }

                            }

                    }

            }

            // close the directory

            closedir($directory_list);

            // return file list

            return $directory_tree;

    // if the path is not readable ...

    }else{

            // ... we return false

            return FALSE;   
    }

}

?>

Scheduling

Linux

Edit your crontab by typing in the Terminal “crontab -e”

Paste the following code with your modifications:

/2 * * * php "/home/myuser/Videos/Security Cameras/sync.php" # JOB_ID_4

Windows

Navigate to Start->Programs->Accessories->System Tools and choose Task Scheduler (Vista)

You will have to create a task to run “php [Drive]:\Folder\sync.php” every hour, then go back to edit the advanced options using these steps provided by Microsoft.

Latest Posts