mirror of
https://gitlab.com/Shinobi-Systems/ShinobiCE.git
synced 2025-03-09 15:40:15 +00:00
remove experimental changes
This commit is contained in:
parent
ef2fa4dc2d
commit
c7a4bb5cba
28 changed files with 355 additions and 1453 deletions
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
docker-entrypoint.sh text eol=lf
|
3
INSTALL.md
Normal file
3
INSTALL.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
**Detailed Instructions for multiple Operating Systems can now be found in the docs.**
|
||||
|
||||
https://shinobi.video/docs/start
|
|
@ -1,10 +1,10 @@
|
|||
#https://devtalk.nvidia.com/default/topic/1000340/cuda-setup-and-installation/-quot-nvidia-smi-has-failed-because-it-couldn-t-communicate-with-the-nvidia-driver-quot-ubuntu-16-04/4
|
||||
sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
|
||||
sudo echo "# NVIDIA Graphics Driver Repo (Added by Shinobi installer)" | sudo tee -a /etc/apt/sources.list
|
||||
sudo echo "# Public Key : sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub" | sudo tee -a /etc/apt/sources.list
|
||||
sudo echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 /" | sudo tee -a /etc/apt/sources.list
|
||||
apt update
|
||||
sudo apt -y install cuda-drivers
|
||||
sudo echo "# NVIDIA Graphics Driver Repo (Added by Shinobi installer)" >> /etc/apt/sources.list
|
||||
sudo echo "# Public Key : sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub" >> /etc/apt/sources.list
|
||||
sudo echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 /" >> /etc/apt/sources.list
|
||||
sudo apt update
|
||||
sudo apt-get -y install cuda-drivers
|
||||
|
||||
echo "After rebooting you need to run part 2. The file is named `cuda9-part2-after-reboot.sh`."
|
||||
echo "Reboot is required. Do it now?"
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
#!/bin/bash
|
||||
#dlib
|
||||
echo "================="
|
||||
echo "Installing OpenCV"
|
||||
echo "================="
|
||||
# OpenCV CUDA
|
||||
if [ $(dpkg-query -W -f='${Status}' git 2>/dev/null | grep -c "ok installed") -eq 0 ]; then
|
||||
echo "Installing Git..."
|
||||
apt install git -y;
|
||||
fi
|
||||
sudo apt-get install libopenblas-dev -y
|
||||
|
||||
if [ ! -e "./opencv" ]; then
|
||||
echo "Downloading OpenCV..."
|
||||
git clone https://github.com/opencv/opencv.git
|
||||
|
@ -31,64 +28,46 @@ fi
|
|||
echo "Entering OpenCV Build Directory..."
|
||||
cd build
|
||||
echo "*****************"
|
||||
if [ -f /etc/lsb-release ]; then
|
||||
flavor=$(cat /var/log/installer/media-info)
|
||||
echo "$flavor"
|
||||
echo "*****************"
|
||||
echo "Adding Additional Repository"
|
||||
echo "http://security.ubuntu.com/ubuntu"
|
||||
if [ "$flavor" = *"Artful"* ]; then
|
||||
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu artful-security main"
|
||||
fi
|
||||
if [ "$flavor" = *"Zesty"* ]; then
|
||||
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu zesty-security main"
|
||||
fi
|
||||
if [ "$flavor" = *"Xenial"* ]; then
|
||||
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
|
||||
fi
|
||||
if [ "$flavor" = *"Trusty"* ]; then
|
||||
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu trusty-security main"
|
||||
fi
|
||||
echo "Downloading Libraries"
|
||||
sudo apt-get install libjpeg-dev libpango1.0-dev libgif-dev build-essential gcc-6 g++-6 -y;
|
||||
sudo apt-get install libxvidcore-dev libx264-dev -y;
|
||||
sudo apt-get install libatlas-base-dev gfortran -y;
|
||||
|
||||
sudo apt install build-essential cmake pkg-config unzip ffmpeg qtbase5-dev python-dev python3-dev python-numpy python3-numpy libhdf5-dev libgtk-3-dev libdc1394-22 libdc1394-22-dev libjpeg-dev libtiff5-dev libtesseract-dev -y;
|
||||
|
||||
sudo apt install libavcodec-dev libavformat-dev libswscale-dev libxine2-dev libgstreamer-plugins-base1.0-0 libgstreamer-plugins-base1.0-dev libpng16-16 libpng-dev libv4l-dev libtbb-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev v4l-utils libleptonica-dev -y
|
||||
|
||||
echo "Setting CUDA Paths"
|
||||
export LD_LIBRARY_PATH=/usr/local/cuda/lib
|
||||
export PATH=$PATH:/usr/local/cuda/bin
|
||||
echo "Configure OpenCV Build"
|
||||
|
||||
cmake -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_NVCUVID=ON -D FORCE_VTK=ON -D WITH_XINE=ON -D WITH_CUDA=ON -D WITH_OPENGL=ON -D WITH_TBB=ON -D WITH_OPENCL=ON -D CMAKE_BUILD_TYPE=RELEASE -D CUDA_NVCC_FLAGS="-D_FORCE_INLINES --expt-relaxed-constexpr" -D WITH_GDAL=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules/ -D ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D WITH_CUBLAS=1 -D CXXFLAGS="-std=c++11" -DCMAKE_CXX_COMPILER=g++-6 -DCMAKE_C_COMPILER=gcc-6 ..
|
||||
|
||||
echo "Start OpenCV Build"
|
||||
make -j "$(nproc)"
|
||||
echo "Install OpenCV Build"
|
||||
sudo make install
|
||||
sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
|
||||
sudo ldconfig
|
||||
sudo apt-get update
|
||||
flavor=$(cat /var/log/installer/media-info)
|
||||
echo "$flavor"
|
||||
echo "*****************"
|
||||
echo "Adding Additional Repository"
|
||||
echo "http://security.ubuntu.com/ubuntu"
|
||||
if [ "$flavor" = *"Artful"* ]; then
|
||||
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu artful-security main"
|
||||
fi
|
||||
if [ -f /etc/redhat-release ]; then
|
||||
yum install -y \
|
||||
protobuf-devel \
|
||||
leveldb-devel \
|
||||
snappy-devel \
|
||||
opencv-devel \
|
||||
boost-devel \
|
||||
hdf5-devel \
|
||||
gflags-devel \
|
||||
glog-devel \
|
||||
lmdb-devel \
|
||||
cmake
|
||||
if [ "$flavor" = *"Zesty"* ]; then
|
||||
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu zesty-security main"
|
||||
fi
|
||||
echo "Leaving OpenCV Directory"
|
||||
cd ../..
|
||||
if [ "$flavor" = *"Xenial"* ]; then
|
||||
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
|
||||
fi
|
||||
if [ "$flavor" = *"Trusty"* ]; then
|
||||
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu trusty-security main"
|
||||
fi
|
||||
echo "Downloading Libraries"
|
||||
sudo apt-get install libjpeg-dev libpango1.0-dev libgif-dev build-essential gcc-6 g++-6 -y;
|
||||
sudo apt-get install libxvidcore-dev libx264-dev -y;
|
||||
sudo apt-get install libatlas-base-dev gfortran -y;
|
||||
|
||||
sudo apt install build-essential cmake pkg-config unzip ffmpeg qtbase5-dev python-dev python3-dev python-numpy python3-numpy libhdf5-dev libgtk-3-dev libdc1394-22 libdc1394-22-dev libjpeg-dev libtiff5-dev libtesseract-dev -y;
|
||||
|
||||
sudo apt install libavcodec-dev libavformat-dev libswscale-dev libxine2-dev libgstreamer-plugins-base1.0-0 libgstreamer-plugins-base1.0-dev libpng16-16 libpng-dev libv4l-dev libtbb-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev v4l-utils libleptonica-dev -y
|
||||
|
||||
echo "Setting CUDA Paths"
|
||||
export LD_LIBRARY_PATH=/usr/local/cuda/lib
|
||||
export PATH=$PATH:/usr/local/cuda/bin
|
||||
echo "Configure OpenCV Build"
|
||||
|
||||
cmake -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_NVCUVID=ON -D FORCE_VTK=ON -D WITH_XINE=ON -D WITH_CUDA=ON -D WITH_OPENGL=ON -D WITH_TBB=ON -D WITH_OPENCL=ON -D CMAKE_BUILD_TYPE=RELEASE -D CUDA_NVCC_FLAGS="-D_FORCE_INLINES --expt-relaxed-constexpr" -D WITH_GDAL=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules/ -D ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D WITH_CUBLAS=1 -D CXXFLAGS="-std=c++11" -DCMAKE_CXX_COMPILER=g++-6 -DCMAKE_C_COMPILER=gcc-6 ..
|
||||
|
||||
echo "Start OpenCV Build"
|
||||
make -j "$(nproc)"
|
||||
echo "Install OpenCV Build"
|
||||
sudo make install
|
||||
sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
|
||||
sudo ldconfig
|
||||
sudo apt-get update
|
||||
echo "============="
|
||||
echo "Done installing OpenCV!"
|
||||
echo "============="
|
||||
|
|
|
@ -3,6 +3,7 @@ if [ -e "INSTALL/installed.txt" ]; then
|
|||
echo "Starting Shinobi"
|
||||
pm2 start camera.js
|
||||
pm2 start cron.js
|
||||
pm2 logs
|
||||
fi
|
||||
if [ ! -e "INSTALL/installed.txt" ]; then
|
||||
chmod +x INSTALL/now.sh&&INSTALL/now.sh
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Shinobi Pro
|
||||
### (GPLv3)
|
||||
### (Creative Commons v4.0)
|
||||
|
||||
Shinobi is the Open Source CCTV Solution written in Node.JS. Designed with multiple account system, Streams by WebSocket, and Save to WebM. Shinobi can record IP Cameras and Local Cameras.
|
||||
|
||||
|
|
41
camera.js
41
camera.js
|
@ -1067,7 +1067,6 @@ s.video=function(x,e,k){
|
|||
if(s.group[e.ke].usedSpace>(s.group[e.ke].sizeLimit*config.cron.deleteOverMaxOffset)){
|
||||
s.sqlQuery('SELECT * FROM Videos WHERE status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND ke=? ORDER BY `time` ASC LIMIT 2',[e.ke],function(err,evs){
|
||||
k.del=[];k.ar=[e.ke];
|
||||
if(!evs)return console.log(err)
|
||||
evs.forEach(function(ev){
|
||||
ev.dir=s.video('getDir',ev)+s.formattedTime(ev.time)+'.'+ev.ext;
|
||||
k.del.push('(mid=? AND time=?)');
|
||||
|
@ -4408,43 +4407,6 @@ var tx;
|
|||
break;
|
||||
}
|
||||
})
|
||||
//functions for retrieving cron announcements
|
||||
cn.on('cron',function(d){
|
||||
if(d.f==='init'){
|
||||
if(config.cron.key){
|
||||
if(config.cron.key===d.cronKey){
|
||||
s.cron={started:moment(),last_run:moment(),id:cn.id};
|
||||
}else{
|
||||
cn.disconnect()
|
||||
}
|
||||
}else{
|
||||
s.cron={started:moment(),last_run:moment(),id:cn.id};
|
||||
}
|
||||
}else{
|
||||
if(s.cron&&cn.id===s.cron.id){
|
||||
delete(d.cronKey)
|
||||
switch(d.f){
|
||||
case'filters':
|
||||
s.filterEvents(d.ff,d);
|
||||
break;
|
||||
case's.tx':
|
||||
s.tx(d.data,d.to)
|
||||
break;
|
||||
case's.video':
|
||||
s.video(d.data,d.file)
|
||||
break;
|
||||
case'start':case'end':
|
||||
d.mid='_cron';s.log(d,{type:'cron',msg:d.msg})
|
||||
break;
|
||||
default:
|
||||
s.systemLog('CRON : ',d)
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
cn.disconnect()
|
||||
}
|
||||
}
|
||||
})
|
||||
cn.on('disconnect', function () {
|
||||
if(cn.socketVideoStream){
|
||||
cn.closeSocketVideoStream()
|
||||
|
@ -4471,9 +4433,6 @@ var tx;
|
|||
s.tx({f:'plugin_engine_unplugged',plug:cn.pluginEngine},'CPU')
|
||||
delete(s.api[cn.pluginEngine])
|
||||
}
|
||||
if(cn.cron){
|
||||
delete(s.cron);
|
||||
}
|
||||
if(cn.ocv){
|
||||
s.tx({f:'detector_unplugged',plug:s.ocv.plug},'CPU')
|
||||
delete(s.ocv);
|
||||
|
|
38
cron.js
38
cron.js
|
@ -10,9 +10,7 @@ var spawn = require('child_process').spawn;
|
|||
var config=require('./conf.json');
|
||||
|
||||
//set option defaults
|
||||
s={
|
||||
utcOffset : moment().utcOffset()
|
||||
};
|
||||
s={};
|
||||
if(config.cron===undefined)config.cron={};
|
||||
if(config.cron.deleteOld===undefined)config.cron.deleteOld=true;
|
||||
if(config.cron.deleteOrphans===undefined)config.cron.deleteOrphans=false;
|
||||
|
@ -25,7 +23,6 @@ if(config.cron.deleteFileBins===undefined)config.cron.deleteFileBins=true;
|
|||
if(config.cron.interval===undefined)config.cron.interval=1;
|
||||
if(config.databaseType===undefined){config.databaseType='mysql'}
|
||||
if(config.databaseLogs===undefined){config.databaseLogs=false}
|
||||
if(config.useUTC===undefined){config.useUTC=false}
|
||||
|
||||
if(!config.ip||config.ip===''||config.ip.indexOf('0.0.0.0')>-1)config.ip='localhost';
|
||||
if(!config.videosDir)config.videosDir=__dirname+'/videos/';
|
||||
|
@ -130,12 +127,6 @@ s.moment=function(e,x){
|
|||
if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'};
|
||||
return moment(e).format(x);
|
||||
}
|
||||
s.utcToLocal = function(time){
|
||||
return moment.utc(time).utcOffset(s.utcOffset).format()
|
||||
}
|
||||
s.localToUtc = function(time){
|
||||
return moment(time).utc()
|
||||
}
|
||||
s.nameToTime=function(x){x=x.replace('.webm','').replace('.mp4','').split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;}
|
||||
io = require('socket.io-client')('ws://'+config.ip+':'+config.port);//connect to master
|
||||
s.cx=function(x){x.cronKey=config.cron.key;return io.emit('cron',x)}
|
||||
|
@ -269,18 +260,12 @@ s.deleteRowsWithNoVideo=function(v,callback){
|
|||
if(evs&&evs[0]){
|
||||
es.del=[];es.ar=[v.ke];
|
||||
evs.forEach(function(ev){
|
||||
var details = JSON.parse(ev.details)
|
||||
var filename = ev.time
|
||||
var dir = s.getVideoDirectory(ev)+s.moment(filename)+'.'+ev.ext;
|
||||
var fileExists = fs.existsSync(dir)
|
||||
if(details.isUTC === true){
|
||||
filename = s.localToUtc(filename).format('YYYY-MM-DDTHH-mm-ss')
|
||||
dir = s.getVideoDirectory(ev)+filename+'.'+ev.ext;
|
||||
fileExists = fs.existsSync(dir)
|
||||
}
|
||||
if(fileExists !== true){
|
||||
ev.dir=s.getVideoDirectory(ev)+s.moment(ev.time)+'.'+ev.ext;
|
||||
if(fs.existsSync(ev.dir)!==true){
|
||||
s.video('delete',ev)
|
||||
s.tx({f:'video_delete',filename:filename+'.'+ev.ext,mid:ev.mid,ke:ev.ke,time:ev.time,end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+ev.ke);
|
||||
es.del.push('(mid=? AND time=?)');
|
||||
es.ar.push(ev.mid),es.ar.push(ev.time);
|
||||
s.tx({f:'video_delete',filename:s.moment(ev.time)+'.'+ev.ext,mid:ev.mid,ke:ev.ke,time:ev.time,end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+ev.ke);
|
||||
}
|
||||
});
|
||||
if(es.del.length>0){
|
||||
|
@ -417,7 +402,6 @@ s.processUser = function(number,rows){
|
|||
//no user object given
|
||||
return
|
||||
}
|
||||
console.log(v)
|
||||
if(!s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]){
|
||||
s.alreadyDeletedRowsWithNoVideosOnStart[v.ke]=false;
|
||||
}
|
||||
|
@ -431,9 +415,6 @@ s.processUser = function(number,rows){
|
|||
//days to keep videos
|
||||
if(!v.d.days||v.d.days==''){v.d.days=5}else{v.d.days=parseFloat(v.d.days)};
|
||||
s.sqlQuery('SELECT * FROM Monitors WHERE ke=?', [v.ke], function(err,rr) {
|
||||
if(!v.d.filters||v.d.filters==''){
|
||||
v.d.filters={};
|
||||
}
|
||||
rr.forEach(function(b,m){
|
||||
b.details=JSON.parse(b.details);
|
||||
if(b.details.max_keep_days&&b.details.max_keep_days!==''){
|
||||
|
@ -462,15 +443,10 @@ s.processUser = function(number,rows){
|
|||
}
|
||||
})
|
||||
s.deleteOldLogs(v,function(){
|
||||
console.log('deleteOldLogs')
|
||||
s.deleteOldFileBins(v,function(){
|
||||
console.log('deleteOldFileBins')
|
||||
s.deleteOldEvents(v,function(){
|
||||
console.log('deleteOldEvents')
|
||||
s.checkFilterRules(v,function(){
|
||||
console.log('checkFilterRules')
|
||||
s.deleteRowsWithNoVideo(v,function(){
|
||||
console.log('deleteRowsWithNoVideo')
|
||||
s.checkForOrphanedFiles(v,function(){
|
||||
//done user, unlock current, and do next
|
||||
s.overlapLock[v.ke]=false;
|
||||
|
@ -482,8 +458,6 @@ s.processUser = function(number,rows){
|
|||
})
|
||||
})
|
||||
})
|
||||
}else{
|
||||
s.processUser(number+1,rows)
|
||||
}
|
||||
}
|
||||
//recursive function
|
||||
|
|
3
plugins/child/.gitignore
vendored
3
plugins/child/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
conf.json
|
||||
events
|
||||
frames
|
|
@ -1,392 +0,0 @@
|
|||
var os = require('os');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mysql = require('mysql');
|
||||
var moment = require('moment');
|
||||
var request = require("request");
|
||||
var spawn = require('child_process').spawn;
|
||||
var exec = require('child_process').exec;
|
||||
var execSync = require('child_process').execSync;
|
||||
var connectionTester = require('connection-tester');
|
||||
var config = require('./conf.json');
|
||||
|
||||
exec("ps aux | grep -ie ffmpeg | awk '{print $2}' | xargs kill -9");//kill any ffmpeg running
|
||||
process.on('uncaughtException', function (err) {
|
||||
console.error('uncaughtException',err);
|
||||
});
|
||||
s={connected:false,child_node:true,platform:os.platform(),group:{}};
|
||||
|
||||
//connect to master
|
||||
io = require('socket.io-client')('ws://'+config.ws);
|
||||
//spawn conatiner
|
||||
s.spawns={};
|
||||
//emulate master sql query
|
||||
sql={
|
||||
query:function(x,y,z){
|
||||
io.emit('c',{f:'sql',query:x,values:y});if(typeof z==='function'){z();}
|
||||
}
|
||||
}
|
||||
//get this nodes cpu usage
|
||||
s.cpuUsage=function(e){
|
||||
k={}
|
||||
switch(s.platform){
|
||||
case'win32':
|
||||
k.cmd="@for /f \"skip=1\" %p in ('wmic cpu get loadpercentage') do @echo %p%"
|
||||
break;
|
||||
case'darwin':
|
||||
k.cmd="ps -A -o %cpu | awk '{s+=$1} END {print s}'";
|
||||
break;
|
||||
case'linux':
|
||||
k.cmd='LANG=C top -b -n 2 | grep "^'+config.cpuUsageMarker+'" | awk \'{print $2}\' | tail -n1';
|
||||
break;
|
||||
}
|
||||
if(config.customCpuCommand){
|
||||
exec(config.customCpuCommand,{encoding:'utf8',detached: true},function(err,d){
|
||||
if(s.isWin===true) {
|
||||
d = d.replace(/(\r\n|\n|\r)/gm, "").replace(/%/g, "")
|
||||
}
|
||||
e(d)
|
||||
});
|
||||
} else if(k.cmd){
|
||||
exec(k.cmd,{encoding:'utf8',detached: true},function(err,d){
|
||||
if(s.isWin===true){
|
||||
d=d.replace(/(\r\n|\n|\r)/gm,"").replace(/%/g,"")
|
||||
}
|
||||
e(d)
|
||||
});
|
||||
} else{
|
||||
e(0)
|
||||
}
|
||||
}
|
||||
setInterval(function(){
|
||||
s.cpuUsage(function(cpu){
|
||||
io.emit('c',{f:'cpu',cpu:parseFloat(cpu)})
|
||||
})
|
||||
},2000);
|
||||
//interact with server functions
|
||||
s.cx=function(x){io.emit('c',x)}
|
||||
//emulate master socket emitter
|
||||
s.tx=function(x,y){s.cx({f:'s.tx',data:x,to:y})}
|
||||
//emulate master logger
|
||||
s.log=function(x,y){console.log(y);s.cx({f:'s.log',data:s.init('clean',x),to:y})}
|
||||
//emulate master camera function
|
||||
s.camera=function(x,y){s.cx({f:'camera',mode:x,data:y})}
|
||||
|
||||
//load camera controller vars
|
||||
s.nameToTime=function(x){x=x.split('.')[0].split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;}
|
||||
s.ratio=function(width,height,ratio){ratio = width / height;return ( Math.abs( ratio - 4 / 3 ) < Math.abs( ratio - 16 / 9 ) ) ? '4:3' : '16:9';}
|
||||
s.gid=function(x){
|
||||
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for( var i=0; i < x; i++ )
|
||||
t += p.charAt(Math.floor(Math.random() * p.length));
|
||||
return t;
|
||||
};
|
||||
s.moment=function(e,x){if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'};return moment(e).utcOffset('-0800').format(x)}
|
||||
s.kill=function(x,e,p){
|
||||
if(e&&s.group[e.ke].mon[e.id].record){
|
||||
clearTimeout(s.group[e.ke].mon[e.id].record.capturing);
|
||||
if(s.group[e.ke].mon[e.id].record.request&&s.group[e.ke].mon[e.id].record.request.abort){s.group[e.ke].mon[e.id].record.request.abort();delete(s.group[e.ke].mon[e.id].record.request);}
|
||||
};
|
||||
if(!x||x===1){return};if(!x.stdin){return};p=x.pid;x.stdin.pause();setTimeout(function(){x.kill('SIGTERM');delete(x);setTimeout(function(){exec('kill -9 '+p)},1000)},1000)
|
||||
}
|
||||
s.cameraVals=function(e){
|
||||
e.t=Object.keys(s.group[e.ke].mon[e.id]);e.a={};
|
||||
e.t.forEach(function(n){
|
||||
if(s.group[e.ke].mon[e.id][n] instanceof Object){e.a[n]=s.group[e.ke].mon[e.id][n]};
|
||||
});
|
||||
return e.a;
|
||||
}
|
||||
//directories
|
||||
s.group={};
|
||||
s.dir={videos:__dirname+'/videos/',frames:__dirname+'/frames/'};
|
||||
if (!fs.existsSync(s.dir.frames)){
|
||||
fs.mkdirSync(s.dir.frames);
|
||||
}
|
||||
if (!fs.existsSync(s.dir.videos)){
|
||||
fs.mkdirSync(s.dir.videos);
|
||||
}
|
||||
////Camera Controller
|
||||
s.init=function(x,e){
|
||||
switch(x){
|
||||
case 0://camera
|
||||
if(!s.group[e.ke]){s.group[e.ke]={}};
|
||||
if(!s.group[e.ke].mon){s.group[e.ke].mon={}}
|
||||
if(!s.group[e.ke].mon[e.mid]){s.group[e.ke].mon[e.mid]={}}
|
||||
if(!s.group[e.ke].mon[e.mid].watch){s.group[e.ke].mon[e.mid].watch={}};
|
||||
if(e.type==='record'){e.record=1}else{e.record=0}
|
||||
if(!s.group[e.ke].mon[e.mid].record){s.group[e.ke].mon[e.mid].record={yes:e.record}};
|
||||
if(!s.group[e.ke].mon[e.mid].started){s.group[e.ke].mon[e.mid].started={}};
|
||||
if(!s.group[e.ke].mon[e.mid].running){s.group[e.ke].mon[e.mid].running={}};
|
||||
break;
|
||||
case'clean':
|
||||
if(e instanceof Object){
|
||||
x={keys:Object.keys(e),ar:{}};
|
||||
x.keys.forEach(function(v){
|
||||
if(v!=='record'&&v!=='spawn'&&v!=='running'&&(typeof e[v]!=='function')){x.ar[v]=e[v];}
|
||||
});
|
||||
return x.ar;
|
||||
}
|
||||
break;
|
||||
case'url':
|
||||
//build a complete url from pieces
|
||||
e.authd='';
|
||||
if(e.details.muser&&e.details.muser!==''&&e.host.indexOf('@')===-1) {
|
||||
e.authd=e.details.muser+':'+e.details.mpass+'@';
|
||||
}
|
||||
if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port}
|
||||
e.url=e.protocol+'://'+e.authd+e.host+e.porty+e.path;return e.url;
|
||||
break;
|
||||
case'url_no_path':
|
||||
e.authd='';
|
||||
if(!e.details.muser){e.details.muser=''}
|
||||
if(!e.details.mpass){e.details.mpass=''}
|
||||
if(e.details.muser!==''&&e.host.indexOf('@')===-1) {
|
||||
e.authd=e.details.muser+':'+e.details.mpass+'@';
|
||||
}
|
||||
if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port}
|
||||
e.url=e.protocol+'://'+e.authd+e.host+e.porty;return e.url;
|
||||
break;
|
||||
}
|
||||
if(typeof e.callback==='function'){setTimeout(function(){e.callback();delete(e.callback);},2000);}
|
||||
}
|
||||
s.video=function(x,e){
|
||||
if(!e){e={}};
|
||||
if(e.mid){e.id=e.mid};
|
||||
switch(x){
|
||||
case'delete':
|
||||
e.dir=s.dir.videos+e.ke+'/'+e.id+'/';
|
||||
e.save=[e.id,e.ke,s.nameToTime(e.filename),0];
|
||||
sql.query('DELETE FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=? AND `status`=?',e.save)
|
||||
s.tx({f:'video_delete',reason:'Camera Error',filename:e.filename+'.'+e.ext,mid:e.id,ke:e.ke,time:s.nameToTime(e.filename),end:moment().format('YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke);
|
||||
if(fs.existsSync(e.dir+e.filename+'.'+e.ext)){
|
||||
return fs.unlink(e.dir+e.filename+'.'+e.ext);
|
||||
}
|
||||
break;
|
||||
case'close':
|
||||
e.dir=s.dir.videos+e.ke+'/'+e.id+'/';
|
||||
console.log(e.dir+e.filename+'.'+e.ext)
|
||||
if(fs.existsSync(e.dir+e.filename+'.'+e.ext)){
|
||||
e.filesize=fs.statSync(e.dir+e.filename+'.'+e.ext)["size"];
|
||||
if((e.filesize/100000).toFixed(2)>0.25){
|
||||
e.save=[e.filesize,e.frames,1,e.id,e.ke,s.nameToTime(e.filename)];
|
||||
sql.query('UPDATE Videos SET `size`=?,`frames`=?,`status`=? WHERE `mid`=? AND `ke`=? AND `time`=?',e.save)
|
||||
fs.readFile(e.dir+e.filename+'.'+e.ext,function (err,data) {
|
||||
s.cx({f:'created_file',mid:e.id,ke:e.ke,created_file:data,filename:e.filename+'.'+e.ext,d:s.init('clean',e)});
|
||||
s.tx({f:'video_build_success',filename:e.filename+'.'+e.ext,mid:e.id,ke:e.ke,time:s.nameToTime(e.filename),size:e.filesize,end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke);
|
||||
});
|
||||
}else{
|
||||
s.video('delete',e);
|
||||
s.log(e,{type:'File Corrupt',msg:{ffmpeg:s.group[e.ke].mon[e.mid].ffmpeg,filesize:(e.filesize/100000).toFixed(2)}})
|
||||
}
|
||||
}else{
|
||||
s.video('delete',e);
|
||||
s.log(e,{type:'File Not Exist',msg:'Cannot save non existant file. Something went wrong.',ffmpeg:s.group[e.ke].mon[e.id].ffmpeg})
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
s.ffmpeg=function(e,x){
|
||||
if(!x){x={tmp:''}}
|
||||
// if(!e.details.cutoff||e.details.cutoff===''){x.cutoff=15}else{x.cutoff=parseFloat(e.details.cutoff)};if(isNaN(x.cutoff)===true){x.cutoff=15}
|
||||
// x.segment=' -f segment -strftime 1 -segment_time '+(60*x.cutoff)+' -segment_format '+e.ext
|
||||
if(!e.details.timestamp||e.details.timestamp==1){x.time=' -vf drawtext=fontfile=/usr/share/fonts/truetype/freefont/FreeSans.ttf:text=\'%{localtime}\':x=(w-tw)/2:y=0:fontcolor=white:box=1:boxcolor=0x00000000@1:fontsize=10';}else{x.time=''}
|
||||
switch(e.ext){
|
||||
case'mp4':
|
||||
x.vcodec='libx265';x.acodec='libfaac';
|
||||
if(e.details.vcodec&&e.details.vcodec!==''){x.vcodec=e.details.vcodec}
|
||||
break;
|
||||
case'webm':
|
||||
x.acodec='libvorbis',x.vcodec='libvpx';
|
||||
break;
|
||||
}
|
||||
if(e.details.acodec&&e.details.acodec!==''){x.acodec=e.details.acodec}
|
||||
if(x.acodec==='none'){x.acodec=''}else{x.acodec=' -acodec '+x.acodec}
|
||||
if(x.vcodec!=='none'){x.vcodec=' -vcodec '+x.vcodec}
|
||||
if(e.fps&&e.fps!==''){x.framerate=' -r '+e.fps}else{x.framerate=''}
|
||||
if(e.details.vf&&e.details.vf!==''){
|
||||
if(x.time===''){x.vf=' -vf '}else{x.vf=','}
|
||||
x.vf+=e.details.vf;
|
||||
x.time+=x.vf;
|
||||
}
|
||||
if(e.details.svf&&e.details.svf!==''){x.svf=' -vf '+e.details.svf;}else{x.svf='';}
|
||||
// if(e.details.svf){'-vf "rotate=45*(PI/180)'}
|
||||
switch(e.type){
|
||||
case'socket':case'jpeg':case'pipe':
|
||||
if(!x.vf||x.vf===','){x.vf=''}
|
||||
x.tmp='-loglevel warning -pattern_type glob -f image2pipe'+x.framerate+' -vcodec mjpeg -i -'+x.vcodec+x.time+x.framerate+' -use_wallclock_as_timestamps 1 -q:v 1'+x.vf+' '+e.dir+e.filename+'.'+e.ext;
|
||||
break;
|
||||
case'mjpeg':
|
||||
if(e.mode=='record'){
|
||||
x.watch=x.vcodec+x.time+' -r 10 -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 -q:v 1 '+e.dir+e.filename+'.'+e.ext+''
|
||||
}else{
|
||||
x.watch='';
|
||||
};
|
||||
x.tmp='-loglevel warning -reconnect 1 -f mjpeg -i '+e.url+''+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1';
|
||||
break;
|
||||
case'h264':
|
||||
if(!x.vf||x.vf===','){x.vf=''}
|
||||
if(e.mode=='record'){
|
||||
x.watch=x.vcodec+x.framerate+x.acodec+' -movflags frag_keyframe+empty_moov -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 -q:v 1'+x.vf+' '+e.dir+e.filename+'.'+e.ext
|
||||
}else{
|
||||
x.watch='';
|
||||
};
|
||||
x.tmp='-loglevel warning -i '+e.url+' -stimeout 2000'+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1';
|
||||
break;
|
||||
case'local':
|
||||
if(e.mode=='record'){
|
||||
x.watch=x.vcodec+x.time+x.framerate+x.acodec+' -movflags frag_keyframe+empty_moov -s '+e.width+'x'+e.height+' -use_wallclock_as_timestamps 1 '+e.dir+e.filename+'.'+e.ext
|
||||
}else{
|
||||
x.watch='';
|
||||
};
|
||||
x.tmp='-loglevel warning -i '+e.path+''+x.watch+' -f image2pipe'+x.svf+' -s '+e.ratio+' pipe:1';
|
||||
break;
|
||||
}
|
||||
s.group[e.ke].mon[e.mid].ffmpeg=x.tmp;
|
||||
return spawn('ffmpeg',x.tmp.split(' '));
|
||||
}
|
||||
|
||||
//child functions
|
||||
var cn={};
|
||||
io.on('connect', function(d){
|
||||
console.log('connected');
|
||||
io.emit('c',{f:'init',socketKey:config.key,u:{name:config.name}})
|
||||
});
|
||||
io.on('c',function(d){
|
||||
console.log(d.f);
|
||||
switch(d.f){
|
||||
case'init_success':
|
||||
s.connected=true;
|
||||
s.other_helpers=d.child_helpers;
|
||||
break;
|
||||
case'kill':
|
||||
s.init(0,d.d);
|
||||
s.kill(s.group[d.d.ke].mon[d.d.id].spawn,d.d)
|
||||
break;
|
||||
case'sync':
|
||||
s.init(0,d.sync);
|
||||
Object.keys(d.sync).forEach(function(v){
|
||||
s.group[d.sync.ke].mon[d.sync.mid][v]=d.sync[v];
|
||||
});
|
||||
break;
|
||||
case'delete_file'://delete video
|
||||
d.dir=s.dir.videos+d.ke+'/'+d.mid+'/'+d.file;
|
||||
if(fs.existsSync(d.dir)){
|
||||
fs.unlink(d.dir);
|
||||
}
|
||||
break;
|
||||
case'close'://close video
|
||||
s.video('close',d.d);
|
||||
break;
|
||||
case'spawn'://start video
|
||||
s.init(0,d.d);
|
||||
s.group[d.d.ke].mon[d.d.id]=d.mon;
|
||||
if(!s.group[d.d.ke].mon_conf){s.group[d.d.ke].mon_conf={}}
|
||||
if(!s.group[d.d.ke].mon_conf[d.d.id]){s.group[d.d.ke].mon_conf[d.d.id]=s.init('clean',d.d);}
|
||||
if(s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){return}
|
||||
if(d.d.mode==='record'){
|
||||
console.log(s.group[d.d.ke].mon[d.d.id])
|
||||
s.group[d.d.ke].mon[d.d.id].record.yes=1;
|
||||
d.d.dir=s.dir.videos+d.d.ke+'/';
|
||||
if (!fs.existsSync(d.d.dir)){
|
||||
fs.mkdirSync(d.d.dir);
|
||||
}
|
||||
d.d.dir=s.dir.videos+d.d.ke+'/'+d.d.id+'/';
|
||||
if (!fs.existsSync(d.d.dir)){
|
||||
fs.mkdirSync(d.d.dir);
|
||||
}
|
||||
}else{
|
||||
s.group[d.d.ke].mon[d.d.mid].record.yes=0;
|
||||
}
|
||||
if(d.d.mode==='record'||d.d.type==='mjpeg'||d.d.type==='h264'||d.d.type==='local'){
|
||||
s.group[d.d.ke].mon[d.d.id].spawn = s.ffmpeg(d.d);
|
||||
s.log(d.d,{type:'FFMPEG Process Starting',msg:{cmd:s.group[d.d.ke].mon[d.d.id].ffmpeg}});
|
||||
}
|
||||
d.d.frames=0;
|
||||
switch(d.d.type){
|
||||
case'jpeg':
|
||||
if(!d.d.details.sfps||d.d.details.sfps===''){
|
||||
d.d.details.sfps=parseFloat(d.d.details.sfps);
|
||||
if(isNaN(d.d.details.sfps)){d.d.details.sfps=1}
|
||||
}
|
||||
d.d.captureOne=function(f){
|
||||
s.group[d.d.ke].mon[d.d.id].record.request=request({url:d.d.url,method:'GET',encoding: null,timeout:3000},function(er,data){
|
||||
++d.d.frames; if(s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){
|
||||
if(er){
|
||||
++d.d.error_count;
|
||||
s.log(d.d,{type:'Snapshot Error',msg:er});
|
||||
return;
|
||||
}
|
||||
if(d.d.mode==='record'&&s.group[d.d.ke].mon[d.d.id].spawn&&s.group[d.d.ke].mon[d.d.id].spawn.stdin){
|
||||
s.group[d.d.ke].mon[d.d.id].spawn.stdin.write(data.body);
|
||||
}
|
||||
if(s.group[d.d.ke].mon[d.d.id].watch&&Object.keys(s.group[d.d.ke].mon[d.d.id].watch).length>0){
|
||||
s.tx({f:'monitor_frame',ke:d.d.ke,id:d.d.id,time:s.moment(),frame:data.body.toString('base64'),frame_format:'b64'},'MON_'+d.d.id);
|
||||
}
|
||||
s.group[d.d.ke].mon[d.d.id].record.capturing=setTimeout(function(){d.d.captureOne()},1000/d.d.details.sfps);
|
||||
clearTimeout(d.d.timeOut),d.d.timeOut=setTimeout(function(){d.d.error_count=0;},3000)
|
||||
}
|
||||
}).on('error', function(err){
|
||||
// if(s.group[d.d.ke]&&s.group[d.d.ke].mon[d.d.id]&&s.group[d.d.ke].mon[d.d.id].record&&s.group[d.d.ke].mon[d.d.id].record.request){s.group[d.d.ke].mon[d.d.id].record.request.abort();}
|
||||
clearTimeout(s.group[d.d.ke].mon[d.d.id].record.capturing);
|
||||
if(d.d.error_count>4){d.d.fn();return}
|
||||
d.d.captureOne();
|
||||
});
|
||||
}
|
||||
d.d.captureOne()
|
||||
break;
|
||||
case'mjpeg':case'h264'://case'socket':case'local':
|
||||
if(!s.group[d.d.ke]||!s.group[d.d.ke].mon[d.d.id]){s.init(0,d.d)}
|
||||
if(s.group[d.d.ke].mon[d.d.id].spawn){
|
||||
s.group[d.d.ke].mon[d.d.id].spawn.on('error',function(er){d.d.error({type:'Spawn Error',msg:er})})
|
||||
s.group[d.d.ke].mon[d.d.id].spawn.stdout.on('data',function(de){
|
||||
s.tx({f:'monitor_frame',ke:d.d.ke,id:d.d.id,time:s.moment(),frame:de.toString('base64'),frame_format:'b64'},'MON_'+d.d.id);
|
||||
});
|
||||
s.group[d.d.ke].mon[d.d.id].spawn.stderr.on('data',function(de){
|
||||
de=de.toString();
|
||||
d.d.chk=function(x){return de.indexOf(x)>-1;}
|
||||
switch(true){
|
||||
// case d.d.chk('av_interleaved_write_frame'):
|
||||
case d.d.chk('Connection timed out'):
|
||||
setTimeout(function(){s.log(d.d,{type:"Can't Connect",msg:'Retrying...'});d.d.error_fatal();},1000)//restart
|
||||
break;
|
||||
case d.d.chk('No pixel format specified'):
|
||||
s.log(d.d,{type:"FFMPEG STDERR",msg:{ffmpeg:s.group[d.d.ke].mon[d.d.id].ffmpeg,msg:de}})
|
||||
break;
|
||||
case d.d.chk('RTP: missed'):
|
||||
case d.d.chk('deprecated pixel format used, make sure you did set range correctly'):
|
||||
return
|
||||
break;
|
||||
case d.d.chk('No such file or directory'):
|
||||
case d.d.chk('Unable to open RTSP for listening'):
|
||||
case d.d.chk('timed out'):
|
||||
case d.d.chk('Invalid data found when processing input'):
|
||||
case d.d.chk('Immediate exit requested'):
|
||||
case d.d.chk('reset by peer'):
|
||||
if(d.d.frames===0&&x==='record'){s.video('delete',d.d)};
|
||||
break;
|
||||
}
|
||||
s.log(d.d,{type:"FFMPEG STDERR",msg:de})
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case'video':
|
||||
s.video(d.d[0],d.d[1]);
|
||||
break;
|
||||
}
|
||||
});
|
||||
io.on('disconnect',function(d){
|
||||
s.connected=false;
|
||||
});
|
||||
|
||||
//web server
|
||||
if(config.port===undefined)config.port = 8080;
|
||||
if(config.ip===undefined||config.ip===''||config.ip.indexOf('0.0.0.0')>-1){config.ip='localhost'}else{config.bindip=config.ip};
|
||||
var childNodeHTTP = express();
|
||||
var childNodeServer = http.createServer(app);
|
||||
var childNodeWebsocket = new (require('socket.io'))()
|
||||
childNodeServer.listen(config.port,config.bindip,function(){
|
||||
console.log('SHINOBI CHILD NODE RUNNING ON PORT : '+config.port);
|
||||
});
|
||||
childNodeWebsocket.attach(childNodeServer);
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"name":"childMachine1",
|
||||
"ws":"192.168.1.48",
|
||||
"port":8080,
|
||||
"key":"3123asdasdf1dtj1hjk23sdfaasd12asdasddfdbtnkkfgvesra3asdsd3123afdsfqw345",
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#!/bin/bash
|
||||
ln -s /usr/local/cuda/targets/x86_64-linux/lib/libcurand.so /usr/local/lib/libcurand.so
|
||||
ln -s /usr/local/cuda/targets/x86_64-linux/lib/libcublas.so /usr/local/lib/libcublas.so
|
||||
ln -s /usr/local/cuda/targets/x86_64-linux/lib/libcudart.so /usr/local/lib/libcudart.so
|
||||
|
||||
git clone https://github.com/OrKoN/darknet
|
||||
rm darknet/Makefile
|
||||
cp modifiedMakefile darknet/Makefile
|
||||
cd darknet
|
||||
make OPENCV=1 GPU=1
|
||||
make install
|
||||
|
||||
npm install @moovel/yolo --unsafe-perm
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"plug":"OpenCV",
|
||||
"host":"localhost",
|
||||
"port":8080,
|
||||
"hostPort":8082,
|
||||
"key":"change_this_to_something_very_random____make_sure_to_match__/plugins/opencv/conf.json",
|
||||
"mode":"client",
|
||||
"type":"detector"
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
GPU=0
|
||||
CUDNN=0
|
||||
OPENCV=1
|
||||
OPENMP=0
|
||||
DEBUG=0
|
||||
|
||||
PREFIX = /usr/local
|
||||
|
||||
ARCH= #-gencode arch=compute_20,code=[sm_20,sm_21] \
|
||||
-gencode arch=compute_30,code=sm_30 \
|
||||
-gencode arch=compute_35,code=sm_35 \
|
||||
-gencode arch=compute_50,code=[sm_50,compute_50] \
|
||||
-gencode arch=compute_52,code=[sm_52,compute_52]
|
||||
|
||||
# This is what I use, uncomment if you know your arch and want to specify
|
||||
# ARCH= -gencode arch=compute_52,code=compute_52
|
||||
|
||||
VPATH=./src/:./examples
|
||||
SLIB=libdarknet.so
|
||||
ALIB=libdarknet.a
|
||||
EXEC=darknet
|
||||
OBJDIR=./obj/
|
||||
|
||||
CC=gcc
|
||||
NVCC=nvcc
|
||||
AR=ar
|
||||
ARFLAGS=rcs
|
||||
OPTS=-Ofast
|
||||
LDFLAGS= -lm -pthread
|
||||
COMMON= -Iinclude/ -Isrc/
|
||||
CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC
|
||||
|
||||
ifeq ($(OPENMP), 1)
|
||||
CFLAGS+= -fopenmp
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
OPTS=-O0 -g
|
||||
endif
|
||||
|
||||
CFLAGS+=$(OPTS)
|
||||
|
||||
ifeq ($(OPENCV), 1)
|
||||
COMMON+= -DOPENCV
|
||||
CFLAGS+= -DOPENCV
|
||||
LDFLAGS+= `pkg-config --libs opencv`
|
||||
COMMON+= `pkg-config --cflags opencv`
|
||||
endif
|
||||
|
||||
ifeq ($(GPU), 1)
|
||||
COMMON+= -DGPU -I/usr/local/cuda/include/
|
||||
CFLAGS+= -DGPU
|
||||
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
|
||||
endif
|
||||
|
||||
ifeq ($(CUDNN), 1)
|
||||
COMMON+= -DCUDNN
|
||||
CFLAGS+= -DCUDNN
|
||||
LDFLAGS+= -lcudnn
|
||||
endif
|
||||
|
||||
OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o detection_layer.o route_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o lstm_layer.o
|
||||
EXECOBJA=captcha.o lsd.o super.o voxel.o art.o tag.o cifar.o go.o rnn.o rnn_vid.o compare.o segmenter.o regressor.o classifier.o coco.o dice.o yolo.o detector.o writing.o nightmare.o swag.o darknet.o
|
||||
ifeq ($(GPU), 1)
|
||||
LDFLAGS+= -lstdc++
|
||||
OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o network_kernels.o avgpool_layer_kernels.o
|
||||
endif
|
||||
|
||||
EXECOBJ = $(addprefix $(OBJDIR), $(EXECOBJA))
|
||||
OBJS = $(addprefix $(OBJDIR), $(OBJ))
|
||||
DEPS = $(wildcard src/*.h) Makefile include/darknet.h
|
||||
HEADERS = $(wildcard src/*.h)
|
||||
|
||||
#all: obj backup results $(SLIB) $(ALIB) $(EXEC)
|
||||
all: obj results $(SLIB) $(ALIB) $(EXEC)
|
||||
|
||||
|
||||
$(EXEC): $(EXECOBJ) $(ALIB)
|
||||
$(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(ALIB)
|
||||
|
||||
$(ALIB): $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
$(SLIB): $(OBJS)
|
||||
$(CC) $(CFLAGS) -shared $^ -o $@ $(LDFLAGS)
|
||||
|
||||
$(OBJDIR)%.o: %.c $(DEPS)
|
||||
$(CC) $(COMMON) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJDIR)%.o: %.cu $(DEPS)
|
||||
$(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $@
|
||||
|
||||
darknet.a: $(OBJS)
|
||||
ar rcs $@ $^
|
||||
|
||||
obj:
|
||||
mkdir -p obj
|
||||
backup:
|
||||
mkdir -p backup
|
||||
results:
|
||||
mkdir -p results
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJS) $(SLIB) $(ALIB) $(EXEC) $(EXECOBJ) darknet.a
|
||||
|
||||
.PHONY: install
|
||||
|
||||
install:
|
||||
mkdir -p $(PREFIX)/include/darknet
|
||||
cp libdarknet.a $(PREFIX)/lib/libdarknet.a
|
||||
cp ${HEADERS} include/darknet.h $(PREFIX)/include/darknet
|
||||
|
||||
.PHONY: uninstall
|
||||
|
||||
uninstall:
|
||||
rm -f $(PREFIX)/lib/libdarknet.a
|
||||
rm -rf $(PREFIX)/include/darknet
|
|
@ -1,456 +0,0 @@
|
|||
//
|
||||
// Shinobi - OpenCV Plugin
|
||||
// Copyright (C) 2016-2025 Moe Alam, moeiscool
|
||||
//
|
||||
// # Donate
|
||||
//
|
||||
// If you like what I am doing here and want me to continue please consider donating :)
|
||||
// PayPal : paypal@m03.ca
|
||||
//
|
||||
process.on('uncaughtException', function (err) {
|
||||
console.error('uncaughtException',err);
|
||||
});
|
||||
var fs=require('fs');
|
||||
var cv=require('opencv4nodejs');
|
||||
var exec = require('child_process').exec;
|
||||
var moment = require('moment');
|
||||
var Canvas = require('canvas');
|
||||
var express = require('express');
|
||||
var http = require('http'),
|
||||
app = express(),
|
||||
server = http.createServer(app);
|
||||
var config=require('./conf.json');
|
||||
if(!config.port){config.port=8080}
|
||||
if(!config.hostPort){config.hostPort=8082}
|
||||
if(config.systemLog===undefined){config.systemLog=true}
|
||||
if(config.cascadesDir===undefined){config.cascadesDir=__dirname+'/cascades/'}
|
||||
if(config.alprConfig===undefined){config.alprConfig=__dirname+'/openalpr.conf'}
|
||||
s={
|
||||
group:{},
|
||||
dir:{
|
||||
cascades : config.cascadesDir
|
||||
},
|
||||
isWin:(process.platform==='win32')
|
||||
}
|
||||
//default stream folder check
|
||||
if(!config.streamDir){
|
||||
if(s.isWin===false){
|
||||
config.streamDir='/dev/shm'
|
||||
}else{
|
||||
config.streamDir=config.windowsTempDir
|
||||
}
|
||||
if(!fs.existsSync(config.streamDir)){
|
||||
config.streamDir=__dirname+'/streams/'
|
||||
}else{
|
||||
config.streamDir+='/streams/'
|
||||
}
|
||||
}
|
||||
s.dir.streams=config.streamDir;
|
||||
//streams dir
|
||||
if(!fs.existsSync(s.dir.streams)){
|
||||
fs.mkdirSync(s.dir.streams);
|
||||
}
|
||||
s.gid=function(x){
|
||||
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for( var i=0; i < x; i++ )
|
||||
t += p.charAt(Math.floor(Math.random() * p.length));
|
||||
return t;
|
||||
};
|
||||
s.findCascades=function(callback){
|
||||
var tmp={};
|
||||
tmp.foundCascades=[];
|
||||
fs.readdir(s.dir.cascades,function(err,files){
|
||||
files.forEach(function(cascade,n){
|
||||
if(cascade.indexOf('.xml')>-1){
|
||||
tmp.foundCascades.push(cascade.replace('.xml',''))
|
||||
}
|
||||
})
|
||||
s.cascadesInDir=tmp.foundCascades;
|
||||
callback(tmp.foundCascades)
|
||||
})
|
||||
}
|
||||
s.findCascades(function(){
|
||||
//get cascades
|
||||
})
|
||||
s.detectLicensePlate=function(buffer,d,tx){
|
||||
if(!d.mon.detector_lisence_plate_country||d.mon.detector_lisence_plate_country===''){
|
||||
d.mon.detector_lisence_plate_country='us'
|
||||
}
|
||||
d.tmpFile=s.gid(5)+'.jpg'
|
||||
if(!fs.existsSync(s.dir.streams)){
|
||||
fs.mkdirSync(s.dir.streams);
|
||||
}
|
||||
d.dir=s.dir.streams+d.ke+'/'
|
||||
if(!fs.existsSync(d.dir)){
|
||||
fs.mkdirSync(d.dir);
|
||||
}
|
||||
d.dir=s.dir.streams+d.ke+'/'+d.id+'/'
|
||||
if(!fs.existsSync(d.dir)){
|
||||
fs.mkdirSync(d.dir);
|
||||
}
|
||||
fs.writeFile(d.dir+d.tmpFile,buffer,function(err){
|
||||
if(err) return s.systemLog(err);
|
||||
exec('alpr -j --config '+config.alprConfig+' -c '+d.mon.detector_lisence_plate_country+' '+d.dir+d.tmpFile,{encoding:'utf8'},(err, scan, stderr) => {
|
||||
if(err){
|
||||
s.systemLog(err);
|
||||
}else{
|
||||
try{
|
||||
try{
|
||||
scan=JSON.parse(scan.replace('--(!)Loaded CUDA classifier','').trim())
|
||||
}catch(err){
|
||||
if(!scan||!scan.results){
|
||||
return s.systemLog(scan,err);
|
||||
}
|
||||
}
|
||||
// console.log('scan',scan)
|
||||
if(scan.results.length>0){
|
||||
scan.plates=[]
|
||||
scan.mats=[]
|
||||
scan.results.forEach(function(v){
|
||||
v.candidates.forEach(function(g,n){
|
||||
if(v.candidates[n].matches_template)
|
||||
delete(v.candidates[n].matches_template)
|
||||
})
|
||||
scan.plates.push({coordinates:v.coordinates,candidates:v.candidates,confidence:v.confidence,plate:v.plate})
|
||||
var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2));
|
||||
var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2))
|
||||
scan.mats.push({
|
||||
x:v.coordinates[0].x,
|
||||
y:v.coordinates[0].y,
|
||||
width:width,
|
||||
height:height,
|
||||
tag:v.plate
|
||||
})
|
||||
})
|
||||
tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:'licensePlate',reason:'object',matrices:scan.mats,imgHeight:d.mon.detector_scale_y,imgWidth:d.mon.detector_scale_x,frame:d.base64}})
|
||||
}
|
||||
}catch(err){
|
||||
s.systemLog(scan,err);
|
||||
}
|
||||
}
|
||||
exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'})
|
||||
})
|
||||
})
|
||||
}
|
||||
s.detectObject=function(buffer,d,tx){
|
||||
//detect license plate?
|
||||
if(d.mon.detector_lisence_plate==="1"){
|
||||
s.detectLicensePlate(buffer,d,tx)
|
||||
}
|
||||
//check selected opencv cascades
|
||||
var selectedCascades = Object.keys(d.mon.detector_cascades);
|
||||
if(selectedCascades.length > 0){
|
||||
cv.imdecodeAsync(buffer,(err,im) => {
|
||||
if(err){
|
||||
console.log(err)
|
||||
return
|
||||
}
|
||||
selectedCascades.forEach(function(cascade){
|
||||
var classifier = new cv.CascadeClassifier(s.dir.cascades+cascade+'.xml')
|
||||
var matrices = classifier.detectMultiScaleGpu(im).objects
|
||||
if(matrices.length > 0){
|
||||
matrices.forEach(function(v,n){
|
||||
v.centerX=v.width/2
|
||||
v.centerY=v.height/2
|
||||
v.centerXnoParent=v.x+(v.width/2)
|
||||
v.centerYnoParent=v.y+(v.height/2)
|
||||
})
|
||||
s.cx({
|
||||
f:'trigger',
|
||||
id:d.id,
|
||||
ke:d.ke,
|
||||
name:cascade,
|
||||
details:{
|
||||
plug:'built-in-opencv',
|
||||
name:cascade,
|
||||
reason:'object',
|
||||
matrices : matrices,
|
||||
confidence:d.average
|
||||
},
|
||||
imgHeight:d.mon.detector_scale_y,
|
||||
imgWidth:d.mon.detector_scale_x
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
s.systemLog=function(q,w,e){
|
||||
if(!w){w=''}
|
||||
if(!e){e=''}
|
||||
if(config.systemLog===true){
|
||||
return console.log(moment().format(),q,w,e)
|
||||
}
|
||||
}
|
||||
|
||||
s.blenderRegion=function(d,cord,tx){
|
||||
d.width = d.image.width;
|
||||
d.height = d.image.height;
|
||||
if(!s.group[d.ke][d.id].canvas[cord.name]){
|
||||
if(!cord.sensitivity||isNaN(cord.sensitivity)){
|
||||
cord.sensitivity=d.mon.detector_sensitivity;
|
||||
}
|
||||
s.group[d.ke][d.id].canvas[cord.name] = new Canvas(d.width,d.height);
|
||||
s.group[d.ke][d.id].canvasContext[cord.name] = s.group[d.ke][d.id].canvas[cord.name].getContext('2d');
|
||||
s.group[d.ke][d.id].canvasContext[cord.name].fillStyle = '#000';
|
||||
s.group[d.ke][d.id].canvasContext[cord.name].fillRect( 0, 0,d.width,d.height);
|
||||
if(cord.points&&cord.points.length>0){
|
||||
s.group[d.ke][d.id].canvasContext[cord.name].beginPath();
|
||||
for (var b = 0; b < cord.points.length; b++){
|
||||
cord.points[b][0]=parseFloat(cord.points[b][0]);
|
||||
cord.points[b][1]=parseFloat(cord.points[b][1]);
|
||||
if(b===0){
|
||||
s.group[d.ke][d.id].canvasContext[cord.name].moveTo(cord.points[b][0],cord.points[b][1]);
|
||||
}else{
|
||||
s.group[d.ke][d.id].canvasContext[cord.name].lineTo(cord.points[b][0],cord.points[b][1]);
|
||||
}
|
||||
}
|
||||
s.group[d.ke][d.id].canvasContext[cord.name].clip();
|
||||
}
|
||||
}
|
||||
if(!s.group[d.ke][d.id].canvasContext[cord.name]){
|
||||
return
|
||||
}
|
||||
s.group[d.ke][d.id].canvasContext[cord.name].drawImage(d.image, 0, 0, d.width, d.height);
|
||||
if(!s.group[d.ke][d.id].blendRegion[cord.name]){
|
||||
s.group[d.ke][d.id].blendRegion[cord.name] = new Canvas(d.width, d.height);
|
||||
s.group[d.ke][d.id].blendRegionContext[cord.name] = s.group[d.ke][d.id].blendRegion[cord.name].getContext('2d');
|
||||
}
|
||||
var sourceData = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||
// create an image if the previous image doesn<73>t exist
|
||||
if (!s.group[d.ke][d.id].lastRegionImageData[cord.name]) s.group[d.ke][d.id].lastRegionImageData[cord.name] = s.group[d.ke][d.id].canvasContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||
// create a ImageData instance to receive the blended result
|
||||
var blendedData = s.group[d.ke][d.id].canvasContext[cord.name].createImageData(d.width, d.height);
|
||||
// blend the 2 images
|
||||
s.differenceAccuracy(blendedData.data,sourceData.data,s.group[d.ke][d.id].lastRegionImageData[cord.name].data);
|
||||
// draw the result in a canvas
|
||||
s.group[d.ke][d.id].blendRegionContext[cord.name].putImageData(blendedData, 0, 0);
|
||||
// store the current webcam image
|
||||
s.group[d.ke][d.id].lastRegionImageData[cord.name] = sourceData;
|
||||
blendedData = s.group[d.ke][d.id].blendRegionContext[cord.name].getImageData(0, 0, d.width, d.height);
|
||||
var i = 0;
|
||||
d.average = 0;
|
||||
while (i < (blendedData.data.length * 0.25)) {
|
||||
d.average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]);
|
||||
++i;
|
||||
}
|
||||
d.average = (d.average / (blendedData.data.length * 0.25))*10;
|
||||
if (d.average > parseFloat(cord.sensitivity)){
|
||||
if(d.mon.detector_use_detect_object==="1"&&d.mon.detector_second!=='1'){
|
||||
var buffer=s.group[d.ke][d.id].canvas[cord.name].toBuffer();
|
||||
s.detectObject(buffer,d,tx)
|
||||
}else{
|
||||
tx({f:'trigger',id:d.id,ke:d.ke,details:{split:true,plug:config.plug,name:cord.name,reason:'motion',confidence:d.average,frame:d.base64}})
|
||||
}
|
||||
}
|
||||
s.group[d.ke][d.id].canvasContext[cord.name].clearRect(0, 0, d.width, d.height);
|
||||
s.group[d.ke][d.id].blendRegionContext[cord.name].clearRect(0, 0, d.width, d.height);
|
||||
}
|
||||
function blobToBuffer (blob, cb) {
|
||||
if (typeof Blob === 'undefined' || !(blob instanceof Blob)) {
|
||||
throw new Error('first argument must be a Blob')
|
||||
}
|
||||
if (typeof cb !== 'function') {
|
||||
throw new Error('second argument must be a function')
|
||||
}
|
||||
|
||||
var reader = new FileReader()
|
||||
|
||||
function onLoadEnd (e) {
|
||||
reader.removeEventListener('loadend', onLoadEnd, false)
|
||||
if (e.error) cb(e.error)
|
||||
else cb(null, Buffer.from(reader.result))
|
||||
}
|
||||
|
||||
reader.addEventListener('loadend', onLoadEnd, false)
|
||||
reader.readAsArrayBuffer(blob)
|
||||
}
|
||||
function fastAbs(value) {
|
||||
return (value ^ (value >> 31)) - (value >> 31);
|
||||
}
|
||||
|
||||
function threshold(value) {
|
||||
return (value > 0x15) ? 0xFF : 0;
|
||||
}
|
||||
s.differenceAccuracy=function(target, data1, data2) {
|
||||
if (data1.length != data2.length) return null;
|
||||
var i = 0;
|
||||
while (i < (data1.length * 0.25)) {
|
||||
var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3;
|
||||
var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3;
|
||||
var diff = threshold(fastAbs(average1 - average2));
|
||||
target[4 * i] = diff;
|
||||
target[4 * i + 1] = diff;
|
||||
target[4 * i + 2] = diff;
|
||||
target[4 * i + 3] = 0xFF;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
s.checkAreas=function(d,tx){
|
||||
if(!s.group[d.ke][d.id].cords){
|
||||
if(!d.mon.cords){d.mon.cords={}}
|
||||
s.group[d.ke][d.id].cords=Object.values(d.mon.cords);
|
||||
}
|
||||
if(d.mon.detector_frame==='1'){
|
||||
d.mon.cords.frame={name:'FULL_FRAME',s:d.mon.detector_sensitivity,points:[[0,0],[0,d.image.height],[d.image.width,d.image.height],[d.image.width,0]]};
|
||||
s.group[d.ke][d.id].cords.push(d.mon.cords.frame);
|
||||
}
|
||||
for (var b = 0; b < s.group[d.ke][d.id].cords.length; b++){
|
||||
if(!s.group[d.ke][d.id].cords[b]){return}
|
||||
s.blenderRegion(d,s.group[d.ke][d.id].cords[b],tx)
|
||||
}
|
||||
delete(d.image)
|
||||
}
|
||||
|
||||
s.MainEventController=function(d,cn,tx){
|
||||
switch(d.f){
|
||||
case'refreshPlugins':
|
||||
s.findCascades(function(cascades){
|
||||
s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:cascades},to:'GRP_'+d.ke})
|
||||
})
|
||||
break;
|
||||
case'readPlugins':
|
||||
s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:s.cascadesInDir},to:'GRP_'+d.ke})
|
||||
break;
|
||||
case'init_plugin_as_host':
|
||||
if(!cn){
|
||||
console.log('No CN',d)
|
||||
return
|
||||
}
|
||||
if(d.key!==config.key){
|
||||
console.log(new Date(),'Plugin Key Mismatch',cn.request.connection.remoteAddress,d)
|
||||
cn.emit('init',{ok:false})
|
||||
cn.disconnect()
|
||||
}else{
|
||||
console.log(new Date(),'Plugin Connected to Client',cn.request.connection.remoteAddress)
|
||||
cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type})
|
||||
}
|
||||
break;
|
||||
case'init_monitor':
|
||||
if(s.group[d.ke]&&s.group[d.ke][d.id]){
|
||||
s.group[d.ke][d.id].canvas={}
|
||||
s.group[d.ke][d.id].canvasContext={}
|
||||
s.group[d.ke][d.id].blendRegion={}
|
||||
s.group[d.ke][d.id].blendRegionContext={}
|
||||
s.group[d.ke][d.id].lastRegionImageData={}
|
||||
s.group[d.ke][d.id].numberOfTriggers=0
|
||||
delete(s.group[d.ke][d.id].cords)
|
||||
delete(s.group[d.ke][d.id].buffer)
|
||||
}
|
||||
break;
|
||||
case'init_aws_push':
|
||||
// console.log('init_aws')
|
||||
s.group[d.ke][d.id].aws={links:[],complete:0,total:d.total,videos:[],tx:tx}
|
||||
break;
|
||||
case'frame':
|
||||
try{
|
||||
if(!s.group[d.ke]){
|
||||
s.group[d.ke]={}
|
||||
}
|
||||
if(!s.group[d.ke][d.id]){
|
||||
s.group[d.ke][d.id]={
|
||||
canvas:{},
|
||||
canvasContext:{},
|
||||
lastRegionImageData:{},
|
||||
blendRegion:{},
|
||||
blendRegionContext:{},
|
||||
}
|
||||
}
|
||||
if(!s.group[d.ke][d.id].buffer){
|
||||
s.group[d.ke][d.id].buffer=[d.frame];
|
||||
}else{
|
||||
s.group[d.ke][d.id].buffer.push(d.frame)
|
||||
}
|
||||
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||
s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer);
|
||||
try{
|
||||
d.mon.detector_cascades=JSON.parse(d.mon.detector_cascades)
|
||||
}catch(err){
|
||||
|
||||
}
|
||||
if(d.mon.detector_frame_save==="1"){
|
||||
d.base64=s.group[d.ke][d.id].buffer.toString('base64')
|
||||
}
|
||||
if(d.mon.detector_second==='1'&&d.objectOnly===true){
|
||||
s.detectObject(s.group[d.ke][d.id].buffer,d,tx)
|
||||
}else{
|
||||
if((d.mon.detector_pam !== '1' && d.mon.detector_use_motion === "1") || d.mon.detector_use_detect_object !== "1"){
|
||||
if((typeof d.mon.cords ==='string')&&d.mon.cords.trim()===''){
|
||||
d.mon.cords=[]
|
||||
}else{
|
||||
try{
|
||||
d.mon.cords=JSON.parse(d.mon.cords)
|
||||
}catch(err){
|
||||
// console.log('d.mon.cords',err,d)
|
||||
}
|
||||
}
|
||||
s.group[d.ke][d.id].cords=Object.values(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===''){
|
||||
s.systemLog('Must set detector image size')
|
||||
return
|
||||
}else{
|
||||
d.image.width=d.mon.detector_scale_x;
|
||||
d.image.height=d.mon.detector_scale_y;
|
||||
}
|
||||
d.width=d.image.width;
|
||||
d.height=d.image.height;
|
||||
d.image.onload = function() {
|
||||
s.checkAreas(d,tx);
|
||||
}
|
||||
d.image.src = s.group[d.ke][d.id].buffer;
|
||||
}else{
|
||||
s.detectObject(s.group[d.ke][d.id].buffer,d,tx)
|
||||
}
|
||||
}
|
||||
s.group[d.ke][d.id].buffer=null;
|
||||
}
|
||||
}catch(err){
|
||||
if(err){
|
||||
s.systemLog(err)
|
||||
delete(s.group[d.ke][d.id].buffer)
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
server.listen(config.hostPort);
|
||||
//web pages and plugin api
|
||||
app.get('/', function (req, res) {
|
||||
res.end('<b>'+config.plug+'</b> for Shinobi is running')
|
||||
});
|
||||
//Conector to Shinobi
|
||||
if(config.mode==='host'){
|
||||
//start plugin as host
|
||||
var io = require('socket.io')(server);
|
||||
io.attach(server);
|
||||
s.connectedClients={};
|
||||
io.on('connection', function (cn) {
|
||||
s.connectedClients[cn.id]={id:cn.id}
|
||||
s.connectedClients[cn.id].tx = function(data){
|
||||
data.pluginKey=config.key;data.plug=config.plug;
|
||||
return io.to(cn.id).emit('ocv',data);
|
||||
}
|
||||
cn.on('f',function(d){
|
||||
s.MainEventController(d,cn,s.connectedClients[cn.id].tx)
|
||||
});
|
||||
cn.on('disconnect',function(d){
|
||||
delete(s.connectedClients[cn.id])
|
||||
})
|
||||
});
|
||||
}else{
|
||||
//start plugin as client
|
||||
if(!config.host){config.host='localhost'}
|
||||
var io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master
|
||||
s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)}
|
||||
io.on('connect',function(d){
|
||||
s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type});
|
||||
})
|
||||
io.on('disconnect',function(d){
|
||||
io.connect();
|
||||
})
|
||||
io.on('f',function(d){
|
||||
s.MainEventController(d,null,s.cx)
|
||||
})
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"plug":"ComputerVision",
|
||||
"host":"localhost",
|
||||
"port":8080,
|
||||
"key":"UNIQUE KEY HERE",
|
||||
"computerVision":{
|
||||
"apiKey":"YOUR_KEY",
|
||||
"endpoint":"http://YOUR_ENDPOINT/analyze",
|
||||
"params":{
|
||||
"visualFeatures": "Categories,Description,Color",
|
||||
"details": "",
|
||||
"language": "en"
|
||||
}
|
||||
},
|
||||
"EmotionAPI":{
|
||||
"apiKey":"YOUR_KEY",
|
||||
"endpoint":"http://YOUR_ENDPOINT/recognize",
|
||||
"params":{}
|
||||
},
|
||||
"FaceAPI":{
|
||||
"apiKey":"YOUR_KEY",
|
||||
"endpoint":"http://YOUR_ENDPOINT/detect",
|
||||
"params":{
|
||||
"returnFaceId": "true",
|
||||
"returnFaceLandmarks": "false",
|
||||
"returnFaceAttributes": "age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
//
|
||||
// Shinobi - Microsoft Computer Vision Plugin
|
||||
// Copyright (C) 2016-2025 Moe Alam, moeiscool
|
||||
//
|
||||
process.on('uncaughtException', function (err) {
|
||||
console.error('uncaughtException',err);
|
||||
});
|
||||
var fs=require('fs');
|
||||
var exec = require('child_process').exec;
|
||||
//var http = require('http');
|
||||
var request = require('request');
|
||||
var moment = require('moment');
|
||||
var cognitive = require('cognitive-services');
|
||||
var config=require('./conf.json');
|
||||
if(config.systemLog===undefined){config.systemLog=true}
|
||||
s={
|
||||
group:{},
|
||||
dir:{
|
||||
cascades:__dirname+'/cascades/'
|
||||
},
|
||||
isWin:(process.platform==='win32')
|
||||
}
|
||||
//default stream folder check
|
||||
if(!config.streamDir){
|
||||
if(s.isWin===false){
|
||||
config.streamDir='/dev/shm'
|
||||
}else{
|
||||
config.streamDir=config.windowsTempDir
|
||||
}
|
||||
if(!fs.existsSync(config.streamDir)){
|
||||
config.streamDir=__dirname+'/streams/'
|
||||
}else{
|
||||
config.streamDir+='/streams/'
|
||||
}
|
||||
}
|
||||
s.dir.streams=config.streamDir;
|
||||
//streams dir
|
||||
if(!fs.existsSync(s.dir.streams)){
|
||||
fs.mkdirSync(s.dir.streams);
|
||||
}
|
||||
s.gid=function(x){
|
||||
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for( var i=0; i < x; i++ )
|
||||
t += p.charAt(Math.floor(Math.random() * p.length));
|
||||
return t;
|
||||
};
|
||||
s.systemLog=function(q,w,e){
|
||||
if(!w){w=''}
|
||||
if(!e){e=''}
|
||||
if(config.systemLog===true){
|
||||
return console.log(moment().format(),q,w,e)
|
||||
}
|
||||
}
|
||||
s.objectToParameter = function(obj){
|
||||
return Object.keys(obj).map(function(key) {
|
||||
return key + '=' + encodeURIComponent(obj[key]);
|
||||
}).join('&');
|
||||
}
|
||||
s.sendImageToMS=function(sourceImageUrl,API,callback){
|
||||
var URL = API.endpoint+'?'+s.objectToParameter(API.params)
|
||||
request(URL,{
|
||||
method: 'POST',
|
||||
headers:{
|
||||
"Ocp-Apim-Subscription-Key":API.apiKey
|
||||
},
|
||||
json: {
|
||||
url:sourceImageUrl
|
||||
}
|
||||
}, callback)
|
||||
}
|
||||
s.detectObject=function(buffer,d){
|
||||
var sourceImageUrl = 'http://184.105.6.43/'+s.api_key+'/jpeg/'+d.ke+'/'+d.id+'/s.jpg'
|
||||
// const client = new cognitive.computerVision({
|
||||
// apiKey: config.computerVision.apiKey,
|
||||
// endpoint: config.computerVision.endpoint
|
||||
// });
|
||||
// const parameters = {
|
||||
// "visualFeatures": "Categories,Tags,Description",
|
||||
// "details": "Celebrities,Landmarks"
|
||||
// };
|
||||
// const headers = {
|
||||
// 'Content-type': 'application/json'
|
||||
// };
|
||||
// const body = {
|
||||
// "url": sourceImageUrl
|
||||
// };
|
||||
//
|
||||
// client.analyzeImage({
|
||||
// parameters,
|
||||
// headers,
|
||||
// body
|
||||
// }).then((response) => {
|
||||
//// should(response).not.be.undefined();
|
||||
//// should(response).have.properties(["categories", "metadata", "requestId"]);
|
||||
// console.log(response)
|
||||
// }).catch((err) => {
|
||||
// console.log('Error',err)
|
||||
// });
|
||||
var responses = {}
|
||||
s.sendImageToMS(sourceImageUrl,config.computerVision,function(err,resp,body1){
|
||||
responses.computerVisionURL = body1
|
||||
s.sendImageToMS(sourceImageUrl,config.FaceAPI,function(err,resp,body2){
|
||||
responses.faceApiURL = body2
|
||||
s.sendImageToMS(sourceImageUrl,config.EmotionAPI,function(err,resp,body3){
|
||||
responses.EmotionAPI = body3
|
||||
console.log('responses',JSON.stringify(responses,null,3))
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
s.makeMonitorObject=function(d){
|
||||
if(!s.group[d.ke]){
|
||||
s.group[d.ke]={}
|
||||
}
|
||||
if(!s.group[d.ke][d.id]){
|
||||
s.group[d.ke][d.id]={
|
||||
port:null,
|
||||
countStarted:new Date()
|
||||
}
|
||||
}
|
||||
}
|
||||
io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master
|
||||
s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)}
|
||||
io.on('connect',function(d){
|
||||
s.cx({f:'init',plug:config.plug});
|
||||
})
|
||||
io.on('disconnect',function(d){
|
||||
io.connect()
|
||||
})
|
||||
io.on('f',function(d){
|
||||
switch(d.f){
|
||||
case'api_key':
|
||||
s.api_key=d.key
|
||||
break;
|
||||
case'init_monitor':
|
||||
if(s.group[d.ke]&&s.group[d.ke][d.id]){
|
||||
s.group[d.ke][d.id].buffer=null
|
||||
s.group[d.ke][d.id].countStarted=new Date()
|
||||
}
|
||||
s.makeMonitorObject(d)
|
||||
break;
|
||||
case'frame':
|
||||
d.details={}
|
||||
try{
|
||||
s.makeMonitorObject(d)
|
||||
if(!s.group[d.ke][d.id].buffer){
|
||||
s.group[d.ke][d.id].buffer=[d.frame];
|
||||
}else{
|
||||
s.group[d.ke][d.id].buffer.push(d.frame)
|
||||
}
|
||||
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||
if(d.mon.detector_frame_save==="1"){
|
||||
d.base64=s.group[d.ke][d.id].buffer.toString('base64')
|
||||
}
|
||||
if(d.mon.detector_scale_x&&d.mon.detector_scale_x!==''&&d.mon.detector_scale_y&&d.mon.detector_scale_y!==''){
|
||||
d.width=d.mon.detector_scale_x;
|
||||
d.height=d.mon.detector_scale_y;
|
||||
}else{
|
||||
d.width=640
|
||||
d.height=480
|
||||
}
|
||||
s.detectObject(Buffer.concat(s.group[d.ke][d.id].buffer),d)
|
||||
s.group[d.ke][d.id].buffer=null;
|
||||
}
|
||||
} catch(err){
|
||||
console.error(err)
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
2
plugins/opencv/.gitignore
vendored
Normal file
2
plugins/opencv/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
conf.json
|
||||
cascades
|
212
plugins/opencv/shinobi-opencv-no-motion.js
Normal file
212
plugins/opencv/shinobi-opencv-no-motion.js
Normal file
|
@ -0,0 +1,212 @@
|
|||
//
|
||||
// Shinobi - OpenCV Plugin
|
||||
// Copyright (C) 2016-2025 Moe Alam, moeiscool
|
||||
//
|
||||
// # Donate
|
||||
//
|
||||
// If you like what I am doing here and want me to continue please consider donating :)
|
||||
// PayPal : paypal@m03.a
|
||||
//
|
||||
process.on('uncaughtException', function (err) {
|
||||
console.error('uncaughtException',err);
|
||||
});
|
||||
var fs=require('fs');
|
||||
var cv=require('opencv');
|
||||
var exec = require('child_process').exec;
|
||||
var moment = require('moment');
|
||||
var config=require('./conf.json');
|
||||
if(config.systemLog===undefined){config.systemLog=true}
|
||||
s={
|
||||
group:{},
|
||||
dir:{
|
||||
cascades:__dirname+'/cascades/'
|
||||
},
|
||||
isWin:(process.platform==='win32')
|
||||
}
|
||||
//default stream folder check
|
||||
if(!config.streamDir){
|
||||
if(s.isWin===false){
|
||||
config.streamDir='/dev/shm'
|
||||
}else{
|
||||
config.streamDir=config.windowsTempDir
|
||||
}
|
||||
if(!fs.existsSync(config.streamDir)){
|
||||
config.streamDir=__dirname+'/streams/'
|
||||
}else{
|
||||
config.streamDir+='/streams/'
|
||||
}
|
||||
}
|
||||
s.dir.streams=config.streamDir;
|
||||
//streams dir
|
||||
if(!fs.existsSync(s.dir.streams)){
|
||||
fs.mkdirSync(s.dir.streams);
|
||||
}
|
||||
s.gid=function(x){
|
||||
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for( var i=0; i < x; i++ )
|
||||
t += p.charAt(Math.floor(Math.random() * p.length));
|
||||
return t;
|
||||
};
|
||||
s.systemLog=function(q,w,e){
|
||||
if(!w){w=''}
|
||||
if(!e){e=''}
|
||||
if(config.systemLog===true){
|
||||
return console.log(moment().format(),q,w,e)
|
||||
}
|
||||
}
|
||||
s.findCascades=function(callback){
|
||||
var tmp={};
|
||||
tmp.foundCascades=[];
|
||||
fs.readdir(s.dir.cascades,function(err,files){
|
||||
files.forEach(function(cascade,n){
|
||||
if(cascade.indexOf('.xml')>-1){
|
||||
tmp.foundCascades.push(cascade.replace('.xml',''))
|
||||
}
|
||||
})
|
||||
s.cascadesInDir=tmp.foundCascades;
|
||||
callback(tmp.foundCascades)
|
||||
})
|
||||
}
|
||||
s.findCascades(function(){
|
||||
//get cascades
|
||||
})
|
||||
s.detectObject=function(buffer,d){
|
||||
var keys = Object.keys(d.mon.detector_cascades);
|
||||
if(d.mon.detector_lisence_plate==="1"){
|
||||
if(!d.mon.detector_lisence_plate_country||d.mon.detector_lisence_plate_country===''){
|
||||
d.mon.detector_lisence_plate_country='us'
|
||||
}
|
||||
d.tmpFile=s.gid(5)+'.jpg'
|
||||
if(!fs.existsSync(s.dir.streams)){
|
||||
fs.mkdirSync(s.dir.streams);
|
||||
}
|
||||
d.dir=s.dir.streams+d.ke+'/'
|
||||
if(!fs.existsSync(d.dir)){
|
||||
fs.mkdirSync(d.dir);
|
||||
}
|
||||
d.dir=s.dir.streams+d.ke+'/'+d.id+'/'
|
||||
if(!fs.existsSync(d.dir)){
|
||||
fs.mkdirSync(d.dir);
|
||||
}
|
||||
fs.writeFile(d.dir+d.tmpFile,buffer,function(err){
|
||||
if(err) return s.systemLog(err);
|
||||
exec('alpr -j -c '+d.mon.detector_lisence_plate_country+' '+d.dir+d.tmpFile,{encoding:'utf8'},(err, scan, stderr) => {
|
||||
if(err){
|
||||
s.systemLog(err);
|
||||
}else{
|
||||
try{
|
||||
try{
|
||||
scan=JSON.parse(scan)
|
||||
}catch(err){
|
||||
if(!scan||!scan.results){
|
||||
return s.systemLog(scan,err);
|
||||
}
|
||||
}
|
||||
if(scan.results.length>0){
|
||||
scan.plates=[]
|
||||
scan.mats=[]
|
||||
scan.results.forEach(function(v){
|
||||
v.candidates.forEach(function(g,n){
|
||||
if(v.candidates[n].matches_template)
|
||||
delete(v.candidates[n].matches_template)
|
||||
})
|
||||
scan.plates.push({coordinates:v.coordinates,candidates:v.candidates,confidence:v.confidence,plate:v.plate})
|
||||
var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2));
|
||||
var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2))
|
||||
scan.mats.push({
|
||||
x:v.coordinates[0].x,
|
||||
y:v.coordinates[0].y,
|
||||
width:width,
|
||||
height:height,
|
||||
tag:v.plate
|
||||
})
|
||||
})
|
||||
tx({f:'trigger',id:d.id,ke:d.ke,details:{plug:config.plug,name:'licensePlate',reason:'object',matrices:scan.mats,confidence:d.average,imgHeight:d.mon.detector_scale_y,imgWidth:d.mon.detector_scale_x,frame:d.base64}})
|
||||
}
|
||||
}catch(err){
|
||||
s.systemLog(err);
|
||||
}
|
||||
}
|
||||
exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'})
|
||||
})
|
||||
})
|
||||
}
|
||||
if(keys.length===0){return false}
|
||||
cv.readImage(buffer, function(err,im){
|
||||
if(err){console.log(err);return false;}
|
||||
var width = im.width();
|
||||
var height = im.height();
|
||||
|
||||
if (width < 1 || height < 1) {
|
||||
throw new Error('Image has no size');
|
||||
}
|
||||
keys.forEach(function(v,n){
|
||||
im.detectObject(s.dir.cascades+v+'.xml',{}, function(err,mats){
|
||||
if(err){console.log(err);return false;}
|
||||
if(mats&&mats.length>0){
|
||||
s.cx({f:'trigger',id:d.id,ke:d.ke,details:{plug:config.plug,name:v,reason:'object',matrices:mats,confidence:d.average,imgHeight:height,imgWidth:width}})
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master
|
||||
s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)}
|
||||
io.on('connect',function(d){
|
||||
s.cx({f:'init',plug:config.plug});
|
||||
})
|
||||
io.on('disconnect',function(d){
|
||||
io.connect()
|
||||
})
|
||||
io.on('f',function(d){
|
||||
switch(d.f){
|
||||
case'refreshPlugins':
|
||||
s.findCascades(function(cascades){
|
||||
s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:cascades},to:'GRP_'+d.ke})
|
||||
})
|
||||
break;
|
||||
case'readPlugins':
|
||||
s.cx({f:'s.tx',data:{f:'detector_cascade_list',cascades:s.cascadesInDir},to:'GRP_'+d.ke})
|
||||
break;
|
||||
case'init_monitor':
|
||||
if(s.group[d.ke]&&s.group[d.ke][d.id]){
|
||||
s.group[d.ke][d.id].canvas={}
|
||||
s.group[d.ke][d.id].canvasContext={}
|
||||
s.group[d.ke][d.id].blendRegion={}
|
||||
s.group[d.ke][d.id].blendRegionContext={}
|
||||
s.group[d.ke][d.id].lastRegionImageData={}
|
||||
delete(s.group[d.ke][d.id].cords)
|
||||
delete(s.group[d.ke][d.id].buffer)
|
||||
}
|
||||
break;
|
||||
case'frame':
|
||||
d.details={}
|
||||
try{
|
||||
if(!s.group[d.ke]){
|
||||
s.group[d.ke]={}
|
||||
}
|
||||
if(!s.group[d.ke][d.id]){
|
||||
s.group[d.ke][d.id]={
|
||||
canvas:{},
|
||||
canvasContext:{},
|
||||
lastRegionImageData:{},
|
||||
blendRegion:{},
|
||||
blendRegionContext:{},
|
||||
}
|
||||
}
|
||||
if(!s.group[d.ke][d.id].buffer){
|
||||
s.group[d.ke][d.id].buffer=[d.frame];
|
||||
}else{
|
||||
s.group[d.ke][d.id].buffer.push(d.frame)
|
||||
}
|
||||
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||
s.group[d.ke][d.id].buffer=Buffer.concat(s.group[d.ke][d.id].buffer);
|
||||
s.detectObject(s.group[d.ke][d.id].buffer,d)
|
||||
s.group[d.ke][d.id].buffer=null;
|
||||
}
|
||||
} catch(err){
|
||||
console.error(err)
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
3
sql/.gitignore
vendored
3
sql/.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
monitors.sql
|
||||
users.sql
|
||||
users.sql
|
||||
shinobi.sqlite
|
20
sql/database.sql
Normal file
20
sql/database.sql
Normal file
|
@ -0,0 +1,20 @@
|
|||
-- --------------------------------------------------------
|
||||
-- Host: 192.168.88.58
|
||||
-- Server version: 5.7.17-0ubuntu0.16.04.1 - (Ubuntu)
|
||||
-- Server OS: Linux
|
||||
-- HeidiSQL Version: 9.3.0.4984
|
||||
-- --------------------------------------------------------
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
|
||||
-- Dumping database structure for ccio
|
||||
CREATE DATABASE IF NOT EXISTS `ccio` /*!40100 DEFAULT CHARACTER SET utf8 */;
|
||||
USE `ccio`;
|
||||
|
||||
-- Data exporting was unselected.
|
||||
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
@ -13,7 +13,7 @@
|
|||
/*!40000 ALTER TABLE `Users` DISABLE KEYS */;
|
||||
INSERT INTO `Users` (`ke`, `uid`, `auth`, `mail`, `pass`, `details`) VALUES
|
||||
('2Df5hBE', 'XDf5hB3', 'ec49f05c1ddc7d818c61b3343c98cbc6', 'ccio@m03.ca', '5f4dcc3b5aa765d61d8327deb882cf99', '{"days":"10"}');
|
||||
INSERT INTO `Monitors` (`mid`, `ke`, `name`, `shto`, `shfr`, `details`, `type`, `ext`, `protocol`, `host`, `path`, `port`, `fps`, `mode`, `width`, `height`) VALUES ('bunny', '2Df5hBE', 'Bunny', '[]', '[]', '{"fatal_max":"","notes":"","dir":"","rtsp_transport":"tcp","muser":"","mpass":"","port_force":"0","sfps":"","aduration":"1000000","probesize":"1000000","accelerator":"0","hwaccel":null,"hwaccel_vcodec":"","hwaccel_device":"","stream_type":"hls","stream_mjpeg_clients":"","stream_vcodec":"copy","stream_acodec":"no","hls_time":"","preset_stream":"","hls_list_size":"","signal_check":"","signal_check_log":null,"stream_quality":"","stream_fps":"1","stream_scale_x":"","stream_scale_y":"","rotate_stream":null,"svf":"","stream_timestamp":"0","stream_timestamp_font":"","stream_timestamp_font_size":"","stream_timestamp_color":"","stream_timestamp_box_color":"","stream_timestamp_x":"","stream_timestamp_y":"","stream_watermark":"0","stream_watermark_location":"","stream_watermark_position":null,"snap":"1","snap_fps":"","snap_scale_x":"","snap_scale_y":"","snap_vf":"","vcodec":"copy","crf":"","preset_record":"","acodec":"libvorbis","dqf":null,"cutoff":"10","rotate_record":null,"vf":"","timestamp":"1","timestamp_font":"","timestamp_font_size":"","timestamp_color":"","timestamp_box_color":"","timestamp_x":"","timestamp_y":"","watermark":null,"watermark_location":"","watermark_position":null,"cust_input":"","cust_snap":"","cust_detect":"","cust_stream":"","cust_stream_server":"","cust_record":"","custom_output":"","detector":"0","detector_webhook":null,"detector_webhook_url":"","detector_command_enable":null,"detector_command":"","detector_command_timeout":"","detector_lock_timeout":"","detector_save":null,"detector_frame_save":null,"detector_mail":null,"detector_mail_timeout":"","detector_record_method":null,"detector_trigger":null,"detector_trigger_record_fps":"","detector_timeout":"","watchdog_reset":null,"detector_delete_motionless_videos":null,"detector_send_frames":null,"detector_fps":"","detector_scale_x":"","detector_scale_y":"","detector_use_motion":null,"detector_use_detect_object":null,"detector_frame":null,"detector_sensitivity":"","cords":"","detector_lisence_plate":null,"detector_lisence_plate_country":null,"detector_notrigger":null,"detector_notrigger_mail":null,"detector_notrigger_timeout":"","control":"0","control_base_url":"","control_stop":null,"control_url_stop_timeout":"","control_url_center":"","control_url_left":"","control_url_left_stop":"","control_url_right":"","control_url_right_stop":"","control_url_up":"","control_url_up_stop":"","control_url_down":"","control_url_down_stop":"","control_url_enable_nv":"","control_url_disable_nv":"","control_url_zoom_out":"","control_url_zoom_out_stop":"","control_url_zoom_in":"","control_url_zoom_in_stop":"","groups":"","loglevel":"warning","sqllog":"0","detector_cascades":""}', 'mjpeg', 'mp4', 'http', 'came3.nkansai.ne.jp', '/nphMotionJpeg?Resolution=640x480&Quality=Motion', 81, 15, 'start', 640, 480);
|
||||
INSERT INTO `Monitors` (`mid`, `ke`, `name`, `shto`, `shfr`, `details`, `type`, `ext`, `protocol`, `host`, `path`, `port`, `fps`, `mode`, `width`, `height`) VALUES ('Demo', '2Df5hBE', 'Demo', '[]', '[]', '{"fatal_max":"","notes":"","dir":"","rtsp_transport":"tcp","muser":"","mpass":"","port_force":"0","sfps":"","aduration":"1000000","probesize":"1000000","accelerator":"0","hwaccel":null,"hwaccel_vcodec":"","hwaccel_device":"","stream_type":"hls","stream_mjpeg_clients":"","stream_vcodec":"copy","stream_acodec":"no","hls_time":"","preset_stream":"","hls_list_size":"","signal_check":"","signal_check_log":null,"stream_quality":"","stream_fps":"1","stream_scale_x":"","stream_scale_y":"","rotate_stream":null,"svf":"","stream_timestamp":"0","stream_timestamp_font":"","stream_timestamp_font_size":"","stream_timestamp_color":"","stream_timestamp_box_color":"","stream_timestamp_x":"","stream_timestamp_y":"","stream_watermark":"0","stream_watermark_location":"","stream_watermark_position":null,"snap":"1","snap_fps":"","snap_scale_x":"","snap_scale_y":"","snap_vf":"","vcodec":"copy","crf":"","preset_record":"","acodec":"libvorbis","dqf":null,"cutoff":"10","rotate_record":null,"vf":"","timestamp":"1","timestamp_font":"","timestamp_font_size":"","timestamp_color":"","timestamp_box_color":"","timestamp_x":"","timestamp_y":"","watermark":null,"watermark_location":"","watermark_position":null,"cust_input":"","cust_snap":"","cust_detect":"","cust_stream":"","cust_stream_server":"","cust_record":"","custom_output":"","detector":"0","detector_webhook":null,"detector_webhook_url":"","detector_command_enable":null,"detector_command":"","detector_command_timeout":"","detector_lock_timeout":"","detector_save":null,"detector_frame_save":null,"detector_mail":null,"detector_mail_timeout":"","detector_record_method":null,"detector_trigger":null,"detector_trigger_record_fps":"","detector_timeout":"","watchdog_reset":null,"detector_delete_motionless_videos":null,"detector_send_frames":null,"detector_fps":"","detector_scale_x":"","detector_scale_y":"","detector_use_motion":null,"detector_use_detect_object":null,"detector_frame":null,"detector_sensitivity":"","cords":"","detector_lisence_plate":null,"detector_lisence_plate_country":null,"detector_notrigger":null,"detector_notrigger_mail":null,"detector_notrigger_timeout":"","control":"0","control_base_url":"","control_stop":null,"control_url_stop_timeout":"","control_url_center":"","control_url_left":"","control_url_left_stop":"","control_url_right":"","control_url_right_stop":"","control_url_up":"","control_url_up_stop":"","control_url_down":"","control_url_down_stop":"","control_url_enable_nv":"","control_url_disable_nv":"","control_url_zoom_out":"","control_url_zoom_out_stop":"","control_url_zoom_in":"","control_url_zoom_in_stop":"","groups":"","loglevel":"warning","sqllog":"0","detector_cascades":""}', 'mjpeg', 'mp4', 'http', 'came3.nkansai.ne.jp', '/nphMotionJpeg?Resolution=640x480&Quality=Motion', 81, 15, 'start', 640, 480);
|
||||
/*!40000 ALTER TABLE `Users` ENABLE KEYS */;
|
||||
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||
|
|
|
@ -52,7 +52,7 @@ CREATE TABLE IF NOT EXISTS Monitors (
|
|||
name varchar(50) DEFAULT NULL,
|
||||
shto text,
|
||||
shfr text,
|
||||
details text,
|
||||
details longtext,
|
||||
type varchar(50) DEFAULT 'jpeg',
|
||||
ext varchar(50) DEFAULT 'webm',
|
||||
protocol varchar(50) DEFAULT 'http',
|
||||
|
@ -82,7 +82,7 @@ CREATE TABLE IF NOT EXISTS Users (
|
|||
auth varchar(50) DEFAULT NULL,
|
||||
mail varchar(100) DEFAULT NULL,
|
||||
pass varchar(100) DEFAULT NULL,
|
||||
details text,
|
||||
details longtext,
|
||||
CONSTRAINT mail UNIQUE (mail)
|
||||
) ;
|
||||
|
||||
|
|
54
tools/ffmpegToWeb.js
Normal file
54
tools/ffmpegToWeb.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Shinobi (http://shinobi.video) - FFMPEG H.264 over HTTP Test
|
||||
// How to Use
|
||||
// 1. Start with `node ffmpegToWeb.js`
|
||||
// 2. Get the IP address of the computer where you did step 1. Example : 127.0.0.1
|
||||
// 3. Open VLC and "Open Network Stream".
|
||||
// 4. Input the following without quotes : `http://127.0.0.1:8001` and start.
|
||||
|
||||
var child = require('child_process');
|
||||
var events = require('events');
|
||||
var spawn = child.spawn;
|
||||
var exec = child.exec;
|
||||
var Emitter = new events.EventEmitter().setMaxListeners(0)
|
||||
var config = {
|
||||
port:8001
|
||||
}
|
||||
//ffmpeg
|
||||
console.log('Starting FFMPEG')
|
||||
var ffmpeg = spawn('ffmpeg',('-rtsp_transport tcp -i rtsp://131.95.3.162/axis-media/media.3gp -f mpegts -c:v copy -an -').split(' '));
|
||||
ffmpeg.on('close', function (buffer) {
|
||||
console.log('ffmpeg died')
|
||||
})
|
||||
//ffmpeg.stderr.on('data', function (buffer) {
|
||||
// console.log(buffer.toString())
|
||||
//});
|
||||
ffmpeg.stdout.on('data', function (buffer) {
|
||||
Emitter.emit('data',buffer)
|
||||
});
|
||||
//web app
|
||||
console.log('Starting Express Web Server on Port '+config.port)
|
||||
var express = require('express')
|
||||
var app = express();
|
||||
var http = require('http')
|
||||
var httpServer = http.createServer(app);
|
||||
|
||||
app.get('/', function (req, res) {
|
||||
var contentWriter
|
||||
var date = new Date();
|
||||
res.writeHead(200, {
|
||||
'Date': date.toUTCString(),
|
||||
'Connection': 'close',
|
||||
'Cache-Control': 'no-cache',
|
||||
'Pragma': 'no-cache',
|
||||
'Content-Type': 'video/mp4',
|
||||
'Server': 'Shinobi H.264 Test Stream',
|
||||
});
|
||||
Emitter.on('data',contentWriter=function(buffer){
|
||||
res.write(buffer)
|
||||
})
|
||||
res.on('close', function () {
|
||||
Emitter.removeListener('data',contentWriter)
|
||||
})
|
||||
});
|
||||
|
||||
httpServer.listen(config.port);
|
Binary file not shown.
Before Width: | Height: | Size: 218 KiB After Width: | Height: | Size: 217 KiB |
|
@ -46,6 +46,11 @@
|
|||
<div><input class="form-control" name="name"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Retry Connection']%></span></div>
|
||||
<div><input class="form-control" detail="fatal_max" placeholder="10"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang["Number of Days to keep"]%> <%-lang["Videos"]%></span></div>
|
||||
<div><input class="form-control" detail="max_keep_days" placeholder="Default is global value"></div>
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default pull-left" data-dismiss="modal">Close</button>
|
||||
<div>
|
||||
<!-- <a class="btn btn-success edit_all"><%-lang['Edit Selected']%></a>-->
|
||||
<a class="btn btn-danger delete"><%-lang['Delete']%></a>
|
||||
<a class="btn btn-primary save_config"><%-lang['Export']%></a>
|
||||
<a class="btn btn-default import_config"><%-lang['Import']%></a>
|
||||
|
@ -36,113 +35,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--Multi Monitor Manager-->
|
||||
<!--
|
||||
<div class="modal medium fade dark" mid ke id="multi_mon_edit" tabindex="-1" role="dialog" aria-labelledby="multi_mon_editLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title" id="multi_mon_editLabel"><i class="fa fa-clone"></i> <%- lang['Monitors'] %></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table table-striped tableData">
|
||||
<thead></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default pull-left" data-dismiss="modal">Close</button>
|
||||
<div>
|
||||
<a class="btn btn-success save"><%-lang['Save']%></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
|
||||
//multiple monitor editor, multimonitoredit
|
||||
$.multimonedit={
|
||||
e:$('#multi_mon_edit'),
|
||||
|
||||
}
|
||||
|
||||
$.multimonedit.findFieldInDefintion = function(){
|
||||
$define['Monitor Settings']
|
||||
}
|
||||
$.multimonedit.submit = function(){
|
||||
|
||||
}
|
||||
$.multimonedit.refreshMonitors = function(){
|
||||
// $.get('/'+$user.auth_token+'/monitor/'+$user.ke,function(monitors){
|
||||
// $.multimonedit.monitorsList = monitors;
|
||||
// var selectedMonitors = $.multimonedit.selectedList;
|
||||
// $.each(monitors,function(n,monitor){
|
||||
// if(selectedMonitors[monitor.ke+monitor.mid]){
|
||||
// monitor.details = JSON.parse(monitor.details)
|
||||
// }
|
||||
// })
|
||||
// console.log(monitors)
|
||||
// })
|
||||
var tmp = '';
|
||||
var tmpHeader = '<tr>';
|
||||
$.each($.multimonedit.selectedList,function(n,monitor){
|
||||
var details = '';
|
||||
var detailsHeader = '';
|
||||
tmp += '<tr>';
|
||||
monitor.details = JSON.parse(monitor.details)
|
||||
var drawField = function(e){
|
||||
if(!e.attr){
|
||||
e.attr='name'
|
||||
}
|
||||
if(!e.value){
|
||||
e.value=''
|
||||
}
|
||||
return '<td><input class="form-control" '+e.attr+'='+e.name+' value="'+e.value+'" style="width:100px"></td>'
|
||||
}
|
||||
$.each(monitor,function(m,field){
|
||||
console.log(n)
|
||||
var drawHeader = function(mm){
|
||||
if(n === 0){
|
||||
return '<th>'+mm+'</th>'
|
||||
}
|
||||
}
|
||||
if(m === 'ke'){
|
||||
return
|
||||
}
|
||||
if(m === 'details'){
|
||||
$.each(field,function(k,detailField){
|
||||
detailsHeader += drawHeader(k)
|
||||
details += drawField({
|
||||
attr:'detail',
|
||||
name:k,
|
||||
value:detailField
|
||||
})
|
||||
})
|
||||
}else{
|
||||
tmpHeader += drawHeader(m)
|
||||
tmp += drawField({
|
||||
attr:'name',
|
||||
name:m,
|
||||
value:field
|
||||
})
|
||||
}
|
||||
})
|
||||
tmpHeader += detailsHeader;
|
||||
tmp += details;
|
||||
tmp += '</tr>';
|
||||
})
|
||||
tmpHeader += '</tr>';
|
||||
$.multimonedit.e.find('tbody').html(tmp)
|
||||
$.multimonedit.e.find('thead').html(tmpHeader)
|
||||
}
|
||||
$.multimonedit.e.on('shown.bs.modal', function() {
|
||||
$.multimonedit.refreshMonitors()
|
||||
})
|
||||
})
|
||||
</script>-->
|
||||
</div>
|
|
@ -137,7 +137,6 @@
|
|||
<li class="mdl-menu__item" system="jpegToggle"><div><i class="fa fa-file-image-o"></i><div><%- lang['JPEG Mode'] %></div></div></li>
|
||||
<li class="mdl-menu__item" system="switch" switch="monitorOrder" type="text"><div><i class="fa fa-sort"></i><div><%- lang['Order Streams'] %></div></div></li>
|
||||
<li class="mdl-menu__item" system="switch" switch="notifyHide" type="text"><div><i class="fa fa-exclamation-circle"></i><div><%- lang['Hide Notes'] %></div></div></li>
|
||||
<li class="mdl-menu__item" data-toggle="modal" data-target="#migrator"><div><i class="fa fa-clone"></i><div><%- lang['Migrator'] %></div></div></li>
|
||||
<li class="mdl-menu__item logout"><div><i class="fa fa-sign-out"></i><div><%- lang.Logout %></div></div></li>
|
||||
</ul>
|
||||
<div class="mdl-layout-spacer"></div>
|
||||
|
@ -173,7 +172,6 @@
|
|||
<% include blocks/monitoredit.ejs %>
|
||||
<% include blocks/probe.ejs %>
|
||||
<% include blocks/region.ejs %>
|
||||
<% include blocks/migrator.ejs %>
|
||||
<% include blocks/confirm.ejs %>
|
||||
<% if(config.DropboxAppKey){ %>
|
||||
<!--Dropbox Library, Change data-app-key to your app key. -->
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue