From 84b3e8f1a7e458b81df489ebfa0f27d7653bd468 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Sun, 10 Jul 2016 19:34:49 +0200 Subject: [PATCH] Initial commit --- .gitignore | 3 ++ capture.js | 80 +++++++++++++++++++++++++++++++++++++ config.sample.js | 21 ++++++++++ index.js | 58 +++++++++++++++++++++++++++ package.json | 16 ++++++++ securitycam.sublime-project | 8 ++++ 6 files changed, 186 insertions(+) create mode 100644 .gitignore create mode 100644 capture.js create mode 100644 config.sample.js create mode 100644 index.js create mode 100644 package.json create mode 100644 securitycam.sublime-project diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3e4d1b2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/config.js +/node_modules/ +*.sublime-workspace \ No newline at end of file diff --git a/capture.js b/capture.js new file mode 100644 index 0000000..18edcbe --- /dev/null +++ b/capture.js @@ -0,0 +1,80 @@ +var http = require('http'); +var fs = require('fs'); +var util = require('util'); +var Readable = require('stream').Readable; +var FfmpegCommand = require('fluent-ffmpeg'); + + +var PushStream = function(options) { Readable.call(this, options); }; +util.inherits(PushStream, Readable); +PushStream.prototype._read = function(n) { }; + + +module.exports = +{ + start: function(camId, cam, now) + { + var timer = null; + var req = null; + + console.log('Starting FFmpeg'); + + var output = new PushStream(); + var command = new FfmpegCommand(); + command + .input(output) + .inputFormat('mjpeg') + .inputOption('-use_wallclock_as_timestamps 1') + .output('D:/Temp/' + camId + '.avi') + .videoCodec('libx264') + .outputFormat('avi') + .run(); + + + var cleanup = function() + { + if (timer !== null) + { + clearTimeout(timer); + timer = null; + } + + if (command !== null) + { + output.push(null); + command = null; + } + }; + + + req = http.request(cam.url, function(res) + { + timer = setTimeout(function() + { + console.log('Timeout!'); + req.abort(); + + cleanup(); + }, cam.timeout); + + res.on('data', function(chunk) + { + output.push(chunk); + }); + + res.on('end', function() + { + console.log('End!'); + cleanup(); + }); + }); + + req.on('error', function(e) + { + console.log(e); + cleanup(); + }); + + req.end(); + } +}; \ No newline at end of file diff --git a/config.sample.js b/config.sample.js new file mode 100644 index 0000000..f080bf4 --- /dev/null +++ b/config.sample.js @@ -0,0 +1,21 @@ +var config = {}; + +config.port = 5705; +config.defaultOutputBase = '/srv/cam/'; +config.defaultOutputFilename = 'YYYY-MM-DD HH.mm.ss .avi'; +config.defaultTimeout = 5000; + +config.cams = +{ + frontdoor: + { + url: 'http://10.138.1.10/videostream.cgi?user=viewer&pwd=verysecure', + timeout: 5000, + + outputBase: '/srv/www/publiccam/YYYY-MM-DD HH.mm.ss/', + outputFilename: '.avi' + } +}; + + +module.exports = config; \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..71a8cee --- /dev/null +++ b/index.js @@ -0,0 +1,58 @@ +var config = require('./config'); +var capture = require('./capture'); + +var moment = require('moment'); +var express = require('express'); +var app = express(); + + +// Some sanity checking to avoid issues later on +if (!config.cams) + config.cams = []; + + +app.get('/', function(req, res) +{ + res.send(JSON.stringify( + { + status: 'running', + cams: Object.keys(config.cams) + })); +}); + + +app.get('/capture', function(req, res) +{ + var now = moment(); + var cams = []; + + for (var camId in config.cams) + { + cams.push(camId); + capture.start(camId, config.cams[camId], now); + } + + res.send(JSON.stringify(cams)); +}); + + +app.get('/capture/:camId', function(req, res) +{ + var camId = req.params.camId; + + if (config.cams.hasOwnProperty(camId)) + { + capture.start(config.cams[camId], moment()); + res.send(JSON.stringify([camId])); + } + else + { + res.sendStatus(404); + } +}); + + +app.listen(config.port, function() +{ + console.log('SecurityCam.js running on port ' + config.port); +}); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..176f3b2 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "securitycam.js", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.14.0", + "fluent-ffmpeg": "^2.1.0", + "moment": "^2.14.1" + } +} diff --git a/securitycam.sublime-project b/securitycam.sublime-project new file mode 100644 index 0000000..24db303 --- /dev/null +++ b/securitycam.sublime-project @@ -0,0 +1,8 @@ +{ + "folders": + [ + { + "path": "." + } + ] +}