From 8598382affc9047d926d87ab166a20992466226a Mon Sep 17 00:00:00 2001 From: Moe Date: Mon, 29 May 2017 10:35:50 -0700 Subject: [PATCH 1/4] motion plugin memory leak fix --- plugins/motion/README.md | 4 ++-- plugins/motion/shinobi-motion.js | 25 ++++++++++--------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/plugins/motion/README.md b/plugins/motion/README.md index 1ac4fa10..1bdd4e9a 100644 --- a/plugins/motion/README.md +++ b/plugins/motion/README.md @@ -38,13 +38,13 @@ nano conf.json Start the plugin. ``` -node shinobi-motion.js +node shinobi-stemkoski.js ``` Or to daemonize with PM2. ``` -pm2 start shinobi-motion.js +pm2 start shinobi-stemkoski.js ``` Doing this will reveal options in the monitor configuration. Shinobi does not need to be restarted when a plugin is initiated or stopped. diff --git a/plugins/motion/shinobi-motion.js b/plugins/motion/shinobi-motion.js index b558301e..339934ec 100644 --- a/plugins/motion/shinobi-motion.js +++ b/plugins/motion/shinobi-motion.js @@ -38,8 +38,8 @@ s={ globalCoordsObject:{} } s.blenderRegion=function(d,cord){ - d.width = s.img[d.id].width; - d.height = s.img[d.id].height; + d.width = d.image.width; + d.height = d.image.height; if(!s.canvas[d.id+'_'+cord.name]){ if(!cord.sensitivity||isNaN(cord.sensitivity)){ cord.sensitivity=d.mon.detector_sensitivity; @@ -65,7 +65,7 @@ s.blenderRegion=function(d,cord){ if(!s.canvasContext[d.id+'_'+cord.name]){ return } - s.canvasContext[d.id+'_'+cord.name].drawImage(s.img[d.id], 0, 0, d.width, d.height); + s.canvasContext[d.id+'_'+cord.name].drawImage(d.image, 0, 0, d.width, d.height); if(!s.blendRegion[d.id+'_'+cord.name]){ s.blendRegion[d.id+'_'+cord.name] = new Canvas(d.width, d.height); s.blendRegionContext[d.id+'_'+cord.name] = s.blendRegion[d.id+'_'+cord.name].getContext('2d'); @@ -139,13 +139,14 @@ s.checkAreas=function(d){ s.globalCoordsObject[d.id]=d.mon.cords; } if(d.mon.detector_frame==='1'&&!s.globalCoordsObject[d.id].frame){ - s.globalCoordsObject[d.id].frame={name:'frame',s:d.mon.detector_sensitivity,points:[[0,0],[0,s.img[d.id].height],[s.img[d.id].width,s.img[d.id].height],[s.img[d.id].width,0]]}; + s.globalCoordsObject[d.id].frame={name:'frame',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; s.globalCoords[d.id].push(s.globalCoordsObject[d.id].frame); } for (var b = 0; b < s.globalCoords[d.id].length; b++){ if(!s.globalCoords[d.id][b]){return} s.blenderRegion(d,s.globalCoords[d.id][b]) } + delete(d.image) }catch(err){ console.log(err) } @@ -189,24 +190,18 @@ io.on('f',function(d){ s.buffer[d.id]=Buffer.concat(s.buffer[d.id]); s.globalCoords[d.id]=Object.values(d.mon.cords); s.globalCoordsObject[d.id]=d.mon.cords; - if(!s.img[d.id]){ - s.img[d.id] = new Canvas.Image; - } + d.image = new Canvas.Image; if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ console.log('Must set detector image size') return }else{ - s.img[d.id].width=d.mon.detector_scale_x; - s.img[d.id].height=d.mon.detector_scale_y; - } - if(s.img[d.id].width===0||s.img[d.id].height===0){ - s.img[d.id].width=d.mon.detector_scale_x; - s.img[d.id].height=d.mon.detector_scale_y; + d.image.width=d.mon.detector_scale_x; + d.image.height=d.mon.detector_scale_y; } - s.img[d.id].src = s.buffer[d.id]; - s.img[d.id].onload = function() { + d.image.onload = function() { s.checkAreas(d); } + d.image.src = s.buffer[d.id]; s.buffer[d.id]=null; } break; From ead7297814d3578e31e9932fab2a627630308212 Mon Sep 17 00:00:00 2001 From: Moe Date: Mon, 29 May 2017 10:41:31 -0700 Subject: [PATCH 2/4] simplify code for motion plugin --- plugins/motion/README.md | 10 +++------ plugins/motion/shinobi-motion.js | 38 +++++++++++--------------------- 2 files changed, 16 insertions(+), 32 deletions(-) diff --git a/plugins/motion/README.md b/plugins/motion/README.md index 1bdd4e9a..ea999f6c 100644 --- a/plugins/motion/README.md +++ b/plugins/motion/README.md @@ -1,5 +1,4 @@ -# Shinobi stemkoski Motion Detector -Based on stemkoski JS Motion Detection +# Shinobi Motion Detector Install required libraries. @@ -38,17 +37,14 @@ nano conf.json Start the plugin. ``` -node shinobi-stemkoski.js +node shinobi-motion.js ``` Or to daemonize with PM2. ``` -pm2 start shinobi-stemkoski.js +pm2 start shinobi-motion.js ``` Doing this will reveal options in the monitor configuration. Shinobi does not need to be restarted when a plugin is initiated or stopped. -*Thanks to Cairo and others for these dependencies. Thanks to stemkoski as the JS image comparing is based on their research. I or Shinobi are not affiliated with stemkoski or Cairo.* - -Shinobi Plugin by : Moe Alam diff --git a/plugins/motion/shinobi-motion.js b/plugins/motion/shinobi-motion.js index 339934ec..1b5cfcbc 100644 --- a/plugins/motion/shinobi-motion.js +++ b/plugins/motion/shinobi-motion.js @@ -132,24 +132,19 @@ s.differenceAccuracy=function(target, data1, data2) { } s.checkAreas=function(d){ - try{ - if(!s.globalCoords[d.id]){ - if(!d.mon.cords){d.mon.cords={}} - s.globalCoords[d.id]=Object.values(d.mon.cords); - s.globalCoordsObject[d.id]=d.mon.cords; - } - if(d.mon.detector_frame==='1'&&!s.globalCoordsObject[d.id].frame){ - s.globalCoordsObject[d.id].frame={name:'frame',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; - s.globalCoords[d.id].push(s.globalCoordsObject[d.id].frame); - } - for (var b = 0; b < s.globalCoords[d.id].length; b++){ - if(!s.globalCoords[d.id][b]){return} - s.blenderRegion(d,s.globalCoords[d.id][b]) - } - delete(d.image) - }catch(err){ - console.log(err) + if(!s.globalCoords[d.id]){ + if(!d.mon.cords){d.mon.cords={}} + s.globalCoords[d.id]=Object.values(d.mon.cords); + } + if(d.mon.detector_frame==='1'&&!d.mon.cords.frame){ + d.mon.cords.frame={name:'frame',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]}; + s.globalCoords[d.id].push(d.mon.cords.frame); } + for (var b = 0; b < s.globalCoords[d.id].length; b++){ + if(!s.globalCoords[d.id][b]){return} + s.blenderRegion(d,s.globalCoords[d.id][b]) + } + delete(d.image) } io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master @@ -171,16 +166,9 @@ io.on('f',function(d){ delete(s.blendRegionContext[d.id+'_'+v.name]) }) delete(s.globalCoords[d.id]) - delete(s.globalCoordsObject[d.id]) } break; case'frame': - if(typeof d.mon ==='string'){ - try{d.mon=JSON.parse(d.mon)}catch(er){d.mon={}} - } - if(typeof d.mon.cords ==='string'){ - try{d.mon.cords=JSON.parse(d.mon.cords)}catch(er){d.mon.cords={}} - } if(!s.buffer[d.id]){ s.buffer[d.id]=[d.frame]; }else{ @@ -189,7 +177,7 @@ io.on('f',function(d){ if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){ s.buffer[d.id]=Buffer.concat(s.buffer[d.id]); s.globalCoords[d.id]=Object.values(d.mon.cords); - s.globalCoordsObject[d.id]=d.mon.cords; + d.mon.cords=d.mon.cords; d.image = new Canvas.Image; if(d.mon.detector_scale_x===''||d.mon.detector_scale_y===''){ console.log('Must set detector image size') From ad341c5ccdc1a905f465b9e3658528f7d243fc03 Mon Sep 17 00:00:00 2001 From: Moe Date: Mon, 29 May 2017 15:12:16 -0700 Subject: [PATCH 3/4] fix : deleting videos affects space count live --- camera.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/camera.js b/camera.js index 9746cc10..1910a31a 100644 --- a/camera.js +++ b/camera.js @@ -427,9 +427,13 @@ s.video=function(x,e){ if(!e.filename&&e.time){e.filename=s.moment(e.time)} if(!e.status){e.status=0} e.save=[e.id,e.ke,s.nameToTime(e.filename)]; - sql.query('DELETE FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=?',e.save,function(err,r){ - s.tx({f:'video_delete',filename:e.filename+'.'+e.ext,mid:e.mid,ke:e.ke,time:s.nameToTime(e.filename),end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); - s.file('delete',e.dir+e.filename+'.'+e.ext) + fs.stat(e.dir+e.filename+'.'+e.ext,function(err,file){ + sql.query('DELETE FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=?',e.save,function(err,r){ + s.group[e.ke].init.used_space=s.group[e.ke].init.used_space-(file.size/1000000) + s.init('diskUsed',e) + s.tx({f:'video_delete',filename:e.filename+'.'+e.ext,mid:e.mid,ke:e.ke,time:s.nameToTime(e.filename),end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke); + s.file('delete',e.dir+e.filename+'.'+e.ext) + }) }) break; case'open': From 4c3b9b349b52e82c8b27ed5658e934d654a9b005 Mon Sep 17 00:00:00 2001 From: Moe Date: Mon, 29 May 2017 15:14:21 -0700 Subject: [PATCH 4/4] readme format fix --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2504575a..002e8d89 100644 --- a/README.md +++ b/README.md @@ -54,15 +54,13 @@ http://shinobi.video/why > "After trying zoneminder without success (heavy unstable and slow) I passed to Shinobi that despite being young spins a thousand times better (I have a setup with 16 cameras recording in FHD to ~ 10fps on a pentium of ~ 2009 and I turn with load below 1.5)." -> A Reddit user -> - /r/ItalyInformatica +> *A Reddit user, /r/ItalyInformatica*   > "I would suggest Shinobi as a NVR. It's still in the early days but works a lot better than ZoneMinder for me. I'm able to record 16 cams at 1080p 15fps continously whith no load on server (Pentium E5500 3GB RAM) where zm crashed with 6 cams at 720p. Not to mention the better interface." -> A Reddit user -> /r/HomeNetworking +> *A Reddit user, /r/HomeNetworking* # How to Install and Run