Merge branch 'dev' into 'master'
Tabantha Frontier See merge request Shinobi-Systems/Shinobi!49merge-requests/55/head^2
commit
8bccd65fa1
|
@ -27,7 +27,7 @@ if [ ! -e "./super.json" ]; then
|
||||||
fi
|
fi
|
||||||
echo "Shinobi - Run yum update"
|
echo "Shinobi - Run yum update"
|
||||||
sudo yum update -y
|
sudo yum update -y
|
||||||
sudo yum install make -y
|
sudo yum install make zip -y
|
||||||
echo "============="
|
echo "============="
|
||||||
echo "Shinobi - Do you want to Install FFMPEG?"
|
echo "Shinobi - Do you want to Install FFMPEG?"
|
||||||
echo "(y)es or (N)o"
|
echo "(y)es or (N)o"
|
||||||
|
@ -143,21 +143,14 @@ if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then
|
||||||
echo "====================================="
|
echo "====================================="
|
||||||
echo "====================================="
|
echo "====================================="
|
||||||
fi
|
fi
|
||||||
if [ ! "$sqliteormariadb" = "M" ] && [ ! "$sqliteormariadb" = "m" ]; then
|
echo "====================================="
|
||||||
echo "====================================="
|
echo "||===== Install Completed =====||"
|
||||||
echo "||===== Install Completed =====||"
|
echo "====================================="
|
||||||
echo "====================================="
|
echo "|| Login with the Superuser and create a new user!!"
|
||||||
echo "|| Login with the Superuser and create a new user!!"
|
echo "||==================================="
|
||||||
echo "||==================================="
|
echo "|| Open http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080/super in your web browser."
|
||||||
echo "|| Open http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080/super in your web browser."
|
echo "||==================================="
|
||||||
echo "||==================================="
|
echo "|| Default Superuser : admin@shinobi.video"
|
||||||
echo "|| Default Superuser : admin@shinobi.video"
|
echo "|| Default Password : admin"
|
||||||
echo "|| Default Password : admin"
|
echo "====================================="
|
||||||
echo "====================================="
|
echo "====================================="
|
||||||
echo "====================================="
|
|
||||||
else
|
|
||||||
echo "+=================================+"
|
|
||||||
echo "||===== Install Completed =====||"
|
|
||||||
echo "|| Access the main Shinobi panel at http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080 in your web browser."
|
|
||||||
echo "+=================================+"
|
|
||||||
fi
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Install prerequisites
|
||||||
|
DIR=`dirname $0`
|
||||||
|
INSTALLERS_DIR="$DIR"
|
||||||
|
echo "-----------------------------------"
|
||||||
|
if ! [ -x "$(command -v opencv_version)" ]; then
|
||||||
|
echo "Installing OpenCV"
|
||||||
|
dos2unix $INSTALLERS_DIR/opencv-cuda.sh
|
||||||
|
sh $INSTALLERS_DIR/opencv-cuda.sh
|
||||||
|
else
|
||||||
|
echo "OpenCV found... : $(opencv_version)"
|
||||||
|
fi
|
||||||
|
# this includes all the ones missing from OpenALPR's guide.
|
||||||
|
sudo apt install libtesseract-dev git cmake build-essential libleptonica-dev -y
|
||||||
|
sudo apt install liblog4cplus-dev libcurl3-dev -y
|
||||||
|
sudo apt install libleptonica-dev -y
|
||||||
|
sudo apt install libcurl4-openssl-dev -y
|
||||||
|
sudo apt install liblog4cplus-dev -y
|
||||||
|
sudo apt install beanstalkd -y
|
||||||
|
sudo apt install openjdk-8-jdk -y
|
||||||
|
|
||||||
|
# Clone the latest code from GitHub
|
||||||
|
git clone https://github.com/openalpr/openalpr.git
|
||||||
|
|
||||||
|
# Setup the build directory
|
||||||
|
cd openalpr/src
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
# setup the compile environment
|
||||||
|
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_INSTALL_SYSCONFDIR:PATH=/etc ..
|
||||||
|
|
||||||
|
# compile the library
|
||||||
|
make
|
||||||
|
|
||||||
|
# Install the binaries/libraries to your local system (prefix is /usr)
|
||||||
|
sudo make install
|
||||||
|
|
||||||
|
# Test the library
|
||||||
|
wget http://plates.openalpr.com/h786poj.jpg -O lp.jpg
|
||||||
|
alpr lp.jpg
|
||||||
|
rm lp.jpg
|
|
@ -1,4 +1,14 @@
|
||||||
# Install prerequisites
|
# Install prerequisites
|
||||||
|
DIR=`dirname $0`
|
||||||
|
INSTALLERS_DIR="$DIR"
|
||||||
|
echo "-----------------------------------"
|
||||||
|
if ! [ -x "$(command -v opencv_version)" ]; then
|
||||||
|
echo "Installing OpenCV"
|
||||||
|
dos2unix $INSTALLERS_DIR/opencv-cuda.sh
|
||||||
|
sh $INSTALLERS_DIR/opencv-cuda.sh
|
||||||
|
else
|
||||||
|
echo "OpenCV found... : $(opencv_version)"
|
||||||
|
fi
|
||||||
# this includes all the ones missing from OpenALPR's guide.
|
# this includes all the ones missing from OpenALPR's guide.
|
||||||
sudo apt install libtesseract-dev git cmake build-essential libleptonica-dev -y
|
sudo apt install libtesseract-dev git cmake build-essential libleptonica-dev -y
|
||||||
sudo apt install liblog4cplus-dev libcurl3-dev -y
|
sudo apt install liblog4cplus-dev libcurl3-dev -y
|
||||||
|
@ -28,4 +38,4 @@ sudo make install
|
||||||
# Test the library
|
# Test the library
|
||||||
wget http://plates.openalpr.com/h786poj.jpg -O lp.jpg
|
wget http://plates.openalpr.com/h786poj.jpg -O lp.jpg
|
||||||
alpr lp.jpg
|
alpr lp.jpg
|
||||||
rm lp.jpg
|
rm lp.jpg
|
||||||
|
|
|
@ -115,15 +115,6 @@ sudo chmod -R 755 .
|
||||||
touch INSTALL/installed.txt
|
touch INSTALL/installed.txt
|
||||||
dos2unix /home/Shinobi/INSTALL/shinobi
|
dos2unix /home/Shinobi/INSTALL/shinobi
|
||||||
ln -s /home/Shinobi/INSTALL/shinobi /usr/bin/shinobi
|
ln -s /home/Shinobi/INSTALL/shinobi /usr/bin/shinobi
|
||||||
if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then
|
|
||||||
echo "=====================================" > INSTALL/installed.txt
|
|
||||||
echo "======= Login Credentials =======" >> INSTALL/installed.txt
|
|
||||||
echo "|| Username : $userEmail" >> INSTALL/installed.txt
|
|
||||||
echo "|| Password : $userPasswordPlain" >> INSTALL/installed.txt
|
|
||||||
echo "|| API Key : $apiKey" >> INSTALL/installed.txt
|
|
||||||
echo "=====================================" >> INSTALL/installed.txt
|
|
||||||
echo "=====================================" >> INSTALL/installed.txt
|
|
||||||
fi
|
|
||||||
echo "Shinobi - Start Shinobi and set to start on boot?"
|
echo "Shinobi - Start Shinobi and set to start on boot?"
|
||||||
echo "(y)es or (N)o"
|
echo "(y)es or (N)o"
|
||||||
read startShinobi
|
read startShinobi
|
||||||
|
@ -134,31 +125,14 @@ if [ "$startShinobi" = "y" ] || [ "$startShinobi" = "Y" ]; then
|
||||||
sudo pm2 save
|
sudo pm2 save
|
||||||
sudo pm2 list
|
sudo pm2 list
|
||||||
fi
|
fi
|
||||||
if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then
|
echo "====================================="
|
||||||
echo "details written to INSTALL/installed.txt"
|
echo "||===== Install Completed =====||"
|
||||||
echo "====================================="
|
echo "====================================="
|
||||||
echo "======= Login Credentials ======="
|
echo "|| Login with the Superuser and create a new user!!"
|
||||||
echo "|| Username : $userEmail"
|
echo "||==================================="
|
||||||
echo "|| Password : $userPasswordPlain"
|
echo "|| Open http://$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1):8080/super in your web browser."
|
||||||
echo "|| API Key : $apiKey"
|
echo "||==================================="
|
||||||
echo "====================================="
|
echo "|| Default Superuser : admin@shinobi.video"
|
||||||
echo "====================================="
|
echo "|| Default Password : admin"
|
||||||
fi
|
echo "====================================="
|
||||||
if [ ! "$sqliteormariadb" = "M" ] && [ ! "$sqliteormariadb" = "m" ]; then
|
echo "====================================="
|
||||||
echo "====================================="
|
|
||||||
echo "||===== Install Completed =====||"
|
|
||||||
echo "====================================="
|
|
||||||
echo "|| Login with the Superuser and create a new user!!"
|
|
||||||
echo "||==================================="
|
|
||||||
echo "|| Open http://$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1):8080/super in your web browser."
|
|
||||||
echo "||==================================="
|
|
||||||
echo "|| Default Superuser : admin@shinobi.video"
|
|
||||||
echo "|| Default Password : admin"
|
|
||||||
echo "====================================="
|
|
||||||
echo "====================================="
|
|
||||||
else
|
|
||||||
echo "+=================================+"
|
|
||||||
echo "||===== Install Completed =====||"
|
|
||||||
echo "|| Access the main Shinobi panel at http://$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1):8080 in your web browser."
|
|
||||||
echo "+=================================+"
|
|
||||||
fi
|
|
||||||
|
|
114
INSTALL/shinobi
114
INSTALL/shinobi
|
@ -1,30 +1,68 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
installationDirectory="/home/Shinobi"
|
if [ ! -e "/etc/shinobisystems/path.txt" ]; then
|
||||||
if [ ! "$1" ]; then
|
installationDirectory="/home/Shinobi"
|
||||||
|
else
|
||||||
|
installationDirectory=$(cat /etc/shinobisystems/cctv.txt)
|
||||||
|
fi
|
||||||
|
cd $installationDirectory
|
||||||
|
currentBuild=$(git show --oneline -s)
|
||||||
|
gitOrigin=$(git remote show origin)
|
||||||
|
splitBuildString=($currentBuild)
|
||||||
|
currentCommitNumber=${splitBuildString[0]}
|
||||||
|
if [[ $gitOrigin == *'ShinobiCE'* ]]; then
|
||||||
|
repo="CE"
|
||||||
|
else
|
||||||
|
repo="Pro"
|
||||||
|
fi
|
||||||
|
if [[ $@ == *'help'* ]] || [ ! "$1" ]; then
|
||||||
echo "========================================================="
|
echo "========================================================="
|
||||||
echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!=="
|
echo "==!! Shinobi : The Open Source CCTV and NVR Solution !!=="
|
||||||
echo "========================================================="
|
echo "========================================================="
|
||||||
echo "You are missing function parameters."
|
if [ ! "$1" ]; then
|
||||||
echo "Example : shinobi [command] .."
|
echo "You are missing function parameters."
|
||||||
echo "Example : shinobi flush restart logs"
|
echo "Example : shinobi [command] .."
|
||||||
|
echo "Example : shinobi flush restart logs"
|
||||||
|
else
|
||||||
|
echo "Hello there! if you need support come on over"
|
||||||
|
echo "to the Shinobi Community Chat! :)"
|
||||||
|
echo "https://discordapp.com/invite/mdhmvuH/"
|
||||||
|
fi
|
||||||
echo "========================================================="
|
echo "========================================================="
|
||||||
echo "Your available options for COMMAND are as follows"
|
echo "Your available options for COMMAND are as follows"
|
||||||
echo "========================================================="
|
echo "========================================================="
|
||||||
echo "| start or s :"
|
echo "| start :"
|
||||||
echo "|--> Start camera.js and cron.js under PM2 (Process Manager)"
|
echo "|--> Start camera.js and cron.js under PM2 (Process Manager)"
|
||||||
echo "-"
|
echo "-"
|
||||||
echo "| restart or r :"
|
echo "| restart :"
|
||||||
echo "|--> Restart all processes running under the PM2 daemon."
|
echo "|--> Restart all processes running under the PM2 daemon."
|
||||||
echo "-"
|
echo "-"
|
||||||
echo "| stop, exit, or e :"
|
echo "| stop, exit :"
|
||||||
echo "|--> Stop all processes running under the PM2 daemon."
|
echo "|--> Stop all processes running under the PM2 daemon."
|
||||||
echo "-"
|
echo "-"
|
||||||
|
echo "| version :"
|
||||||
|
echo "|--> get version of your current build by git."
|
||||||
|
echo "-"
|
||||||
echo "| logs :"
|
echo "| logs :"
|
||||||
echo "|--> Get PM2 log stream with last 100 lines."
|
echo "|--> Get PM2 log stream with last 100 lines."
|
||||||
echo "-"
|
echo "-"
|
||||||
echo "| clear, flush, or f :"
|
echo "| update :"
|
||||||
|
echo "|--> Update via Git."
|
||||||
|
echo "-"
|
||||||
|
echo "| getMaster :"
|
||||||
|
echo "|--> Switch to the Master Branch (For Pro Repo only)."
|
||||||
|
echo "-"
|
||||||
|
echo "| getDev :"
|
||||||
|
echo "|--> Switch to the Development Branch (For Pro Repo only)."
|
||||||
|
echo "-"
|
||||||
|
echo "| clear, flush :"
|
||||||
echo "|--> Clear all PM2 logs."
|
echo "|--> Clear all PM2 logs."
|
||||||
echo "-"
|
echo "-"
|
||||||
|
echo "| bootupEnable :"
|
||||||
|
echo "|--> Start Shinobi on OS reboot."
|
||||||
|
echo "-"
|
||||||
|
echo "| bootupDisable :"
|
||||||
|
echo "|--> Disable starting Shinobi on OS reboot."
|
||||||
|
echo "-"
|
||||||
echo "| kill :"
|
echo "| kill :"
|
||||||
echo "|--> Stop the entire PM2 daemon."
|
echo "|--> Stop the entire PM2 daemon."
|
||||||
fi
|
fi
|
||||||
|
@ -34,7 +72,8 @@ fi
|
||||||
if [[ $@ == *'restart'* ]]; then
|
if [[ $@ == *'restart'* ]]; then
|
||||||
proccessAlive=$(pm2 list | grep camera)
|
proccessAlive=$(pm2 list | grep camera)
|
||||||
if [ "$proccessAlive" ]; then
|
if [ "$proccessAlive" ]; then
|
||||||
pm2 restart all
|
pm2 restart $installationDirectory/camera.js
|
||||||
|
pm2 restart $installationDirectory/cron.js
|
||||||
else
|
else
|
||||||
echo "Shinobi process is not running."
|
echo "Shinobi process is not running."
|
||||||
fi
|
fi
|
||||||
|
@ -58,11 +97,64 @@ fi
|
||||||
if [[ $@ == *'stop'* ]] || [[ $@ == *'exit'* ]]; then
|
if [[ $@ == *'stop'* ]] || [[ $@ == *'exit'* ]]; then
|
||||||
proccessAlive=$(pm2 list | grep camera)
|
proccessAlive=$(pm2 list | grep camera)
|
||||||
if [ "$proccessAlive" ]; then
|
if [ "$proccessAlive" ]; then
|
||||||
pm2 kill
|
pm2 stop $installationDirectory/camera.js
|
||||||
|
pm2 stop $installationDirectory/cron.js
|
||||||
else
|
else
|
||||||
echo "Shinobi process is not running."
|
echo "Shinobi process is not running."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
if [[ $@ == *'version'* ]]; then
|
||||||
|
echo "Build ID : $currentCommitNumber"
|
||||||
|
if [[ $repo == "Pro" ]]; then
|
||||||
|
echo "Repository : Shinobi Pro"
|
||||||
|
else
|
||||||
|
echo "Repository : Shinobi CE"
|
||||||
|
fi
|
||||||
|
echo $currentBuild
|
||||||
|
fi
|
||||||
|
if [[ $@ == *'bootupEnable'* ]] || [[ $@ == *'bootupenable'* ]]; then
|
||||||
|
pm2 startup
|
||||||
|
pm2 save
|
||||||
|
fi
|
||||||
|
if [[ $@ == *'bootupDisable'* ]] || [[ $@ == *'bootupdisable'* ]]; then
|
||||||
|
pm2 unstartup
|
||||||
|
pm2 save
|
||||||
|
fi
|
||||||
|
if [[ $@ == *'getDev'* ]] || [[ $@ == *'getdev'* ]]; then
|
||||||
|
if [[ $repo == "Pro" ]]; then
|
||||||
|
git checkout dev
|
||||||
|
echo "Shinobi - Restart Shinobi to make the changes take affect."
|
||||||
|
else
|
||||||
|
echo "Shinobi - Cannot use \"getDev\" with Shinobi CE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ $@ == *'getMaster'* ]] || [[ $@ == *'getmaster'* ]]; then
|
||||||
|
if [[ $repo == "Pro" ]]; then
|
||||||
|
git checkout master
|
||||||
|
echo "Shinobi - Restart Shinobi to make the changes take affect."
|
||||||
|
else
|
||||||
|
echo "Shinobi - Cannot use \"getMaster\" with Shinobi CE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ $@ == *'update'* ]]; then
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Are you sure you want to update? This will restart Shinobi."
|
||||||
|
echo "(y)es or (N)o"
|
||||||
|
read updateshinobi
|
||||||
|
if [ "$updateshinobi" = "y" ] || [ "$updateshinobi" = "Y" ]; then
|
||||||
|
echo "Beginning Update Process..."
|
||||||
|
pm2 stop $installationDirectory/camera.js
|
||||||
|
pm2 stop $installationDirectory/cron.js
|
||||||
|
npm install --unsafe-perm
|
||||||
|
npm audit fix --force
|
||||||
|
git reset --hard
|
||||||
|
git pull
|
||||||
|
pm2 start $installationDirectory/camera.js
|
||||||
|
pm2 start $installationDirectory/cron.js
|
||||||
|
else
|
||||||
|
echo "Cancelled Update Process."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if [[ $@ == *'kill'* ]]; then
|
if [[ $@ == *'kill'* ]]; then
|
||||||
pm2 kill
|
pm2 kill
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
var fs = require('fs');
|
||||||
|
var moment = require('moment');
|
||||||
|
var exec = require('child_process').exec;
|
||||||
|
var execSync = require('child_process').execSync;
|
||||||
|
s = {
|
||||||
|
isWin: (process.platform === 'win32' || process.platform === 'win64'),
|
||||||
|
mainDirectory: __dirname.split('/INSTALL')[0]
|
||||||
|
}
|
||||||
|
var createTerminalCommands = function(callback){
|
||||||
|
var next = function(){
|
||||||
|
if(callback)callback()
|
||||||
|
}
|
||||||
|
if(!s.isWin){
|
||||||
|
var etcPath = '/etc/shinobisystems/'
|
||||||
|
console.log('Creating "' + etcPath + '"...')
|
||||||
|
var createPathFile = function(){
|
||||||
|
var pathTxt = etcPath + 'cctv.txt'
|
||||||
|
console.log('Creating "' + pathTxt + '"...')
|
||||||
|
fs.writeFile(pathTxt,s.mainDirectory,function(err){
|
||||||
|
if(err)console.log(err)
|
||||||
|
fs.chmod(pathTxt,0o777,function(err){
|
||||||
|
if(err)console.log(err)
|
||||||
|
console.log('Linking "' + s.mainDirectory + '/INSTALL/shinobi" to "/usr/bin/shinobi"...')
|
||||||
|
fs.symlink(s.mainDirectory + '/INSTALL/shinobi', '/usr/bin/shinobi', next)
|
||||||
|
console.log('You can now use `shinobi` in terminal.')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fs.stat(etcPath,function(err,stat){
|
||||||
|
if(!err && stat){
|
||||||
|
createPathFile()
|
||||||
|
}else{
|
||||||
|
fs.mkdir(etcPath,createPathFile)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
//no commands for windows yet
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createTerminalCommands()
|
|
@ -30,12 +30,17 @@ if [ ! -e "./super.json" ]; then
|
||||||
echo "* You can edit these settings in \"super.json\" located in the Shinobi directory."
|
echo "* You can edit these settings in \"super.json\" located in the Shinobi directory."
|
||||||
sudo cp super.sample.json super.json
|
sudo cp super.sample.json super.json
|
||||||
fi
|
fi
|
||||||
|
if ! [ -x "$(command -v ifconfig)" ]; then
|
||||||
|
echo "============="
|
||||||
|
echo "Shinobi - Installing Net-Tools"
|
||||||
|
sudo apt install net-tools -y
|
||||||
|
fi
|
||||||
if ! [ -x "$(command -v node)" ]; then
|
if ! [ -x "$(command -v node)" ]; then
|
||||||
echo "============="
|
echo "============="
|
||||||
echo "Shinobi - Installing Node.js"
|
echo "Shinobi - Installing Node.js"
|
||||||
wget https://deb.nodesource.com/setup_9.x
|
wget https://deb.nodesource.com/setup_8.x
|
||||||
chmod +x setup_9.x
|
chmod +x setup_8.x
|
||||||
./setup_9.x
|
./setup_8.x
|
||||||
sudo apt install nodejs -y
|
sudo apt install nodejs -y
|
||||||
else
|
else
|
||||||
echo "Node.js Found..."
|
echo "Node.js Found..."
|
||||||
|
@ -44,7 +49,7 @@ fi
|
||||||
if ! [ -x "$(command -v npm)" ]; then
|
if ! [ -x "$(command -v npm)" ]; then
|
||||||
sudo apt install npm -y
|
sudo apt install npm -y
|
||||||
fi
|
fi
|
||||||
sudo apt install make -y
|
sudo apt install make zip -y
|
||||||
if ! [ -x "$(command -v ffmpeg)" ]; then
|
if ! [ -x "$(command -v ffmpeg)" ]; then
|
||||||
if [ "$getubuntuversion" = "16" ] || [ "$getubuntuversion" < "16" ]; then
|
if [ "$getubuntuversion" = "16" ] || [ "$getubuntuversion" < "16" ]; then
|
||||||
echo "============="
|
echo "============="
|
||||||
|
@ -132,21 +137,14 @@ if [ "$startShinobi" = "y" ] || [ "$startShinobi" = "y" ]; then
|
||||||
sudo pm2 save
|
sudo pm2 save
|
||||||
sudo pm2 list
|
sudo pm2 list
|
||||||
fi
|
fi
|
||||||
if [ ! "$sqliteormariadb" = "M" ] && [ ! "$sqliteormariadb" = "m" ]; then
|
echo "====================================="
|
||||||
echo "====================================="
|
echo "||===== Install Completed =====||"
|
||||||
echo "||===== Install Completed =====||"
|
echo "====================================="
|
||||||
echo "====================================="
|
echo "|| Login with the Superuser and create a new user!!"
|
||||||
echo "|| Login with the Superuser and create a new user!!"
|
echo "||==================================="
|
||||||
echo "||==================================="
|
echo "|| Open http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080/super in your web browser."
|
||||||
echo "|| Open http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080/super in your web browser."
|
echo "||==================================="
|
||||||
echo "||==================================="
|
echo "|| Default Superuser : admin@shinobi.video"
|
||||||
echo "|| Default Superuser : admin@shinobi.video"
|
echo "|| Default Password : admin"
|
||||||
echo "|| Default Password : admin"
|
echo "====================================="
|
||||||
echo "====================================="
|
echo "====================================="
|
||||||
echo "====================================="
|
|
||||||
else
|
|
||||||
echo "+=================================+"
|
|
||||||
echo "||===== Install Completed =====||"
|
|
||||||
echo "|| Access the main Shinobi panel at http://$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080 in your web browser."
|
|
||||||
echo "+=================================+"
|
|
||||||
fi
|
|
||||||
|
|
|
@ -26,7 +26,9 @@ loadLib('codeTester')(s,config,lang,io)
|
||||||
//basic functions
|
//basic functions
|
||||||
loadLib('basic')(s,config)
|
loadLib('basic')(s,config)
|
||||||
//video processing engine
|
//video processing engine
|
||||||
loadLib('ffmpeg')(s,config,function(){
|
loadLib('ffmpeg')(s,config,function(ffmpeg){
|
||||||
|
//ffmpeg coProcessor
|
||||||
|
loadLib('ffmpegCoProcessor')(s,config,lang,ffmpeg)
|
||||||
//database connection : mysql, sqlite3..
|
//database connection : mysql, sqlite3..
|
||||||
loadLib('sql')(s,config)
|
loadLib('sql')(s,config)
|
||||||
//working directories : videos, streams, fileBin..
|
//working directories : videos, streams, fileBin..
|
||||||
|
@ -67,6 +69,8 @@ loadLib('ffmpeg')(s,config,function(){
|
||||||
loadLib('notification')(s,config,lang)
|
loadLib('notification')(s,config,lang)
|
||||||
//custom module loader
|
//custom module loader
|
||||||
loadLib('customAutoLoad')(s,config,lang,app,io)
|
loadLib('customAutoLoad')(s,config,lang,app,io)
|
||||||
|
//scheduling engine
|
||||||
|
loadLib('scheduler')(s,config,lang,app,io)
|
||||||
//on-start actions, daemon(s) starter
|
//on-start actions, daemon(s) starter
|
||||||
loadLib('startup')(s,config,lang)
|
loadLib('startup')(s,config,lang)
|
||||||
})
|
})
|
||||||
|
|
|
@ -34,6 +34,10 @@
|
||||||
"API": "API",
|
"API": "API",
|
||||||
"ONVIF": "ONVIF",
|
"ONVIF": "ONVIF",
|
||||||
"FFprobe": "Probe",
|
"FFprobe": "Probe",
|
||||||
|
"Monitor States": "Monitor States",
|
||||||
|
"Schedule": "Schedule",
|
||||||
|
"Schedules": "Schedules",
|
||||||
|
"Monitor States and Schedules": "Monitor States and Schedules",
|
||||||
"Filters": "Filters",
|
"Filters": "Filters",
|
||||||
"Full URL Path": "Full URL Path",
|
"Full URL Path": "Full URL Path",
|
||||||
"Logs": "Logs",
|
"Logs": "Logs",
|
||||||
|
@ -116,6 +120,8 @@
|
||||||
"Can View Videos and Events": "Can View Videos and Events",
|
"Can View Videos and Events": "Can View Videos and Events",
|
||||||
"Can Delete Videos and Events": "Can Delete Videos and Events",
|
"Can Delete Videos and Events": "Can Delete Videos and Events",
|
||||||
"Saved Filters": "Saved Filters",
|
"Saved Filters": "Saved Filters",
|
||||||
|
"Saved Presets": "Saved Presets",
|
||||||
|
"Saved Schedules": "Saved Schedules",
|
||||||
"Filter Name": "Filter Name",
|
"Filter Name": "Filter Name",
|
||||||
"Find Where": "Find Where",
|
"Find Where": "Find Where",
|
||||||
"Reason": "Reason",
|
"Reason": "Reason",
|
||||||
|
@ -288,9 +294,15 @@
|
||||||
"DeleteMonitorText": "Do you want to delete this monitor? You cannot recover it. You can choose for the files to remain in the filesystem. If you choose to recreate a monitor with the same ID the videos and events will become visible in the dashboard.",
|
"DeleteMonitorText": "Do you want to delete this monitor? You cannot recover it. You can choose for the files to remain in the filesystem. If you choose to recreate a monitor with the same ID the videos and events will become visible in the dashboard.",
|
||||||
"DeleteMonitorsText": "Do you want to delete these monitors? You cannot recover them. You can choose to keep the files for these IDs in the filesystem. If you choose to recreate a monitor with one of the IDs the videos and events will become visible in the dashboard.",
|
"DeleteMonitorsText": "Do you want to delete these monitors? You cannot recover them. You can choose to keep the files for these IDs in the filesystem. If you choose to recreate a monitor with one of the IDs the videos and events will become visible in the dashboard.",
|
||||||
"Invalid JSON": "Invalid JSON",
|
"Invalid JSON": "Invalid JSON",
|
||||||
|
"Invalid Data": "Invalid Data",
|
||||||
|
"Name cannot be empty.": "Name cannot be empty.",
|
||||||
|
"Start Time cannot be empty.": "Start Time cannot be empty.",
|
||||||
|
"Must be atleast one row": "Must be atleast one row",
|
||||||
"InvalidJSONText": "Please ensure this is a valid JSON string for Shinobi monitor configuration.",
|
"InvalidJSONText": "Please ensure this is a valid JSON string for Shinobi monitor configuration.",
|
||||||
"Passwords don't match": "Passwords don't match",
|
"Passwords don't match": "Passwords don't match",
|
||||||
"Email address is in use.": "Email address is in use.",
|
"Email address is in use.": "Email address is in use.",
|
||||||
|
"Group Key is in use.": "Group Key is in use.",
|
||||||
|
"Create Sub-Accounts at /admin": "Create Sub-Accounts at /admin",
|
||||||
"No Events found for this video": "No Events found for this video",
|
"No Events found for this video": "No Events found for this video",
|
||||||
"Video and Time Span (Minutes)": "Video and Time Span (Minutes)",
|
"Video and Time Span (Minutes)": "Video and Time Span (Minutes)",
|
||||||
"Video Length (minutes) and Motion Count per video": "Video Length (minutes) and Motion Count per video",
|
"Video Length (minutes) and Motion Count per video": "Video Length (minutes) and Motion Count per video",
|
||||||
|
@ -329,6 +341,10 @@
|
||||||
"Filter for Objects only": "Filter for Objects only",
|
"Filter for Objects only": "Filter for Objects only",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
"Detector": "Detector",
|
"Detector": "Detector",
|
||||||
|
"Audio Detector": "Audio Detector",
|
||||||
|
"Audio Detection": "Audio Detection",
|
||||||
|
"Minimum dB": "Minimum dB",
|
||||||
|
"Maximum dB": "Maximum dB",
|
||||||
"Connected": "Connected",
|
"Connected": "Connected",
|
||||||
"Not Saved": "Not Saved",
|
"Not Saved": "Not Saved",
|
||||||
"Not Connected": "Not Connected",
|
"Not Connected": "Not Connected",
|
||||||
|
@ -400,7 +416,17 @@
|
||||||
"Image Height": "Image Height",
|
"Image Height": "Image Height",
|
||||||
"Record File Type": "Record File Type",
|
"Record File Type": "Record File Type",
|
||||||
"Video Codec": "Video Codec",
|
"Video Codec": "Video Codec",
|
||||||
|
"Delete Monitor States Preset": "Delete Monitor States Preset",
|
||||||
|
"Delete Monitor State?": "Delete Monitor State",
|
||||||
|
"deleteMonitorStateText1": "Do you want to delete this Monitor States Preset?",
|
||||||
|
"deleteMonitorStateText2": "Do you want to delete this Monitor's Preset?",
|
||||||
|
"Search Images": "Search Images",
|
||||||
|
"Launch in New Window": "Launch in New Window",
|
||||||
"Preset": "Preset",
|
"Preset": "Preset",
|
||||||
|
"Presets": "Presets",
|
||||||
|
"possibleInternalError": "Possible Internal Error",
|
||||||
|
"sizePurgeLockedText": "The Size Purge Lock (deleteOverMax) appears to have failed to unlock. Unlocking now...",
|
||||||
|
"Use coProcessor": "Use coProcessor",
|
||||||
"Audio Codec": "Audio Codec",
|
"Audio Codec": "Audio Codec",
|
||||||
"Video Record Rate": "Video Record Rate <small>(FPS)</small>",
|
"Video Record Rate": "Video Record Rate <small>(FPS)</small>",
|
||||||
"Record Width": "Record Width",
|
"Record Width": "Record Width",
|
||||||
|
@ -415,6 +441,7 @@
|
||||||
"Stream to YouTube": "Stream to YouTube",
|
"Stream to YouTube": "Stream to YouTube",
|
||||||
"Stream to YouTube Flags": "Stream to YouTube Flags",
|
"Stream to YouTube Flags": "Stream to YouTube Flags",
|
||||||
"Recording Flags": "Recording Flags",
|
"Recording Flags": "Recording Flags",
|
||||||
|
"Traditional Recording Flags": "Traditional Recording Flags",
|
||||||
"Output Method": "Output Method",
|
"Output Method": "Output Method",
|
||||||
"Webhook": "Webhook",
|
"Webhook": "Webhook",
|
||||||
"Event Webhook Error": "Event Webhook Error",
|
"Event Webhook Error": "Event Webhook Error",
|
||||||
|
@ -426,6 +453,8 @@
|
||||||
"Save Events to SQL": "Save Events to SQL",
|
"Save Events to SQL": "Save Events to SQL",
|
||||||
"Email on Trigger": "Email on Trigger <small>Emails go to the main account holder's login address.</small>",
|
"Email on Trigger": "Email on Trigger <small>Emails go to the main account holder's login address.</small>",
|
||||||
"Attach Video Clip": "Attach Video Clip",
|
"Attach Video Clip": "Attach Video Clip",
|
||||||
|
"Error While Decoding": "Error While Decoding",
|
||||||
|
"ErrorWhileDecodingText": "Your hardware may have an unstable connection to the network. Check your network connections.",
|
||||||
"Discord": "Discord",
|
"Discord": "Discord",
|
||||||
"Discord Alert on Trigger": "Discord Alert on Trigger",
|
"Discord Alert on Trigger": "Discord Alert on Trigger",
|
||||||
"Allow Next Email": "Allow Next Email <small>in Minutes</small>",
|
"Allow Next Email": "Allow Next Email <small>in Minutes</small>",
|
||||||
|
@ -642,6 +671,7 @@
|
||||||
"Monitor mode is already": "Monitor mode is already",
|
"Monitor mode is already": "Monitor mode is already",
|
||||||
"Monitor or Key does not exist.": "Monitor or Key does not exist.",
|
"Monitor or Key does not exist.": "Monitor or Key does not exist.",
|
||||||
"No Group with this key exists": "No Group with this key exists",
|
"No Group with this key exists": "No Group with this key exists",
|
||||||
|
"Success": "Success",
|
||||||
"Trigger Successful": "Trigger Successful",
|
"Trigger Successful": "Trigger Successful",
|
||||||
"No such file": "No such file",
|
"No such file": "No such file",
|
||||||
"h265BrowserText1": "If you are trying to play an H.265 file, you may need to download it and open it in another application like VLC.",
|
"h265BrowserText1": "If you are trying to play an H.265 file, you may need to download it and open it in another application like VLC.",
|
||||||
|
@ -666,6 +696,10 @@
|
||||||
"Inserted State Configuration": "Inserted State Configuration",
|
"Inserted State Configuration": "Inserted State Configuration",
|
||||||
"Edited State Configuration": "Edited State Configuration",
|
"Edited State Configuration": "Edited State Configuration",
|
||||||
"Deleted State Configuration": "Deleted State Configuration",
|
"Deleted State Configuration": "Deleted State Configuration",
|
||||||
|
"Schedule Configuration Not Found": "Schedule Configuration Not Found",
|
||||||
|
"Inserted Schedule Configuration": "Inserted Schedule Configuration",
|
||||||
|
"Edited Schedule Configuration": "Edited Schedule Configuration",
|
||||||
|
"Deleted Schedule Configuration": "Deleted Schedule Configuration",
|
||||||
"Dashboard Language": "Dashboard Language",
|
"Dashboard Language": "Dashboard Language",
|
||||||
"Form Data Not Found": "Form Data Not Found",
|
"Form Data Not Found": "Form Data Not Found",
|
||||||
"File Not Found": "File Not Found",
|
"File Not Found": "File Not Found",
|
||||||
|
@ -777,6 +811,11 @@
|
||||||
"RTMP Stream":"RTMP Stream",
|
"RTMP Stream":"RTMP Stream",
|
||||||
"Stream Channel":"Stream Channel",
|
"Stream Channel":"Stream Channel",
|
||||||
"Confidence":"Confidence",
|
"Confidence":"Confidence",
|
||||||
|
"Trainer Engine":"Trainer Engine",
|
||||||
|
"Train":"Train",
|
||||||
|
"TrainConfirm":"Are you sure you want to begin training? This can take more than 12 hours with over 500 images. This will consume a large amount of resources, like RAM or CPU.",
|
||||||
|
"Batch":"Batch",
|
||||||
|
"Subdivision":"Subdivision",
|
||||||
"Map":"Map",
|
"Map":"Map",
|
||||||
"Add Map":"Add Map",
|
"Add Map":"Add Map",
|
||||||
"Add Input Feed":"Add Input Feed",
|
"Add Input Feed":"Add Input Feed",
|
||||||
|
@ -792,6 +831,7 @@
|
||||||
"TV Channel ID":"TV Channel ID",
|
"TV Channel ID":"TV Channel ID",
|
||||||
"TV Channel Group":"TV Channel Group",
|
"TV Channel Group":"TV Channel Group",
|
||||||
"Emotion Average":"Emotion Average",
|
"Emotion Average":"Emotion Average",
|
||||||
|
"Require Object to be in Region":"Require Object to be in Region",
|
||||||
"Show Regions of Interest":"Show Regions of Interest",
|
"Show Regions of Interest":"Show Regions of Interest",
|
||||||
"Confidence of Detection":"Confidence of Detection",
|
"Confidence of Detection":"Confidence of Detection",
|
||||||
"Edit Selected":"Edit Selected",
|
"Edit Selected":"Edit Selected",
|
||||||
|
|
|
@ -12,7 +12,7 @@ module.exports = function(s,config){
|
||||||
if(s.isWin===true){
|
if(s.isWin===true){
|
||||||
cmd = "Taskkill /IM ffmpeg.exe /F"
|
cmd = "Taskkill /IM ffmpeg.exe /F"
|
||||||
}else{
|
}else{
|
||||||
cmd = "ps aux | grep -ie ffmpeg | awk '{print $2}' | xargs kill -9"
|
cmd = "pkill -9 ffmpeg"
|
||||||
}
|
}
|
||||||
exec(cmd,{detached: true})
|
exec(cmd,{detached: true})
|
||||||
};
|
};
|
||||||
|
@ -33,7 +33,7 @@ module.exports = function(s,config){
|
||||||
s.parseJSON = function(string){
|
s.parseJSON = function(string){
|
||||||
var parsed
|
var parsed
|
||||||
try{
|
try{
|
||||||
string = JSON.parse(string)
|
parsed = JSON.parse(string)
|
||||||
}catch(err){
|
}catch(err){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -226,4 +226,19 @@ module.exports = function(s,config){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s.createTimeout = function(timeoutVar,timeoutLength,defaultLength,multiplier,callback){
|
||||||
|
var theTimeout
|
||||||
|
if(!multiplier)multiplier = 1000 * 60
|
||||||
|
if(!timeoutLength || timeoutLength === ''){
|
||||||
|
theTimeout = defaultLength
|
||||||
|
}else{
|
||||||
|
theTimeout = parseFloat(timeoutLength) * multiplier
|
||||||
|
}
|
||||||
|
clearTimeout(timeoutVar)
|
||||||
|
timeoutVar = setTimeout(function(){
|
||||||
|
clearTimeout(timeoutVar)
|
||||||
|
delete(timeoutVar)
|
||||||
|
if(callback)callback()
|
||||||
|
},theTimeout)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,134 @@
|
||||||
var fs = require('fs')
|
var fs = require('fs')
|
||||||
|
var express = require('express')
|
||||||
module.exports = function(s,config,lang,app,io){
|
module.exports = function(s,config,lang,app,io){
|
||||||
var checkFolder = function(folderName){
|
s.customAutoLoadModules = {}
|
||||||
var folderPath = __dirname + '/' + folderName
|
s.customAutoLoadTree = {
|
||||||
fs.readdir(folderPath,function(err,folderContents){
|
pages: [],
|
||||||
if(!err && folderContents){
|
PageBlocks: [],
|
||||||
folderContents.forEach(function(filename){
|
LibsJs: [],
|
||||||
if(filename.indexOf('.js') > -1){
|
LibsCss: [],
|
||||||
var customModulePath = folderPath + '/' + filename
|
adminPageBlocks: [],
|
||||||
|
adminLibsJs: [],
|
||||||
|
adminLibsCss: [],
|
||||||
|
superPageBlocks: [],
|
||||||
|
superLibsJs: [],
|
||||||
|
superLibsCss: []
|
||||||
|
}
|
||||||
|
var folderPath = __dirname + '/customAutoLoad'
|
||||||
|
var search = function(searchFor,searchIn){return searchIn.indexOf(searchFor) > -1}
|
||||||
|
fs.readdir(folderPath,function(err,folderContents){
|
||||||
|
if(!err && folderContents){
|
||||||
|
folderContents.forEach(function(filename){
|
||||||
|
s.customAutoLoadModules[filename] = {}
|
||||||
|
var customModulePath = folderPath + '/' + filename
|
||||||
|
if(filename.indexOf('.js') > -1){
|
||||||
|
s.customAutoLoadModules[filename].type = 'file'
|
||||||
|
try{
|
||||||
|
require(customModulePath)(s,config,lang,app,io)
|
||||||
|
}catch(err){
|
||||||
|
console.log('Failed to Load Module : ' + filename)
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(fs.lstatSync(customModulePath).isDirectory()){
|
||||||
|
s.customAutoLoadModules[filename].type = 'folder'
|
||||||
try{
|
try{
|
||||||
require(customModulePath)(s,config,lang,app,io)
|
require(customModulePath)(s,config,lang,app,io)
|
||||||
|
fs.readdir(customModulePath,function(err,folderContents){
|
||||||
|
folderContents.forEach(function(name){
|
||||||
|
switch(name){
|
||||||
|
case'web':
|
||||||
|
var webFolder = s.checkCorrectPathEnding(customModulePath) + 'web/'
|
||||||
|
fs.readdir(webFolder,function(err,webFolderContents){
|
||||||
|
webFolderContents.forEach(function(name){
|
||||||
|
switch(name){
|
||||||
|
case'libs':
|
||||||
|
case'pages':
|
||||||
|
if(name === 'libs'){
|
||||||
|
if(config.webPaths.home !== '/'){
|
||||||
|
app.use('/libs',express.static(webFolder + '/libs'))
|
||||||
|
}
|
||||||
|
app.use(s.checkCorrectPathEnding(config.webPaths.home)+'libs',express.static(webFolder + '/libs'))
|
||||||
|
app.use(s.checkCorrectPathEnding(config.webPaths.admin)+'libs',express.static(webFolder + '/libs'))
|
||||||
|
app.use(s.checkCorrectPathEnding(config.webPaths.super)+'libs',express.static(webFolder + '/libs'))
|
||||||
|
}
|
||||||
|
var libFolder = webFolder + name + '/'
|
||||||
|
fs.readdir(libFolder,function(err,webFolderContents){
|
||||||
|
webFolderContents.forEach(function(libName){
|
||||||
|
var thirdLevelName = libFolder + libName
|
||||||
|
switch(libName){
|
||||||
|
case'js':
|
||||||
|
case'css':
|
||||||
|
case'blocks':
|
||||||
|
fs.readdir(thirdLevelName,function(err,webFolderContents){
|
||||||
|
webFolderContents.forEach(function(filename){
|
||||||
|
var fullPath = thirdLevelName + '/' + filename
|
||||||
|
var blockPrefix = ''
|
||||||
|
switch(true){
|
||||||
|
case search('super.',filename):
|
||||||
|
blockPrefix = 'super'
|
||||||
|
break;
|
||||||
|
case search('admin.',filename):
|
||||||
|
blockPrefix = 'admin'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch(libName){
|
||||||
|
case'js':
|
||||||
|
s.customAutoLoadTree[blockPrefix + 'LibsJs'].push(filename)
|
||||||
|
break;
|
||||||
|
case'css':
|
||||||
|
s.customAutoLoadTree[blockPrefix + 'LibsCss'].push(filename)
|
||||||
|
break;
|
||||||
|
case'blocks':
|
||||||
|
s.customAutoLoadTree[blockPrefix + 'PageBlocks'].push(fullPath)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(libName.indexOf('.ejs') > -1){
|
||||||
|
s.customAutoLoadTree.pages.push(thirdLevelName)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case'languages':
|
||||||
|
var languagesFolder = s.checkCorrectPathEnding(customModulePath) + 'languages/'
|
||||||
|
fs.readdir(languagesFolder,function(err,files){
|
||||||
|
if(err)return console.log(err);
|
||||||
|
files.forEach(function(filename){
|
||||||
|
var fileData = require(languagesFolder + filename)
|
||||||
|
var rule = filename.replace('.json','')
|
||||||
|
if(config.language === rule){
|
||||||
|
lang = Object.assign(lang,fileData)
|
||||||
|
}
|
||||||
|
if(s.loadedLanguages[rule]){
|
||||||
|
s.loadedLanguages[rule] = Object.assign(s.loadedLanguages[rule],fileData)
|
||||||
|
}else{
|
||||||
|
s.loadedLanguages[rule] = Object.assign(s.copySystemDefaultLanguage(),fileData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
}catch(err){
|
}catch(err){
|
||||||
console.log('Failed to Load Module : ' + filename)
|
console.log('Failed to Load Module : ' + filename)
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}else{
|
})
|
||||||
fs.mkdirSync(folderPath)
|
}else{
|
||||||
}
|
fs.mkdirSync(folderPath)
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
checkFolder('customAutoLoad')
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
var P2P = require('pipe2pam');
|
// Matrix In Region Libs >
|
||||||
|
var SAT = require('sat')
|
||||||
|
var V = SAT.Vector;
|
||||||
|
var P = SAT.Polygon;
|
||||||
|
// Matrix In Region Libs />
|
||||||
|
var P2P = require('pipe2pam')
|
||||||
// pamDiff is based on https://www.npmjs.com/package/pam-diff
|
// pamDiff is based on https://www.npmjs.com/package/pam-diff
|
||||||
var PamDiff = require('./detectorPamDiff.js');
|
var PamDiff = require('pam-diff')
|
||||||
module.exports = function(s,config){
|
module.exports = function(s,config){
|
||||||
s.createPamDiffEngine = function(e){
|
s.createPamDiffEngine = function(e){
|
||||||
var width,
|
var width,
|
||||||
|
@ -46,7 +51,7 @@ module.exports = function(s,config){
|
||||||
[width,height],
|
[width,height],
|
||||||
[width,0]
|
[width,0]
|
||||||
]
|
]
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.triggerTimer = {}
|
e.triggerTimer = {}
|
||||||
|
@ -58,7 +63,7 @@ module.exports = function(s,config){
|
||||||
regions : regions.forPam,
|
regions : regions.forPam,
|
||||||
drawMatrix : e.details.detector_show_matrix
|
drawMatrix : e.details.detector_show_matrix
|
||||||
});
|
});
|
||||||
s.group[e.ke].mon[e.id].p2p = new P2P();
|
s.group[e.ke].mon[e.id].p2p = new P2P()
|
||||||
var regionArray = Object.values(regionJson)
|
var regionArray = Object.values(regionJson)
|
||||||
if(config.detectorMergePamRegionTriggers === true){
|
if(config.detectorMergePamRegionTriggers === true){
|
||||||
// merge pam triggers for performance boost
|
// merge pam triggers for performance boost
|
||||||
|
@ -317,4 +322,39 @@ module.exports = function(s,config){
|
||||||
}
|
}
|
||||||
return trigger
|
return trigger
|
||||||
}
|
}
|
||||||
|
s.isAtleastOneMatrixInRegion = function(regions,matrices,callback){
|
||||||
|
var regionPolys = []
|
||||||
|
var matrixPoints = []
|
||||||
|
regions.forEach(function(region,n){
|
||||||
|
var polyPoints = []
|
||||||
|
region.points.forEach(function(point){
|
||||||
|
polyPoints.push(new V(parseInt(point[0]),parseInt(point[1])))
|
||||||
|
})
|
||||||
|
regionPolys[n] = new P(new V(0,0), polyPoints)
|
||||||
|
})
|
||||||
|
var collisions = []
|
||||||
|
var foundInRegion = false
|
||||||
|
matrices.forEach(function(matrix){
|
||||||
|
var matrixPoints = [
|
||||||
|
new V(matrix.x,matrix.y),
|
||||||
|
new V(matrix.width,matrix.y),
|
||||||
|
new V(matrix.width,matrix.height),
|
||||||
|
new V(matrix.x,matrix.height)
|
||||||
|
]
|
||||||
|
var matrixPoly = new P(new V(0,0), matrixPoints)
|
||||||
|
regionPolys.forEach(function(region,n){
|
||||||
|
var response = new SAT.Response()
|
||||||
|
var collided = SAT.testPolygonPolygon(matrixPoly, region, response)
|
||||||
|
if(collided === true){
|
||||||
|
collisions.push({
|
||||||
|
matrix: matrix,
|
||||||
|
region: regions[n]
|
||||||
|
})
|
||||||
|
foundInRegion = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if(callback)callback(foundInRegion,collisions)
|
||||||
|
return foundInRegion
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,25 @@ var exec = require('child_process').exec;
|
||||||
var spawn = require('child_process').spawn;
|
var spawn = require('child_process').spawn;
|
||||||
var request = require('request');
|
var request = require('request');
|
||||||
module.exports = function(s,config,lang){
|
module.exports = function(s,config,lang){
|
||||||
|
var addEventDetailsToString = function(eventData,string,addOps){
|
||||||
|
//d = event data
|
||||||
|
if(!addOps)addOps = {}
|
||||||
|
var newString = string + ''
|
||||||
|
var d = Object.assign(eventData,addOps)
|
||||||
|
var detailString = s.stringJSON(d.details)
|
||||||
|
newString
|
||||||
|
.replace(/{{TIME}}/g,d.currentTimestamp)
|
||||||
|
.replace(/{{REGION_NAME}}/g,d.details.name)
|
||||||
|
.replace(/{{SNAP_PATH}}/g,s.dir.streams+'/'+d.ke+'/'+d.id+'/s.jpg')
|
||||||
|
.replace(/{{MONITOR_ID}}/g,d.id)
|
||||||
|
.replace(/{{GROUP_KEY}}/g,d.ke)
|
||||||
|
.replace(/{{DETAILS}}/g,detailString)
|
||||||
|
if(d.details.confidence){
|
||||||
|
newString = newString
|
||||||
|
.replace(/{{CONFIDENCE}}/g,d.details.confidence)
|
||||||
|
}
|
||||||
|
return newString
|
||||||
|
}
|
||||||
s.filterEvents = function(x,d){
|
s.filterEvents = function(x,d){
|
||||||
switch(x){
|
switch(x){
|
||||||
case'archive':
|
case'archive':
|
||||||
|
@ -45,6 +64,7 @@ module.exports = function(s,config,lang){
|
||||||
}
|
}
|
||||||
d.mon=s.group[d.ke].mon_conf[d.id];
|
d.mon=s.group[d.ke].mon_conf[d.id];
|
||||||
var currentConfig = s.group[d.ke].mon[d.id].details
|
var currentConfig = s.group[d.ke].mon[d.id].details
|
||||||
|
var hasMatrices = (d.details.matrices && d.details.matrices.length > 0)
|
||||||
//read filters
|
//read filters
|
||||||
if(
|
if(
|
||||||
currentConfig.use_detector_filters === '1' &&
|
currentConfig.use_detector_filters === '1' &&
|
||||||
|
@ -160,7 +180,7 @@ module.exports = function(s,config,lang){
|
||||||
})
|
})
|
||||||
if(d.details.matrices && d.details.matrices.length === 0 || filter.halt === true){
|
if(d.details.matrices && d.details.matrices.length === 0 || filter.halt === true){
|
||||||
return
|
return
|
||||||
}else if(d.details.matrices && d.details.matrices.length > 0){
|
}else if(hasMatrices){
|
||||||
var reviewedMatrix = []
|
var reviewedMatrix = []
|
||||||
d.details.matrices.forEach(function(matrix){
|
d.details.matrices.forEach(function(matrix){
|
||||||
if(matrix)reviewedMatrix.push(matrix)
|
if(matrix)reviewedMatrix.push(matrix)
|
||||||
|
@ -193,6 +213,16 @@ module.exports = function(s,config,lang){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// check if object should be in region
|
||||||
|
if(hasMatrices && currentConfig.detector_obj_region === '1'){
|
||||||
|
var regions = s.group[d.ke].mon[d.id].parsedObjects.cords
|
||||||
|
var isMatrixInRegions = s.isAtleastOneMatrixInRegion(regions,d.details.matrices)
|
||||||
|
if(isMatrixInRegions){
|
||||||
|
s.debugLog('Matrix in region!')
|
||||||
|
}else{
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
// check modified indifference
|
// check modified indifference
|
||||||
if(filter.indifference !== false && d.details.confidence < parseFloat(filter.indifference)){
|
if(filter.indifference !== false && d.details.confidence < parseFloat(filter.indifference)){
|
||||||
// fails indifference check for modified indifference
|
// fails indifference check for modified indifference
|
||||||
|
@ -210,12 +240,12 @@ module.exports = function(s,config,lang){
|
||||||
})
|
})
|
||||||
}else{
|
}else{
|
||||||
//save this detection result in SQL, only coords. not image.
|
//save this detection result in SQL, only coords. not image.
|
||||||
if(filter.save && currentConfig.detector_save==='1'){
|
if(filter.save && currentConfig.detector_save === '1'){
|
||||||
s.sqlQuery('INSERT INTO Events (ke,mid,details) VALUES (?,?,?)',[d.ke,d.id,detailString])
|
s.sqlQuery('INSERT INTO Events (ke,mid,details) VALUES (?,?,?)',[d.ke,d.id,detailString])
|
||||||
}
|
}
|
||||||
if(currentConfig.detector_notrigger === '1'){
|
if(currentConfig.detector_notrigger === '1'){
|
||||||
var detector_notrigger_timeout
|
var detector_notrigger_timeout
|
||||||
if(!currentConfig.detector_notrigger_timeout||currentConfig.detector_notrigger_timeout===''){
|
if(!currentConfig.detector_notrigger_timeout||currentConfig.detector_notrigger_timeout === ''){
|
||||||
detector_notrigger_timeout = 10
|
detector_notrigger_timeout = 10
|
||||||
}
|
}
|
||||||
detector_notrigger_timeout = parseFloat(currentConfig.detector_notrigger_timeout)*1000*60;
|
detector_notrigger_timeout = parseFloat(currentConfig.detector_notrigger_timeout)*1000*60;
|
||||||
|
@ -270,17 +300,7 @@ module.exports = function(s,config,lang){
|
||||||
})
|
})
|
||||||
|
|
||||||
if(filter.webhook && currentConfig.detector_webhook === '1'){
|
if(filter.webhook && currentConfig.detector_webhook === '1'){
|
||||||
var detector_webhook_url = currentConfig.detector_webhook_url
|
var detector_webhook_url = addEventDetailsToString(d,currentConfig.detector_webhook_url)
|
||||||
.replace(/{{TIME}}/g,d.currentTimestamp)
|
|
||||||
.replace(/{{REGION_NAME}}/g,d.details.name)
|
|
||||||
.replace(/{{SNAP_PATH}}/g,s.dir.streams+'/'+d.ke+'/'+d.id+'/s.jpg')
|
|
||||||
.replace(/{{MONITOR_ID}}/g,d.id)
|
|
||||||
.replace(/{{GROUP_KEY}}/g,d.ke)
|
|
||||||
.replace(/{{DETAILS}}/g,detailString)
|
|
||||||
if(d.details.confidence){
|
|
||||||
detector_webhook_url = detector_webhook_url
|
|
||||||
.replace(/{{CONFIDENCE}}/g,d.details.confidence)
|
|
||||||
}
|
|
||||||
request({url:detector_webhook_url,method:'GET',encoding:null},function(err,data){
|
request({url:detector_webhook_url,method:'GET',encoding:null},function(err,data){
|
||||||
if(err){
|
if(err){
|
||||||
s.userLog(d,{type:lang["Event Webhook Error"],msg:{error:err,data:data}})
|
s.userLog(d,{type:lang["Event Webhook Error"],msg:{error:err,data:data}})
|
||||||
|
@ -289,28 +309,8 @@ module.exports = function(s,config,lang){
|
||||||
}
|
}
|
||||||
|
|
||||||
if(filter.command && currentConfig.detector_command_enable === '1' && !s.group[d.ke].mon[d.id].detector_command){
|
if(filter.command && currentConfig.detector_command_enable === '1' && !s.group[d.ke].mon[d.id].detector_command){
|
||||||
var detector_command_timeout
|
s.createTimeout(s.group[d.ke].mon[d.id].detector_command,currentConfig.detector_command_timeout,10)
|
||||||
if(!currentConfig.detector_command_timeout||currentConfig.detector_command_timeout===''){
|
var detector_command = addEventDetailsToString(d,currentConfig.detector_command)
|
||||||
detector_command_timeout = 1000*60*10;
|
|
||||||
}else{
|
|
||||||
detector_command_timeout = parseFloat(currentConfig.detector_command_timeout)*1000*60;
|
|
||||||
}
|
|
||||||
s.group[d.ke].mon[d.id].detector_command=setTimeout(function(){
|
|
||||||
clearTimeout(s.group[d.ke].mon[d.id].detector_command);
|
|
||||||
delete(s.group[d.ke].mon[d.id].detector_command);
|
|
||||||
|
|
||||||
},detector_command_timeout);
|
|
||||||
var detector_command = currentConfig.detector_command
|
|
||||||
.replace(/{{TIME}}/g,d.currentTimestamp)
|
|
||||||
.replace(/{{REGION_NAME}}/g,d.details.name)
|
|
||||||
.replace(/{{SNAP_PATH}}/g,s.dir.streams+'/'+d.ke+'/'+d.id+'/s.jpg')
|
|
||||||
.replace(/{{MONITOR_ID}}/g,d.id)
|
|
||||||
.replace(/{{GROUP_KEY}}/g,d.ke)
|
|
||||||
.replace(/{{DETAILS}}/g,detailString)
|
|
||||||
if(d.details.confidence){
|
|
||||||
detector_command = detector_command
|
|
||||||
.replace(/{{CONFIDENCE}}/g,d.details.confidence)
|
|
||||||
}
|
|
||||||
exec(detector_command,{detached: true})
|
exec(detector_command,{detached: true})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,7 +382,16 @@ module.exports = function(s,config,onFinish){
|
||||||
//x = temporary values
|
//x = temporary values
|
||||||
//check if CUDA is enabled
|
//check if CUDA is enabled
|
||||||
e.isStreamer = (e.type === 'dashcam'|| e.type === 'socket')
|
e.isStreamer = (e.type === 'dashcam'|| e.type === 'socket')
|
||||||
if(e.details.accelerator === '1' && e.details.hwaccel === 'cuvid' && e.details.hwaccel_vcodec === ('h264_cuvid' || 'hevc_cuvid' || 'mjpeg_cuvid' || 'mpeg4_cuvid')){
|
e.coProcessor = false
|
||||||
|
if(
|
||||||
|
e.details.use_coprocessor === '1' &&
|
||||||
|
e.details.accelerator === '1' &&
|
||||||
|
e.isStreamer === false &&
|
||||||
|
(!e.details.input_maps || e.details.input_maps.length === 0) &&
|
||||||
|
(e.details.snap === '1' || e.details.stream_type === 'mjpeg' || e.details.stream_type === 'b64' || e.details.detector === '1')
|
||||||
|
){
|
||||||
|
e.coProcessor = true
|
||||||
|
}else if(e.details.accelerator === '1' && e.details.hwaccel === 'cuvid' && e.details.hwaccel_vcodec === ('h264_cuvid' || 'hevc_cuvid' || 'mjpeg_cuvid' || 'mpeg4_cuvid')){
|
||||||
e.cudaEnabled = true
|
e.cudaEnabled = true
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -563,9 +572,11 @@ module.exports = function(s,config,onFinish){
|
||||||
x.pipe+=x.preset_stream+x.stream_acodec+x.stream_vcodec+' -f hls'+x.cust_stream+' -hls_time '+x.hls_time+' -hls_list_size '+x.hls_list_size+' -start_number 0 -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist "'+e.sdir+'s.m3u8"';
|
x.pipe+=x.preset_stream+x.stream_acodec+x.stream_vcodec+' -f hls'+x.cust_stream+' -hls_time '+x.hls_time+' -hls_list_size '+x.hls_list_size+' -start_number 0 -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist "'+e.sdir+'s.m3u8"';
|
||||||
break;
|
break;
|
||||||
case'mjpeg':
|
case'mjpeg':
|
||||||
|
if(e.coProcessor === false){
|
||||||
if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality;
|
if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality;
|
||||||
if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions}
|
if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions}
|
||||||
x.pipe+=' -an -c:v mjpeg -f mpjpeg -boundary_tag shinobi'+x.cust_stream+x.stream_video_filters+' pipe:1';
|
x.pipe+=' -an -c:v mjpeg -f mpjpeg -boundary_tag shinobi'+x.cust_stream+x.stream_video_filters+' pipe:1';
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case'h265':
|
case'h265':
|
||||||
x.cust_stream+=' -movflags +frag_keyframe+empty_moov+default_base_moof -metadata title="Shinobi H.265 Stream" -reset_timestamps 1'
|
x.cust_stream+=' -movflags +frag_keyframe+empty_moov+default_base_moof -metadata title="Shinobi H.265 Stream" -reset_timestamps 1'
|
||||||
|
@ -578,9 +589,11 @@ module.exports = function(s,config,onFinish){
|
||||||
x.pipe+=' -f hevc'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:1';
|
x.pipe+=' -f hevc'+x.stream_acodec+x.stream_vcodec+x.cust_stream+' pipe:1';
|
||||||
break;
|
break;
|
||||||
case'b64':case'':case undefined:case null://base64
|
case'b64':case'':case undefined:case null://base64
|
||||||
if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality;
|
if(e.coProcessor === false){
|
||||||
if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions}
|
if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality;
|
||||||
x.pipe+=' -an -c:v mjpeg -f image2pipe'+x.cust_stream+x.stream_video_filters+' pipe:1';
|
if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions}
|
||||||
|
x.pipe+=' -an -c:v mjpeg -f image2pipe'+x.cust_stream+x.stream_video_filters+' pipe:1';
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
x.pipe=''
|
x.pipe=''
|
||||||
|
@ -588,11 +601,12 @@ module.exports = function(s,config,onFinish){
|
||||||
}
|
}
|
||||||
if(e.details.stream_channels){
|
if(e.details.stream_channels){
|
||||||
e.details.stream_channels.forEach(function(v,n){
|
e.details.stream_channels.forEach(function(v,n){
|
||||||
|
// if(v.stream_type === 'mjpeg')e.coProcessor = true;
|
||||||
x.pipe += s.createStreamChannel(e,n+config.pipeAddition,v)
|
x.pipe += s.createStreamChannel(e,n+config.pipeAddition,v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
//api - snapshot bin/ cgi.bin (JPEG Mode)
|
//api - snapshot bin/ cgi.bin (JPEG Mode)
|
||||||
if(e.details.snap === '1'){
|
if(e.details.snap === '1' && e.coProcessor === false){
|
||||||
if(e.details.input_map_choices&&e.details.input_map_choices.snap){
|
if(e.details.input_map_choices&&e.details.input_map_choices.snap){
|
||||||
//add input feed map
|
//add input feed map
|
||||||
x.pipe += s.createFFmpegMap(e,e.details.input_map_choices.snap)
|
x.pipe += s.createFFmpegMap(e,e.details.input_map_choices.snap)
|
||||||
|
@ -735,12 +749,23 @@ module.exports = function(s,config,onFinish){
|
||||||
x.record_string+=x.vcodec+x.record_fps+x.record_video_filters+x.record_dimensions+x.segment;
|
x.record_string+=x.vcodec+x.record_fps+x.record_video_filters+x.record_dimensions+x.segment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ffmpeg.buildAudioDetector = function(e,x){
|
||||||
|
if(e.details.detector_audio === '1'){
|
||||||
|
if(e.details.input_map_choices&&e.details.input_map_choices.detector_audio){
|
||||||
|
//add input feed map
|
||||||
|
x.pipe += s.createFFmpegMap(e,e.details.input_map_choices.detector_audio)
|
||||||
|
}else{
|
||||||
|
x.pipe += ' -map 0:a'
|
||||||
|
}
|
||||||
|
x.pipe += ' -acodec pcm_s16le -f s16le -ac 1 -ar 16000 pipe:6'
|
||||||
|
}
|
||||||
|
}
|
||||||
ffmpeg.buildMainDetector = function(e,x){
|
ffmpeg.buildMainDetector = function(e,x){
|
||||||
//e = monitor object
|
//e = monitor object
|
||||||
//x = temporary values
|
//x = temporary values
|
||||||
x.cust_detect = ' '
|
x.cust_detect = ' '
|
||||||
//detector - plugins, motion
|
//detector - plugins, motion
|
||||||
if(e.details.detector === '1' && e.details.detector_send_frames === '1'){
|
if(e.details.detector === '1' && e.details.detector_send_frames === '1' && e.coProcessor === false){
|
||||||
if(e.details.input_map_choices&&e.details.input_map_choices.detector){
|
if(e.details.input_map_choices&&e.details.input_map_choices.detector){
|
||||||
//add input feed map
|
//add input feed map
|
||||||
x.pipe += s.createFFmpegMap(e,e.details.input_map_choices.detector)
|
x.pipe += s.createFFmpegMap(e,e.details.input_map_choices.detector)
|
||||||
|
@ -761,14 +786,15 @@ module.exports = function(s,config,onFinish){
|
||||||
if(e.details.detector_use_detect_object === '1'){
|
if(e.details.detector_use_detect_object === '1'){
|
||||||
//for object detection
|
//for object detection
|
||||||
x.pipe += s.createFFmpegMap(e,e.details.input_map_choices.detector)
|
x.pipe += s.createFFmpegMap(e,e.details.input_map_choices.detector)
|
||||||
x.pipe += ' -f singlejpeg '+x.detector_vf+x.cust_detect+x.dratio+' pipe:4';
|
x.pipe += ' -an -f singlejpeg '+x.detector_vf+x.cust_detect+x.dratio+' pipe:4';
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
x.pipe+=' -f image2pipe '+x.detector_vf+x.cust_detect+x.dratio+' pipe:3';
|
x.pipe+=' -an -f image2pipe '+x.detector_vf+x.cust_detect+x.dratio+' pipe:3';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Traditional Recording Buffer
|
//Traditional Recording Buffer
|
||||||
if(e.details.detector=='1'&&e.details.detector_trigger=='1'&&e.details.detector_record_method==='sip'){
|
if(e.details.detector=='1'&&e.details.detector_trigger=='1'&&e.details.detector_record_method==='sip'){
|
||||||
|
if(e.details.cust_sip_record && e.details.cust_sip_record !== ''){x.pipe += ' ' + e.details.cust_sip_record}
|
||||||
if(e.details.input_map_choices&&e.details.input_map_choices.detector_sip_buffer){
|
if(e.details.input_map_choices&&e.details.input_map_choices.detector_sip_buffer){
|
||||||
//add input feed map
|
//add input feed map
|
||||||
x.pipe += s.createFFmpegMap(e,e.details.input_map_choices.detector_sip_buffer)
|
x.pipe += s.createFFmpegMap(e,e.details.input_map_choices.detector_sip_buffer)
|
||||||
|
@ -836,6 +862,12 @@ module.exports = function(s,config,onFinish){
|
||||||
x.pipe+=x.detector_buffer_fps+x.detector_buffer_acodec+' -c:v '+e.details.detector_buffer_vcodec+' -f hls -tune '+e.details.detector_buffer_tune+' -g '+e.details.detector_buffer_g+' -hls_time '+e.details.detector_buffer_hls_time+' -hls_list_size '+e.details.detector_buffer_hls_list_size+' -start_number '+e.details.detector_buffer_start_number+' -live_start_index '+e.details.detector_buffer_live_start_index+' -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist "'+e.sdir+'detectorStream.m3u8"'
|
x.pipe+=x.detector_buffer_fps+x.detector_buffer_acodec+' -c:v '+e.details.detector_buffer_vcodec+' -f hls -tune '+e.details.detector_buffer_tune+' -g '+e.details.detector_buffer_g+' -hls_time '+e.details.detector_buffer_hls_time+' -hls_list_size '+e.details.detector_buffer_hls_list_size+' -start_number '+e.details.detector_buffer_start_number+' -live_start_index '+e.details.detector_buffer_live_start_index+' -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist "'+e.sdir+'detectorStream.m3u8"'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ffmpeg.buildCoProcessorFeed = function(e,x){
|
||||||
|
if(e.coProcessor === true){
|
||||||
|
// the coProcessor ffmpeg consumes this HLS stream (no audio, frames only)
|
||||||
|
x.pipe += ' -q:v 1 -an -c:v copy -f hls -tune zerolatency -g 1 -hls_time 2 -hls_list_size 3 -start_number 0 -live_start_index 3 -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist "'+e.sdir+'coProcessor.m3u8"'
|
||||||
|
}
|
||||||
|
}
|
||||||
ffmpeg.assembleMainPieces = function(e,x){
|
ffmpeg.assembleMainPieces = function(e,x){
|
||||||
//create executeable FFMPEG command
|
//create executeable FFMPEG command
|
||||||
x.ffmpegCommandString = x.loglevel+x.input_fps;
|
x.ffmpegCommandString = x.loglevel+x.input_fps;
|
||||||
|
@ -852,6 +884,9 @@ module.exports = function(s,config,onFinish){
|
||||||
case'mjpeg':
|
case'mjpeg':
|
||||||
x.ffmpegCommandString += ' -reconnect 1 -f mjpeg'+x.cust_input+x.hwaccel+' -i "'+e.url+'"';
|
x.ffmpegCommandString += ' -reconnect 1 -f mjpeg'+x.cust_input+x.hwaccel+' -i "'+e.url+'"';
|
||||||
break;
|
break;
|
||||||
|
// case'rtmp':
|
||||||
|
// x.ffmpegCommandString += x.cust_input+x.hwaccel+' -i -';
|
||||||
|
// break;
|
||||||
case'h264':case'hls':case'mp4':
|
case'h264':case'hls':case'mp4':
|
||||||
x.ffmpegCommandString += x.cust_input+x.hwaccel+' -i "'+e.url+'"';
|
x.ffmpegCommandString += x.cust_input+x.hwaccel+' -i "'+e.url+'"';
|
||||||
break;
|
break;
|
||||||
|
@ -886,7 +921,9 @@ module.exports = function(s,config,onFinish){
|
||||||
ffmpeg.buildMainInput(e,x)
|
ffmpeg.buildMainInput(e,x)
|
||||||
ffmpeg.buildMainStream(e,x)
|
ffmpeg.buildMainStream(e,x)
|
||||||
ffmpeg.buildMainRecording(e,x)
|
ffmpeg.buildMainRecording(e,x)
|
||||||
|
ffmpeg.buildAudioDetector(e,x)
|
||||||
ffmpeg.buildMainDetector(e,x)
|
ffmpeg.buildMainDetector(e,x)
|
||||||
|
ffmpeg.buildCoProcessorFeed(e,x)
|
||||||
s.onFfmpegCameraStringCreationExtensions.forEach(function(extender){
|
s.onFfmpegCameraStringCreationExtensions.forEach(function(extender){
|
||||||
extender(e,x)
|
extender(e,x)
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,234 @@
|
||||||
|
var spawn = require('child_process').spawn;
|
||||||
|
module.exports = function(s,config,lang,ffmpeg){
|
||||||
|
ffmpeg.buildCoProcessorInput = function(e,x){
|
||||||
|
if(e.details.userLoglevel&&e.details.userLoglevel!==''){x.loglevel='-loglevel '+e.details.userLoglevel;}else{x.loglevel='-loglevel error'}
|
||||||
|
x.input = x.loglevel+' -re -i '+e.sdir+'coProcessor.m3u8'
|
||||||
|
}
|
||||||
|
ffmpeg.buildCoProcessorStream = function(e,x){
|
||||||
|
x.stream_video_filters = []
|
||||||
|
//stream - timestamp
|
||||||
|
if(e.details.stream_timestamp&&e.details.stream_timestamp=="1"&&e.details.vcodec!=='copy'){
|
||||||
|
//font
|
||||||
|
if(e.details.stream_timestamp_font&&e.details.stream_timestamp_font!==''){x.stream_timestamp_font=e.details.stream_timestamp_font}else{x.stream_timestamp_font='/usr/share/fonts/truetype/freefont/FreeSans.ttf'}
|
||||||
|
//position x
|
||||||
|
if(e.details.stream_timestamp_x&&e.details.stream_timestamp_x!==''){x.stream_timestamp_x=e.details.stream_timestamp_x}else{x.stream_timestamp_x='(w-tw)/2'}
|
||||||
|
//position y
|
||||||
|
if(e.details.stream_timestamp_y&&e.details.stream_timestamp_y!==''){x.stream_timestamp_y=e.details.stream_timestamp_y}else{x.stream_timestamp_y='0'}
|
||||||
|
//text color
|
||||||
|
if(e.details.stream_timestamp_color&&e.details.stream_timestamp_color!==''){x.stream_timestamp_color=e.details.stream_timestamp_color}else{x.stream_timestamp_color='white'}
|
||||||
|
//box color
|
||||||
|
if(e.details.stream_timestamp_box_color&&e.details.stream_timestamp_box_color!==''){x.stream_timestamp_box_color=e.details.stream_timestamp_box_color}else{x.stream_timestamp_box_color='0x00000000@1'}
|
||||||
|
//text size
|
||||||
|
if(e.details.stream_timestamp_font_size&&e.details.stream_timestamp_font_size!==''){x.stream_timestamp_font_size=e.details.stream_timestamp_font_size}else{x.stream_timestamp_font_size='10'}
|
||||||
|
|
||||||
|
x.stream_video_filters.push('drawtext=fontfile='+x.stream_timestamp_font+':text=\'%{localtime}\':x='+x.stream_timestamp_x+':y='+x.stream_timestamp_y+':fontcolor='+x.stream_timestamp_color+':box=1:boxcolor='+x.stream_timestamp_box_color+':fontsize='+x.stream_timestamp_font_size);
|
||||||
|
}
|
||||||
|
//stream - watermark for -vf
|
||||||
|
if(e.details.stream_watermark&&e.details.stream_watermark=="1"&&e.details.stream_watermark_location&&e.details.stream_watermark_location!==''){
|
||||||
|
switch(e.details.stream_watermark_position){
|
||||||
|
case'tl'://top left
|
||||||
|
x.stream_watermark_position='10:10'
|
||||||
|
break;
|
||||||
|
case'tr'://top right
|
||||||
|
x.stream_watermark_position='main_w-overlay_w-10:10'
|
||||||
|
break;
|
||||||
|
case'bl'://bottom left
|
||||||
|
x.stream_watermark_position='10:main_h-overlay_h-10'
|
||||||
|
break;
|
||||||
|
default://bottom right
|
||||||
|
x.stream_watermark_position='(main_w-overlay_w-10)/2:(main_h-overlay_h-10)/2'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
x.stream_video_filters.push('movie='+e.details.stream_watermark_location+'[watermark],[in][watermark]overlay='+x.stream_watermark_position+'[out]');
|
||||||
|
}
|
||||||
|
//stream - rotation
|
||||||
|
if(e.details.rotate_stream&&e.details.rotate_stream!==""&&e.details.rotate_stream!=="no"&&e.details.stream_vcodec!=='copy'){
|
||||||
|
x.stream_video_filters.push('transpose='+e.details.rotate_stream);
|
||||||
|
}
|
||||||
|
if(e.details.svf&&e.details.svf!==''){
|
||||||
|
x.stream_video_filters.push(e.details.svf)
|
||||||
|
}
|
||||||
|
if(x.stream_video_filters.length>0){
|
||||||
|
x.stream_video_filters=' -vf '+x.stream_video_filters.join(',')
|
||||||
|
}else{
|
||||||
|
x.stream_video_filters=''
|
||||||
|
}
|
||||||
|
if(e.details.cust_stream&&e.details.cust_stream!==''){x.cust_stream=' '+e.details.cust_stream}else{x.cust_stream=''}
|
||||||
|
if(e.details.stream_fps&&e.details.stream_fps!==''){x.stream_fps=' -r '+e.details.stream_fps}else{x.stream_fps=''}
|
||||||
|
if(e.details.stream_vcodec !== 'copy' || e.details.stream_type === 'mjpeg' || e.details.stream_type === 'b64'){
|
||||||
|
x.cust_stream += x.stream_fps
|
||||||
|
}
|
||||||
|
switch(e.details.stream_type){
|
||||||
|
case'mjpeg':
|
||||||
|
if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality;
|
||||||
|
if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions}
|
||||||
|
x.pipe += ' -an -c:v mjpeg -f mpjpeg -boundary_tag shinobi'+x.cust_stream+x.stream_video_filters+' pipe:1';
|
||||||
|
break;
|
||||||
|
case'b64':case'':case undefined:case null://base64
|
||||||
|
if(e.details.stream_quality && e.details.stream_quality !== '')x.cust_stream+=' -q:v '+e.details.stream_quality;
|
||||||
|
if(x.dimensions && x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.dimensions}
|
||||||
|
x.pipe += ' -an -c:v mjpeg -f image2pipe'+x.cust_stream+x.stream_video_filters+' pipe:1';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ffmpeg.buildCoProcessorDetector = function(e,x){
|
||||||
|
//detector frames
|
||||||
|
x.cust_detect=' '
|
||||||
|
if(e.details.detector === '1'){
|
||||||
|
if(e.details.detector_fps && e.details.detector_fps !== ''){
|
||||||
|
x.detector_fps = e.details.detector_fps
|
||||||
|
}else{
|
||||||
|
x.detector_fps = '2'
|
||||||
|
}
|
||||||
|
if(e.details.detector_scale_x && e.details.detector_scale_x !== '' && e.details.detector_scale_y && e.details.detector_scale_y !== ''){
|
||||||
|
x.dratio=' -s '+e.details.detector_scale_x+'x'+e.details.detector_scale_y
|
||||||
|
}else{
|
||||||
|
x.dratio=' -s 320x240'
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e.details.cust_detect&&e.details.cust_detect!==''){x.cust_detect+=e.details.cust_detect;}
|
||||||
|
if(e.details.detector_pam==='1'){
|
||||||
|
x.pipe += ' -an -c:v pam -pix_fmt gray -f image2pipe -r '+x.detector_fps+x.cust_detect+x.dratio+' pipe:3'
|
||||||
|
if(e.details.detector_use_detect_object === '1'){
|
||||||
|
if(e.details.detector_use_motion === '1'){
|
||||||
|
if(e.details.detector_scale_x_object && e.details.detector_scale_x_object !== '' && e.details.detector_scale_y_object && e.details.detector_scale_y_object !== ''){
|
||||||
|
x.dratio=' -s '+e.details.detector_scale_x_object+'x'+e.details.detector_scale_y_object
|
||||||
|
}
|
||||||
|
if(e.details.detector_fps_object && e.details.detector_fps_object !== ''){
|
||||||
|
x.detector_fps = e.details.detector_fps_object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//for object detection
|
||||||
|
x.pipe += s.createFFmpegMap(e,e.details.input_map_choices.detector)
|
||||||
|
x.pipe += ' -f singlejpeg -vf fps='+x.detector_fps+x.cust_detect+x.dratio+' pipe:4';
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
x.pipe+=' -f singlejpeg -vf fps='+x.detector_fps+x.cust_detect+x.dratio+' pipe:3';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ffmpeg.buildCoProcessorJpegApi = function(e,x){
|
||||||
|
//snapshot frames
|
||||||
|
if(e.details.snap === '1'){
|
||||||
|
if(!e.details.snap_fps || e.details.snap_fps === ''){e.details.snap_fps = 1}
|
||||||
|
if(e.details.snap_vf && e.details.snap_vf !== ''){x.snap_vf=' -vf '+e.details.snap_vf}else{x.snap_vf=''}
|
||||||
|
if(e.details.snap_scale_x && e.details.snap_scale_x !== '' && e.details.snap_scale_y && e.details.snap_scale_y !== ''){x.snap_ratio = ' -s '+e.details.snap_scale_x+'x'+e.details.snap_scale_y}else{x.snap_ratio=''}
|
||||||
|
if(e.details.cust_snap && e.details.cust_snap !== ''){x.cust_snap = ' '+e.details.cust_snap}else{x.cust_snap=''}
|
||||||
|
x.pipe += ' -update 1 -r '+e.details.snap_fps+x.cust_snap+x.snap_ratio+x.snap_vf+' "'+e.sdir+'s.jpg" -y';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ffmpeg.buildCoProcessorPipeArray = function(e,x){
|
||||||
|
x.stdioPipes = [];
|
||||||
|
var times = config.pipeAddition;
|
||||||
|
if(e.details.stream_channels){
|
||||||
|
times+=e.details.stream_channels.length
|
||||||
|
}
|
||||||
|
for(var i=0; i < times; i++){
|
||||||
|
x.stdioPipes.push('pipe')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.ffmpegCoProcessor = function(e){
|
||||||
|
if(e.coProcessor === false)return;
|
||||||
|
var x = {}
|
||||||
|
x.pipe = ''
|
||||||
|
ffmpeg.buildCoProcessorInput(e,x)
|
||||||
|
ffmpeg.buildCoProcessorStream(e,x)
|
||||||
|
ffmpeg.buildCoProcessorDetector(e,x)
|
||||||
|
ffmpeg.buildCoProcessorJpegApi(e,x)
|
||||||
|
ffmpeg.buildCoProcessorPipeArray(e,x)
|
||||||
|
var commandString = x.input + x.pipe
|
||||||
|
if(commandString === x.input){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
s.group[e.ke].mon[e.mid].coProcessorCmd = commandString
|
||||||
|
return spawn(config.ffmpegDir,s.splitForFFPMEG((commandString).replace(/\s+/g,' ').trim()),{detached: true,stdio:x.stdioPipes})
|
||||||
|
}
|
||||||
|
s.coSpawnLauncher = function(e){
|
||||||
|
if(s.group[e.ke].mon[e.id].isStarted === true && e.coProcessor === true){
|
||||||
|
s.coSpawnClose(e)
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor = s.ffmpegCoProcessor(e)
|
||||||
|
if(s.group[e.ke].mon[e.id].coSpawnProcessor === false){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.userLog(e,{type:lang['coProcessor Started'],msg:{msg:lang.coProcessorTextStarted,cmd:s.group[e.ke].mon[e.id].coProcessorCmd}});
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessorExit = function(){
|
||||||
|
s.userLog(e,{type:lang['coProcess Unexpected Exit'],msg:{msg:lang['coProcess Crashed for Monitor']+' : '+e.id,cmd:s.group[e.ke].mon[e.id].coProcessorCmd}});
|
||||||
|
setTimeout(function(){
|
||||||
|
s.coSpawnLauncher(e)
|
||||||
|
},2000)
|
||||||
|
}
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.on('end',s.group[e.ke].mon[e.id].coSpawnProcessorExit)
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.on('exit',s.group[e.ke].mon[e.id].coSpawnProcessorExit)
|
||||||
|
var checkLog = function(d,x){return d.indexOf(x)>-1;}
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.stderr.on('data',function(d){
|
||||||
|
d=d.toString();
|
||||||
|
switch(true){
|
||||||
|
case checkLog(d,'deprecated pixel format used'):
|
||||||
|
case checkLog(d,'[hls @'):
|
||||||
|
case checkLog(d,'Past duration'):
|
||||||
|
case checkLog(d,'Last message repeated'):
|
||||||
|
case checkLog(d,'pkt->duration = 0'):
|
||||||
|
case checkLog(d,'Non-monotonous DTS'):
|
||||||
|
case checkLog(d,'NULL @'):
|
||||||
|
return
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s.userLog(e,{type:lang.coProcessor,msg:d});
|
||||||
|
})
|
||||||
|
if(e.frame_to_stream){
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.stdout.on('data',e.frame_to_stream)
|
||||||
|
}
|
||||||
|
if(e.details.detector === '1'){
|
||||||
|
s.ocvTx({f:'init_monitor',id:e.id,ke:e.ke})
|
||||||
|
//frames from motion detect
|
||||||
|
if(e.details.detector_pam === '1'){
|
||||||
|
s.createPamDiffEngine(e)
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.stdio[3].pipe(s.group[e.ke].mon[e.id].p2p).pipe(s.group[e.ke].mon[e.id].pamDiff)
|
||||||
|
if(e.details.detector_use_detect_object === '1'){
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.stdio[4].on('data',function(d){
|
||||||
|
s.group[e.ke].mon[e.id].lastJpegDetectorFrame = d
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}else if(s.ocv){
|
||||||
|
if(s.ocv.connectionType !== 'ram'){
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.stdio[3].on('data',function(d){
|
||||||
|
s.ocvTx({f:'frame',mon:s.group[e.ke].mon_conf[e.id].details,ke:e.ke,id:e.id,time:s.formattedTime(),frame:d});
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.stdio[3].on('data',function(d){
|
||||||
|
if(!s.group[e.ke].mon[e.id].detectorFrameSaveBuffer){
|
||||||
|
s.group[e.ke].mon[e.id].detectorFrameSaveBuffer=[d]
|
||||||
|
}else{
|
||||||
|
s.group[e.ke].mon[e.id].detectorFrameSaveBuffer.push(d)
|
||||||
|
}
|
||||||
|
if(d[d.length-2] === 0xFF && d[d.length-1] === 0xD9){
|
||||||
|
var buffer = Buffer.concat(s.group[e.ke].mon[e.id].detectorFrameSaveBuffer);
|
||||||
|
var frameLocation = s.dir.streams + e.ke + '/' + e.id + '/' + s.gid(5) + '.jpg'
|
||||||
|
if(s.ocv){
|
||||||
|
fs.writeFile(frameLocation,buffer,function(err){
|
||||||
|
if(err){
|
||||||
|
s.debugLog(err)
|
||||||
|
}else{
|
||||||
|
s.ocvTx({f:'frameFromRam',mon:s.group[e.ke].mon_conf[e.id].details,ke:e.ke,id:e.id,time:s.formattedTime(),frameLocation:frameLocation})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
s.group[e.ke].mon[e.id].detectorFrameSaveBuffer = null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.coSpawnClose = function(e){
|
||||||
|
if(s.group[e.ke].mon[e.id].coSpawnProcessor){
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.removeListener('end',s.group[e.ke].mon[e.id].coSpawnProcessorExit);
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.removeListener('exit',s.group[e.ke].mon[e.id].coSpawnProcessorExit);
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.stdin.pause()
|
||||||
|
s.group[e.ke].mon[e.id].coSpawnProcessor.kill()
|
||||||
|
delete(s.group[e.ke].mon[e.id].coSpawnProcessor)
|
||||||
|
s.userLog(e,{type:lang['coProcessor Stopped'],msg:{msg:lang.coProcessorTextStopped+' : '+e.id}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
139
libs/monitor.js
139
libs/monitor.js
|
@ -6,6 +6,7 @@ var Mp4Frag = require('mp4frag');
|
||||||
var onvif = require('node-onvif');
|
var onvif = require('node-onvif');
|
||||||
var request = require('request');
|
var request = require('request');
|
||||||
var connectionTester = require('connection-tester')
|
var connectionTester = require('connection-tester')
|
||||||
|
var SoundDetection = require('shinobi-sound-detection')
|
||||||
var URL = require('url')
|
var URL = require('url')
|
||||||
module.exports = function(s,config,lang){
|
module.exports = function(s,config,lang){
|
||||||
s.initiateMonitorObject = function(e){
|
s.initiateMonitorObject = function(e){
|
||||||
|
@ -21,6 +22,7 @@ module.exports = function(s,config,lang){
|
||||||
if(!s.group[e.ke].mon[e.mid].eventBasedRecording){s.group[e.ke].mon[e.mid].eventBasedRecording={}};
|
if(!s.group[e.ke].mon[e.mid].eventBasedRecording){s.group[e.ke].mon[e.mid].eventBasedRecording={}};
|
||||||
if(!s.group[e.ke].mon[e.mid].watch){s.group[e.ke].mon[e.mid].watch={}};
|
if(!s.group[e.ke].mon[e.mid].watch){s.group[e.ke].mon[e.mid].watch={}};
|
||||||
if(!s.group[e.ke].mon[e.mid].fixingVideos){s.group[e.ke].mon[e.mid].fixingVideos={}};
|
if(!s.group[e.ke].mon[e.mid].fixingVideos){s.group[e.ke].mon[e.mid].fixingVideos={}};
|
||||||
|
if(!s.group[e.ke].mon[e.mid].parsedObjects){s.group[e.ke].mon[e.mid].parsedObjects={}};
|
||||||
if(!s.group[e.ke].mon[e.mid].isStarted){s.group[e.ke].mon[e.mid].isStarted = false};
|
if(!s.group[e.ke].mon[e.mid].isStarted){s.group[e.ke].mon[e.mid].isStarted = false};
|
||||||
if(s.group[e.ke].mon[e.mid].delete){clearTimeout(s.group[e.ke].mon[e.mid].delete)}
|
if(s.group[e.ke].mon[e.mid].delete){clearTimeout(s.group[e.ke].mon[e.mid].delete)}
|
||||||
if(!s.group[e.ke].mon_conf){s.group[e.ke].mon_conf={}}
|
if(!s.group[e.ke].mon_conf){s.group[e.ke].mon_conf={}}
|
||||||
|
@ -103,7 +105,7 @@ module.exports = function(s,config,lang){
|
||||||
var snapBuffer = []
|
var snapBuffer = []
|
||||||
var snapProcess = spawn(config.ffmpegDir,('-loglevel quiet -re -i '+url+options+' -frames:v 1 -f image2pipe pipe:1').split(' '),{detached: true})
|
var snapProcess = spawn(config.ffmpegDir,('-loglevel quiet -re -i '+url+options+' -frames:v 1 -f image2pipe pipe:1').split(' '),{detached: true})
|
||||||
snapProcess.stdout.on('data',function(data){
|
snapProcess.stdout.on('data',function(data){
|
||||||
snapBuffer.push(data)
|
if(snapBuffer)snapBuffer.push(data)
|
||||||
})
|
})
|
||||||
snapProcess.stderr.on('data',function(data){
|
snapProcess.stderr.on('data',function(data){
|
||||||
console.log(data.toString())
|
console.log(data.toString())
|
||||||
|
@ -266,6 +268,7 @@ module.exports = function(s,config,lang){
|
||||||
if(s.group[e.ke].mon[e.id].childNode){
|
if(s.group[e.ke].mon[e.id].childNode){
|
||||||
s.cx({f:'kill',d:s.cleanMonitorObject(e)},s.group[e.ke].mon[e.id].childNodeId)
|
s.cx({f:'kill',d:s.cleanMonitorObject(e)},s.group[e.ke].mon[e.id].childNodeId)
|
||||||
}else{
|
}else{
|
||||||
|
s.coSpawnClose(e)
|
||||||
if(!x||x===1){return};
|
if(!x||x===1){return};
|
||||||
p=x.pid;
|
p=x.pid;
|
||||||
if(s.group[e.ke].mon_conf[e.id].type===('dashcam'||'socket'||'jpeg'||'pipe')){
|
if(s.group[e.ke].mon_conf[e.id].type===('dashcam'||'socket'||'jpeg'||'pipe')){
|
||||||
|
@ -282,12 +285,20 @@ module.exports = function(s,config,lang){
|
||||||
s.cameraCheckObjectsInDetails = function(e){
|
s.cameraCheckObjectsInDetails = function(e){
|
||||||
//parse Objects
|
//parse Objects
|
||||||
(['detector_cascades','cords','detector_filters','input_map_choices']).forEach(function(v){
|
(['detector_cascades','cords','detector_filters','input_map_choices']).forEach(function(v){
|
||||||
if(e.details&&e.details[v]&&(e.details[v] instanceof Object)===false){
|
if(e.details && e.details[v]){
|
||||||
try{
|
try{
|
||||||
if(e.details[v] === '') e.details[v] = '{}'
|
if(!e.details[v] || e.details[v] === '')e.details[v] = '{}'
|
||||||
e.details[v]=JSON.parse(e.details[v]);
|
e.details[v] = s.parseJSON(e.details[v])
|
||||||
if(!e.details[v])e.details[v]={};
|
if(!e.details[v])e.details[v] = {}
|
||||||
s.group[e.ke].mon[e.id].details = e.details;
|
s.group[e.ke].mon[e.id].details = e.details
|
||||||
|
switch(v){
|
||||||
|
case'cords':
|
||||||
|
s.group[e.ke].mon[e.id].parsedObjects[v] = Object.values(s.parseJSON(e.details[v]))
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s.group[e.ke].mon[e.id].parsedObjects[v] = s.parseJSON(e.details[v])
|
||||||
|
break;
|
||||||
|
}
|
||||||
}catch(err){
|
}catch(err){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -776,7 +787,47 @@ module.exports = function(s,config,lang){
|
||||||
if(e.type==='jpeg'){
|
if(e.type==='jpeg'){
|
||||||
s.cameraPullJpegStream(e)
|
s.cameraPullJpegStream(e)
|
||||||
}
|
}
|
||||||
if(e.details.detector === '1'){
|
if(e.details.detector_audio === '1'){
|
||||||
|
var triggerLevel
|
||||||
|
var triggerLevelMax
|
||||||
|
if(e.details.detector_audio_min_db && e.details.detector_audio_min_db !== ''){
|
||||||
|
triggerLevel = parseInt(e.details.detector_audio_min_db)
|
||||||
|
}else{
|
||||||
|
triggerLevel = 5
|
||||||
|
}
|
||||||
|
if(e.details.detector_audio_max_db && e.details.detector_audio_max_db !== ''){
|
||||||
|
triggerLevelMax = parseInt(e.details.detector_audio_max_db)
|
||||||
|
}
|
||||||
|
var audioDetector = new SoundDetection({
|
||||||
|
format: {
|
||||||
|
bitDepth: 16,
|
||||||
|
numberOfChannels: 1,
|
||||||
|
signed: true
|
||||||
|
},
|
||||||
|
triggerLevel: triggerLevel,
|
||||||
|
triggerLevelMax: triggerLevelMax
|
||||||
|
},function(dB) {
|
||||||
|
s.triggerEvent({
|
||||||
|
f:'trigger',
|
||||||
|
id:e.id,
|
||||||
|
ke:e.ke,
|
||||||
|
name: 'db',
|
||||||
|
details:{
|
||||||
|
plug:'audio',
|
||||||
|
name:'db',
|
||||||
|
reason:'soundChange',
|
||||||
|
confidence:dB
|
||||||
|
},
|
||||||
|
plates:[],
|
||||||
|
imgHeight:e.details.detector_scale_y,
|
||||||
|
imgWidth:e.details.detector_scale_x
|
||||||
|
})
|
||||||
|
})
|
||||||
|
s.group[e.ke].mon[e.id].audioDetector = audioDetector
|
||||||
|
audioDetector.start()
|
||||||
|
s.group[e.ke].mon[e.id].spawn.stdio[6].pipe(audioDetector.streamDecoder)
|
||||||
|
}
|
||||||
|
if(e.details.detector === '1' && e.coProcessor === false){
|
||||||
s.ocvTx({f:'init_monitor',id:e.id,ke:e.ke})
|
s.ocvTx({f:'init_monitor',id:e.id,ke:e.ke})
|
||||||
//frames from motion detect
|
//frames from motion detect
|
||||||
if(e.details.detector_pam === '1'){
|
if(e.details.detector_pam === '1'){
|
||||||
|
@ -865,7 +916,11 @@ module.exports = function(s,config,lang){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(e.frameToStream){
|
if(e.frameToStream){
|
||||||
s.group[e.ke].mon[e.id].spawn.stdout.on('data',e.frameToStream)
|
if(e.coProcessor === true && e.details.stream_type === ('b64'||'mjpeg')){
|
||||||
|
|
||||||
|
}else{
|
||||||
|
s.group[e.ke].mon[e.id].spawn.stdout.on('data',e.frameToStream)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(e.details.stream_channels && e.details.stream_channels !== ''){
|
if(e.details.stream_channels && e.details.stream_channels !== ''){
|
||||||
var createStreamEmitter = function(channel,number){
|
var createStreamEmitter = function(channel,number){
|
||||||
|
@ -911,6 +966,12 @@ module.exports = function(s,config,lang){
|
||||||
s.group[e.ke].mon[e.id].spawn.stderr.on('data',function(d){
|
s.group[e.ke].mon[e.id].spawn.stderr.on('data',function(d){
|
||||||
d=d.toString();
|
d=d.toString();
|
||||||
switch(true){
|
switch(true){
|
||||||
|
// case checkLog(d,'No space left on device'):
|
||||||
|
//
|
||||||
|
// break;
|
||||||
|
case checkLog(d,'error while decoding'):
|
||||||
|
s.userLog(e,{type:lang['Error While Decoding'],msg:lang.ErrorWhileDecodingText});
|
||||||
|
break;
|
||||||
case checkLog(d,'[hls @'):
|
case checkLog(d,'[hls @'):
|
||||||
case checkLog(d,'Past duration'):
|
case checkLog(d,'Past duration'):
|
||||||
case checkLog(d,'Last message repeated'):
|
case checkLog(d,'Last message repeated'):
|
||||||
|
@ -938,6 +999,7 @@ module.exports = function(s,config,lang){
|
||||||
case checkLog(d,'mjpeg_decode_dc'):
|
case checkLog(d,'mjpeg_decode_dc'):
|
||||||
case checkLog(d,'bad vlc'):
|
case checkLog(d,'bad vlc'):
|
||||||
case checkLog(d,'error dc'):
|
case checkLog(d,'error dc'):
|
||||||
|
case checkLog(d,'No route to host'):
|
||||||
s.launchMonitorProcesses(e)
|
s.launchMonitorProcesses(e)
|
||||||
break;
|
break;
|
||||||
case /T[0-9][0-9]-[0-9][0-9]-[0-9][0-9]./.test(d):
|
case /T[0-9][0-9]-[0-9][0-9]-[0-9][0-9]./.test(d):
|
||||||
|
@ -999,7 +1061,7 @@ module.exports = function(s,config,lang){
|
||||||
e.detector_notrigger_timeout = parseFloat(e.details.detector_notrigger_timeout)*1000*60;
|
e.detector_notrigger_timeout = parseFloat(e.details.detector_notrigger_timeout)*1000*60;
|
||||||
s.group[e.ke].mon[e.id].detector_notrigger_timeout_function = function(){
|
s.group[e.ke].mon[e.id].detector_notrigger_timeout_function = function(){
|
||||||
s.onDetectorNoTriggerTimeoutExtensions.forEach(function(extender){
|
s.onDetectorNoTriggerTimeoutExtensions.forEach(function(extender){
|
||||||
extender(r,e)
|
extender(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
clearInterval(s.group[e.ke].mon[e.id].detector_notrigger_timeout)
|
clearInterval(s.group[e.ke].mon[e.id].detector_notrigger_timeout)
|
||||||
|
@ -1012,7 +1074,11 @@ module.exports = function(s,config,lang){
|
||||||
if(s.group[e.ke].mon[e.id].isStarted === true){
|
if(s.group[e.ke].mon[e.id].isStarted === true){
|
||||||
fs.stat(e.sdir+'s.jpg',function(err,snap){
|
fs.stat(e.sdir+'s.jpg',function(err,snap){
|
||||||
var notStreaming = function(){
|
var notStreaming = function(){
|
||||||
s.launchMonitorProcesses(e)
|
if(e.coProcessor === true){
|
||||||
|
s.coSpawnLauncher(e)
|
||||||
|
}else{
|
||||||
|
s.launchMonitorProcesses(e)
|
||||||
|
}
|
||||||
s.userLog(e,{type:lang['Camera is not streaming'],msg:{msg:lang['Restarting Process']}})
|
s.userLog(e,{type:lang['Camera is not streaming'],msg:{msg:lang['Restarting Process']}})
|
||||||
s.orphanedVideoCheck(e,2,null,true)
|
s.orphanedVideoCheck(e,2,null,true)
|
||||||
}
|
}
|
||||||
|
@ -1097,6 +1163,11 @@ module.exports = function(s,config,lang){
|
||||||
){
|
){
|
||||||
s.cameraFilterFfmpegLog(e)
|
s.cameraFilterFfmpegLog(e)
|
||||||
}
|
}
|
||||||
|
if(e.coProcessor === true){
|
||||||
|
setTimeout(function(){
|
||||||
|
s.coSpawnLauncher(e)
|
||||||
|
},6000)
|
||||||
|
}
|
||||||
s.onMonitorStartExtensions.forEach(function(extender){
|
s.onMonitorStartExtensions.forEach(function(extender){
|
||||||
extender(Object.assign(s.group[e.ke].mon_conf[e.id],{}),e)
|
extender(Object.assign(s.group[e.ke].mon_conf[e.id],{}),e)
|
||||||
})
|
})
|
||||||
|
@ -1435,8 +1506,8 @@ module.exports = function(s,config,lang){
|
||||||
s.group[e.ke].mon[e.mid].isRecording = false
|
s.group[e.ke].mon[e.mid].isRecording = false
|
||||||
}
|
}
|
||||||
//set up fatal error handler
|
//set up fatal error handler
|
||||||
if(e.details.fatal_max===''){
|
if(e.details.fatal_max === ''){
|
||||||
e.details.fatal_max = 10
|
e.details.fatal_max = 0
|
||||||
}else{
|
}else{
|
||||||
e.details.fatal_max = parseFloat(e.details.fatal_max)
|
e.details.fatal_max = parseFloat(e.details.fatal_max)
|
||||||
}
|
}
|
||||||
|
@ -1454,4 +1525,48 @@ module.exports = function(s,config,lang){
|
||||||
}
|
}
|
||||||
if(typeof cn === 'function'){setTimeout(function(){cn()},1000)}
|
if(typeof cn === 'function'){setTimeout(function(){cn()},1000)}
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
s.activateMonitorStates = function(groupKey,stateName,user,callback){
|
||||||
|
var endData = {
|
||||||
|
ok: false
|
||||||
|
}
|
||||||
|
s.findPreset([groupKey,'monitorStates',stateName],function(notFound,preset){
|
||||||
|
if(notFound === false){
|
||||||
|
var sqlQuery = 'SELECT * FROM Monitors WHERE ke=? AND '
|
||||||
|
var monitorQuery = []
|
||||||
|
var sqlQueryValues = [groupKey]
|
||||||
|
var monitorPresets = {}
|
||||||
|
preset.details.monitors.forEach(function(monitor){
|
||||||
|
monitorQuery.push('mid=?')
|
||||||
|
sqlQueryValues.push(monitor.mid)
|
||||||
|
monitorPresets[monitor.mid] = monitor
|
||||||
|
})
|
||||||
|
sqlQuery += '('+monitorQuery.join(' OR ')+')'
|
||||||
|
s.sqlQuery(sqlQuery,sqlQueryValues,function(err,monitors){
|
||||||
|
if(monitors && monitors[0]){
|
||||||
|
monitors.forEach(function(monitor){
|
||||||
|
s.checkDetails(monitor)
|
||||||
|
s.checkDetails(monitorPresets[monitor.mid])
|
||||||
|
var monitorPreset = monitorPresets[monitor.mid]
|
||||||
|
monitorPreset.details = Object.assign(monitor.details,monitorPreset.details)
|
||||||
|
monitor = s.cleanMonitorObjectForDatabase(Object.assign(monitor,monitorPreset))
|
||||||
|
monitor.details = JSON.stringify(monitor.details)
|
||||||
|
s.addOrEditMonitor(Object.assign(monitor,{}),function(err,endData){
|
||||||
|
|
||||||
|
},user)
|
||||||
|
})
|
||||||
|
endData.ok = true
|
||||||
|
s.tx({f:'change_group_state',ke:groupKey,name:stateName},'GRP_'+groupKey)
|
||||||
|
callback(endData)
|
||||||
|
}else{
|
||||||
|
endData.msg = user.lang['State Configuration has no monitors associated']
|
||||||
|
callback(endData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
endData.msg = user.lang['State Configuration Not Found']
|
||||||
|
callback(endData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
var fs = require("fs")
|
||||||
var Discord = require("discord.js")
|
var Discord = require("discord.js")
|
||||||
module.exports = function(s,config,lang){
|
module.exports = function(s,config,lang){
|
||||||
//discord bot
|
//discord bot
|
||||||
|
|
|
@ -0,0 +1,263 @@
|
||||||
|
module.exports = function(s,config,lang,app,io){
|
||||||
|
s.schedules = {}
|
||||||
|
//Get all Schedules
|
||||||
|
s.getAllSchedules = function(callback){
|
||||||
|
s.schedules = {}
|
||||||
|
s.sqlQuery('SELECT * FROM Schedules',function(err,rows){
|
||||||
|
rows.forEach(function(schedule){
|
||||||
|
s.updateSchedule(schedule)
|
||||||
|
})
|
||||||
|
if(callback)callback()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//update schedule
|
||||||
|
s.updateSchedule = function(row){
|
||||||
|
var schedule = Object.assign(row,{})
|
||||||
|
if(!s.schedules[schedule.ke])s.schedules[schedule.ke] = {}
|
||||||
|
s.checkDetails(schedule)
|
||||||
|
if(!s.schedules[schedule.ke][schedule.name]){
|
||||||
|
s.schedules[schedule.ke][schedule.name] = schedule
|
||||||
|
}else{
|
||||||
|
s.schedules[schedule.ke][schedule.name] = Object.assign(s.schedules[schedule.ke][schedule.name],schedule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//check time in schedule
|
||||||
|
s.checkTimeAgainstSchedule = function(start,end,callback){
|
||||||
|
try{
|
||||||
|
if(
|
||||||
|
start
|
||||||
|
){
|
||||||
|
var checkStartTime = new Date()
|
||||||
|
var startSplit = start.split(':')
|
||||||
|
var startHour = parseInt(startSplit[0])
|
||||||
|
var startMin = parseInt(startSplit[1])
|
||||||
|
checkStartTime.setHours(startHour)
|
||||||
|
checkStartTime.setMinutes(startMin)
|
||||||
|
if(end){
|
||||||
|
var checkEndTime = new Date()
|
||||||
|
var endSplit = end.split(':')
|
||||||
|
var endHour = parseInt(endSplit[0])
|
||||||
|
var endMin = parseInt(endSplit[1])
|
||||||
|
checkEndTime.setHours(endHour)
|
||||||
|
checkEndTime.setMinutes(endMin)
|
||||||
|
}
|
||||||
|
var currentDate = new Date()
|
||||||
|
if(
|
||||||
|
(
|
||||||
|
currentDate >= checkStartTime &&
|
||||||
|
currentDate <= checkEndTime
|
||||||
|
) ||
|
||||||
|
currentDate >= checkStartTime && !end
|
||||||
|
){
|
||||||
|
callback()
|
||||||
|
}else{
|
||||||
|
callback({
|
||||||
|
currentDate : currentDate,
|
||||||
|
startTime : checkStartTime,
|
||||||
|
endTime : checkEndTime
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
console.log(err)
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//check all Schedules
|
||||||
|
s.checkSchedules = function(v,callback){
|
||||||
|
var groupKeys = Object.keys(s.schedules)
|
||||||
|
groupKeys.forEach(function(key){
|
||||||
|
var scheduleNames = Object.keys(s.schedules[key])
|
||||||
|
scheduleNames.forEach(function(name){
|
||||||
|
var schedule = s.schedules[key][name]
|
||||||
|
if(!schedule.active && schedule.enabled === 1 && schedule.start && schedule.details.monitorStates){
|
||||||
|
s.checkTimeAgainstSchedule(schedule.start,schedule.end,function(err){
|
||||||
|
if(!err){
|
||||||
|
schedule.active = true
|
||||||
|
var monitorStates = schedule.details.monitorStates
|
||||||
|
monitorStates.forEach(function(stateName){
|
||||||
|
s.activateMonitorStates(key,stateName,{
|
||||||
|
ke: key,
|
||||||
|
uid: 'System',
|
||||||
|
details: {},
|
||||||
|
permissions: {},
|
||||||
|
lang: lang
|
||||||
|
},function(endData){
|
||||||
|
// console.log(endData)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
schedule.active = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//
|
||||||
|
s.findSchedule = function(groupKey,name,callback){
|
||||||
|
//presetQueryVals = [ke, type, name]
|
||||||
|
s.sqlQuery("SELECT * FROM Schedules WHERE ke=? AND name=? LIMIT 1",[groupKey,name],function(err,schedules){
|
||||||
|
var schedule
|
||||||
|
var notFound = false
|
||||||
|
if(schedules && schedules[0]){
|
||||||
|
schedule = schedules[0]
|
||||||
|
s.checkDetails(schedule)
|
||||||
|
}else{
|
||||||
|
notFound = true
|
||||||
|
}
|
||||||
|
callback(notFound,schedule)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//
|
||||||
|
var onProcessReady = function(){
|
||||||
|
s.getAllSchedules(function(){
|
||||||
|
s.checkSchedules()
|
||||||
|
})
|
||||||
|
setInterval(function(){
|
||||||
|
s.checkSchedules()
|
||||||
|
},1000 * 60 * 5)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* WebServerPath : API : Get Schedule
|
||||||
|
*/
|
||||||
|
app.all([
|
||||||
|
config.webPaths.apiPrefix+':auth/schedule/:ke',
|
||||||
|
config.webPaths.adminApiPrefix+':auth/schedule/:ke',
|
||||||
|
config.webPaths.apiPrefix+':auth/schedule/:ke/:name',
|
||||||
|
config.webPaths.adminApiPrefix+':auth/schedule/:ke/:name',
|
||||||
|
config.webPaths.apiPrefix+':auth/schedules/:ke',
|
||||||
|
config.webPaths.adminApiPrefix+':auth/schedules/:ke',
|
||||||
|
config.webPaths.apiPrefix+':auth/schedules/:ke/:name',
|
||||||
|
config.webPaths.adminApiPrefix+':auth/schedules/:ke/:name',
|
||||||
|
],function (req,res){
|
||||||
|
s.auth(req.params,function(user){
|
||||||
|
var endData = {
|
||||||
|
ok : false
|
||||||
|
}
|
||||||
|
if(user.details.sub){
|
||||||
|
endData.msg = user.lang['Not Permitted']
|
||||||
|
s.closeJsonResponse(res,endData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var theQuery = "SELECT * FROM Schedules WHERE ke=?"
|
||||||
|
var theQueryValues = [req.params.ke]
|
||||||
|
if(req.params.name){
|
||||||
|
theQuery += ' AND name=?'
|
||||||
|
theQueryValues.push(req.params.name)
|
||||||
|
}
|
||||||
|
s.sqlQuery(theQuery,theQueryValues,function(err,schedules){
|
||||||
|
if(schedules && schedules[0]){
|
||||||
|
endData.ok = true
|
||||||
|
schedules.forEach(function(schedule){
|
||||||
|
s.checkDetails(schedule)
|
||||||
|
})
|
||||||
|
endData.schedules = schedules
|
||||||
|
}else{
|
||||||
|
endData.msg = user.lang['Not Found']
|
||||||
|
}
|
||||||
|
s.closeJsonResponse(res,endData)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* WebServerPath : API : Update Schedule
|
||||||
|
*/
|
||||||
|
app.all([
|
||||||
|
config.webPaths.apiPrefix+':auth/schedule/:ke/:name/:action',
|
||||||
|
config.webPaths.adminApiPrefix+':auth/schedule/:ke/:name/:action',
|
||||||
|
config.webPaths.apiPrefix+':auth/schedules/:ke/:name/:action',
|
||||||
|
config.webPaths.adminApiPrefix+':auth/schedules/:ke/:name/:action'
|
||||||
|
],function (req,res){
|
||||||
|
s.auth(req.params,function(user){
|
||||||
|
var endData = {
|
||||||
|
ok : false
|
||||||
|
}
|
||||||
|
if(user.details.sub){
|
||||||
|
endData.msg = user.lang['Not Permitted']
|
||||||
|
s.closeJsonResponse(res,endData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch(req.params.action){
|
||||||
|
case'insert':case'edit':
|
||||||
|
var form = s.getPostData(req)
|
||||||
|
s.checkDetails(form)
|
||||||
|
if(!form || !form.details){
|
||||||
|
endData.msg = user.lang['Form Data Not Found']
|
||||||
|
s.closeJsonResponse(res,endData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
form.enabled = parseInt(form.enabled) || 1;
|
||||||
|
s.findSchedule(req.params.ke,req.params.name,function(notFound,preset){
|
||||||
|
if(notFound === true){
|
||||||
|
endData.msg = lang["Inserted Schedule Configuration"]
|
||||||
|
var insertData = {
|
||||||
|
ke: req.params.ke,
|
||||||
|
name: req.params.name,
|
||||||
|
details: s.stringJSON(form.details),
|
||||||
|
start: form.start,
|
||||||
|
end: form.end,
|
||||||
|
enabled: form.enabled
|
||||||
|
}
|
||||||
|
s.sqlQuery('INSERT INTO Schedules ('+Object.keys(insertData).join(',')+') VALUES (?,?,?,?,?,?)',Object.values(insertData))
|
||||||
|
s.tx({
|
||||||
|
f: 'add_schedule',
|
||||||
|
insertData: insertData,
|
||||||
|
ke: req.params.ke,
|
||||||
|
name: req.params.name
|
||||||
|
},'GRP_'+req.params.ke)
|
||||||
|
}else{
|
||||||
|
endData.msg = lang["Edited Schedule Configuration"]
|
||||||
|
var insertData = {
|
||||||
|
details: s.stringJSON(form.details),
|
||||||
|
start: form.start,
|
||||||
|
end: form.end,
|
||||||
|
enabled: form.enabled,
|
||||||
|
ke: req.params.ke,
|
||||||
|
name: req.params.name
|
||||||
|
}
|
||||||
|
s.sqlQuery('UPDATE Schedules SET details=?,start=?,end=?,enabled=? WHERE ke=? AND name=?',Object.values(insertData))
|
||||||
|
s.tx({
|
||||||
|
f: 'edit_schedule',
|
||||||
|
insertData: insertData,
|
||||||
|
ke: req.params.ke,
|
||||||
|
name: req.params.name
|
||||||
|
},'GRP_'+req.params.ke)
|
||||||
|
}
|
||||||
|
s.updateSchedule({
|
||||||
|
ke: req.params.ke,
|
||||||
|
name: req.params.name,
|
||||||
|
details: s.stringJSON(form.details),
|
||||||
|
start: form.start,
|
||||||
|
end: form.end,
|
||||||
|
enabled: form.enabled
|
||||||
|
})
|
||||||
|
endData.ok = true
|
||||||
|
s.closeJsonResponse(res,endData)
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case'delete':
|
||||||
|
s.findSchedule(req.params.ke,req.params.name,function(notFound,schedule){
|
||||||
|
if(notFound === true){
|
||||||
|
endData.msg = user.lang['Schedule Configuration Not Found']
|
||||||
|
s.closeJsonResponse(res,endData)
|
||||||
|
}else{
|
||||||
|
s.sqlQuery('DELETE FROM Schedules WHERE ke=? AND name=?',[req.params.ke,req.params.name],function(err){
|
||||||
|
if(!err){
|
||||||
|
endData.msg = lang["Deleted Schedule Configuration"]
|
||||||
|
endData.ok = true
|
||||||
|
if(s.schedules[schedule.ke])delete(s.schedules[schedule.ke][schedule.name])
|
||||||
|
}
|
||||||
|
s.closeJsonResponse(res,endData)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
//bind events
|
||||||
|
s.onProcessReady(onProcessReady)
|
||||||
|
}
|
|
@ -1365,7 +1365,7 @@ module.exports = function(s,config,lang,io){
|
||||||
if(cn.cron){
|
if(cn.cron){
|
||||||
delete(s.cron);
|
delete(s.cron);
|
||||||
}
|
}
|
||||||
if(cn.ocv){
|
if(cn.ocv && s.ocv){
|
||||||
s.tx({f:'detector_unplugged',plug:s.ocv.plug},'CPU')
|
s.tx({f:'detector_unplugged',plug:s.ocv.plug},'CPU')
|
||||||
delete(s.ocv);
|
delete(s.ocv);
|
||||||
delete(s.api[cn.id])
|
delete(s.api[cn.id])
|
||||||
|
|
10
libs/sql.js
10
libs/sql.js
|
@ -10,6 +10,12 @@ module.exports = function(s,config){
|
||||||
if(s.databaseOptions.client.indexOf('sqlite')>-1){
|
if(s.databaseOptions.client.indexOf('sqlite')>-1){
|
||||||
s.databaseOptions.client = 'sqlite3';
|
s.databaseOptions.client = 'sqlite3';
|
||||||
s.databaseOptions.useNullAsDefault = true;
|
s.databaseOptions.useNullAsDefault = true;
|
||||||
|
try{
|
||||||
|
require('sqlite3')
|
||||||
|
}catch(err){
|
||||||
|
console.log('Installing SQlite3 Module...')
|
||||||
|
require('child_process').execSync('npm install sqlite3 --unsafe-perm')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(s.databaseOptions.client === 'sqlite3' && s.databaseOptions.connection.filename === undefined){
|
if(s.databaseOptions.client === 'sqlite3' && s.databaseOptions.connection.filename === undefined){
|
||||||
s.databaseOptions.connection.filename = s.mainDirectory+"/shinobi.sqlite"
|
s.databaseOptions.connection.filename = s.mainDirectory+"/shinobi.sqlite"
|
||||||
|
@ -99,6 +105,10 @@ module.exports = function(s,config){
|
||||||
},true)
|
},true)
|
||||||
}
|
}
|
||||||
},true)
|
},true)
|
||||||
|
//add Schedules table, will remove in future
|
||||||
|
s.sqlQuery("CREATE TABLE IF NOT EXISTS `Schedules` (`ke` varchar(50) DEFAULT NULL,`name` text,`details` text,`start` varchar(10) DEFAULT NULL,`end` varchar(10) DEFAULT NULL,`enabled` int(1) NOT NULL DEFAULT '1')" + mySQLtail + ';',[],function(err){
|
||||||
|
if(err)console.error(err)
|
||||||
|
},true)
|
||||||
//add Cloud Videos table, will remove in future
|
//add Cloud Videos table, will remove in future
|
||||||
s.sqlQuery('CREATE TABLE IF NOT EXISTS `Cloud Videos` (`mid` varchar(50) NOT NULL,`ke` varchar(50) DEFAULT NULL,`href` text NOT NULL,`size` float DEFAULT NULL,`time` timestamp NULL DEFAULT NULL,`end` timestamp NULL DEFAULT NULL,`status` int(1) DEFAULT \'0\',`details` text)' + mySQLtail + ';',[],function(err){
|
s.sqlQuery('CREATE TABLE IF NOT EXISTS `Cloud Videos` (`mid` varchar(50) NOT NULL,`ke` varchar(50) DEFAULT NULL,`href` text NOT NULL,`size` float DEFAULT NULL,`time` timestamp NULL DEFAULT NULL,`end` timestamp NULL DEFAULT NULL,`status` int(1) DEFAULT \'0\',`details` text)' + mySQLtail + ';',[],function(err){
|
||||||
if(err)console.error(err)
|
if(err)console.error(err)
|
||||||
|
|
|
@ -4,16 +4,33 @@ var moment = require('moment');
|
||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
var exec = require('child_process').exec;
|
var exec = require('child_process').exec;
|
||||||
var execSync = require('child_process').execSync;
|
var execSync = require('child_process').execSync;
|
||||||
module.exports = function(s,config,lang,io,processReady){
|
module.exports = function(s,config,lang,io,){
|
||||||
console.log('FFmpeg version : '+s.ffmpegVersion)
|
console.log('FFmpeg version : '+s.ffmpegVersion)
|
||||||
console.log('Node.js version : '+execSync("node -v"))
|
console.log('Node.js version : '+execSync("node -v"))
|
||||||
s.processReady = function(){
|
s.processReady = function(){
|
||||||
s.systemLog(lang.startUpText5)
|
s.systemLog(lang.startUpText5)
|
||||||
process.send('ready')
|
|
||||||
s.onProcessReadyExtensions.forEach(function(extender){
|
s.onProcessReadyExtensions.forEach(function(extender){
|
||||||
extender(true)
|
extender(true)
|
||||||
})
|
})
|
||||||
if(processReady)processReady()
|
process.send('ready')
|
||||||
|
}
|
||||||
|
var checkForTerminalCommands = function(callback){
|
||||||
|
var next = function(){
|
||||||
|
if(callback)callback()
|
||||||
|
}
|
||||||
|
if(!s.isWin){
|
||||||
|
var etcPath = '/etc/shinobisystems/cctv.txt'
|
||||||
|
fs.stat(etcPath,function(err,stat){
|
||||||
|
if(err || !stat){
|
||||||
|
exec('node '+ s.mainDirectory + '/INSTALL/terminalCommands.js',function(err){
|
||||||
|
if(err)console.log(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
next()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var loadedAccounts = []
|
var loadedAccounts = []
|
||||||
var loadMonitors = function(callback){
|
var loadMonitors = function(callback){
|
||||||
|
@ -151,6 +168,9 @@ module.exports = function(s,config,lang,io,processReady){
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},10000)
|
},10000)
|
||||||
|
//hourly check to see if sizePurge has failed to unlock
|
||||||
|
//checks to see if request count is the number of monitors + 10
|
||||||
|
s.checkForStalePurgeLocks()
|
||||||
//run prerequsite queries, load users and monitors
|
//run prerequsite queries, load users and monitors
|
||||||
if(config.childNodes.mode !== 'child'){
|
if(config.childNodes.mode !== 'child'){
|
||||||
//sql/database connection with knex
|
//sql/database connection with knex
|
||||||
|
@ -158,11 +178,13 @@ module.exports = function(s,config,lang,io,processReady){
|
||||||
//run prerequsite queries
|
//run prerequsite queries
|
||||||
s.preQueries()
|
s.preQueries()
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
//load administrators (groups)
|
checkForTerminalCommands(function(){
|
||||||
loadAdminUsers(function(){
|
//load administrators (groups)
|
||||||
//load monitors (for groups)
|
loadAdminUsers(function(){
|
||||||
loadMonitors(function(){
|
//load monitors (for groups)
|
||||||
s.processReady()
|
loadMonitors(function(){
|
||||||
|
s.processReady()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},1500)
|
},1500)
|
||||||
|
|
49
libs/user.js
49
libs/user.js
|
@ -15,7 +15,7 @@ module.exports = function(s,config){
|
||||||
if(s.group[e.ke].sizePurgeQueue.length > 0){
|
if(s.group[e.ke].sizePurgeQueue.length > 0){
|
||||||
checkQueue()
|
checkQueue()
|
||||||
}else{
|
}else{
|
||||||
s.group[e.ke].sizePurging=false
|
s.group[e.ke].sizePurging = false
|
||||||
s.sendDiskUsedAmountToClients(e)
|
s.sendDiskUsedAmountToClients(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,11 +260,11 @@ module.exports = function(s,config){
|
||||||
d.form.details.use_admin=d.d.use_admin
|
d.form.details.use_admin=d.d.use_admin
|
||||||
d.form.details.use_ldap=d.d.use_ldap
|
d.form.details.use_ldap=d.d.use_ldap
|
||||||
//check
|
//check
|
||||||
if(d.d.edit_days=="0"){
|
if(d.d.edit_days == "0"){
|
||||||
d.form.details.days=d.d.days;
|
d.form.details.days = d.d.days;
|
||||||
}
|
}
|
||||||
if(d.d.edit_size=="0"){
|
if(d.d.edit_size == "0"){
|
||||||
d.form.details.size=d.d.size;
|
d.form.details.size = d.d.size;
|
||||||
}
|
}
|
||||||
if(d.d.sub){
|
if(d.d.sub){
|
||||||
d.form.details.sub=d.d.sub;
|
d.form.details.sub=d.d.sub;
|
||||||
|
@ -308,4 +308,43 @@ module.exports = function(s,config){
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
s.findPreset = function(presetQueryVals,callback){
|
||||||
|
//presetQueryVals = [ke, type, name]
|
||||||
|
s.sqlQuery("SELECT * FROM Presets WHERE ke=? AND type=? AND name=? LIMIT 1",presetQueryVals,function(err,presets){
|
||||||
|
var preset
|
||||||
|
var notFound = false
|
||||||
|
if(presets && presets[0]){
|
||||||
|
preset = presets[0]
|
||||||
|
s.checkDetails(preset)
|
||||||
|
}else{
|
||||||
|
notFound = true
|
||||||
|
}
|
||||||
|
callback(notFound,preset)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(config.cron.deleteOverMax === true){
|
||||||
|
s.checkForStalePurgeLocks = function(){
|
||||||
|
var doCheck = function(){
|
||||||
|
Object.keys(s.group).forEach(function(groupKey){
|
||||||
|
var userGroup = s.group[groupKey]
|
||||||
|
var monitorCount = 10
|
||||||
|
if(userGroup.mon)monitorCount = Object.keys(userGroup.mon).length
|
||||||
|
var purgeRequestCount = userGroup.sizePurgeQueue.length
|
||||||
|
var isLocked = (userGroup.sizePurging === true)
|
||||||
|
if(isLocked && purgeRequestCount > monitorCount + 10){
|
||||||
|
s.group[groupKey].sizePurgeQueue = []
|
||||||
|
s.group[groupKey].sizePurging = false
|
||||||
|
s.systemLog(lang.sizePurgeLockedText + ' : ' + groupKey)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
clearTimeout(s.checkForStalePurgeLocksInterval)
|
||||||
|
s.checkForStalePurgeLocksInterval = setInterval(function(){
|
||||||
|
doCheck()
|
||||||
|
},1000 * 60 * 60)
|
||||||
|
doCheck()
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
s.checkForStalePurgeLocks = function(){}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,19 +419,7 @@ module.exports = function(s,config,lang,app){
|
||||||
s.closeJsonResponse(res,endData)
|
s.closeJsonResponse(res,endData)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var findPreset = function(callback){
|
var presetQueryVals = [req.params.ke,'monitorStates',req.params.stateName]
|
||||||
s.sqlQuery("SELECT * FROM Presets WHERE ke=? AND type=? AND name=? LIMIT 1",[req.params.ke,'monitorStates',req.params.stateName],function(err,presets){
|
|
||||||
var preset
|
|
||||||
var notFound = false
|
|
||||||
if(presets && presets[0]){
|
|
||||||
preset = presets[0]
|
|
||||||
s.checkDetails(preset)
|
|
||||||
}else{
|
|
||||||
notFound = true
|
|
||||||
}
|
|
||||||
callback(notFound,preset)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
switch(req.params.action){
|
switch(req.params.action){
|
||||||
case'insert':case'edit':
|
case'insert':case'edit':
|
||||||
var form = s.getPostData(req)
|
var form = s.getPostData(req)
|
||||||
|
@ -441,7 +429,7 @@ module.exports = function(s,config,lang,app){
|
||||||
s.closeJsonResponse(res,endData)
|
s.closeJsonResponse(res,endData)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
findPreset(function(notFound,preset){
|
s.findPreset(presetQueryVals,function(notFound,preset){
|
||||||
if(notFound === true){
|
if(notFound === true){
|
||||||
endData.msg = lang["Inserted State Configuration"]
|
endData.msg = lang["Inserted State Configuration"]
|
||||||
var details = {
|
var details = {
|
||||||
|
@ -478,7 +466,7 @@ module.exports = function(s,config,lang,app){
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
case'delete':
|
case'delete':
|
||||||
findPreset(function(notFound,preset){
|
s.findPreset(presetQueryVals,function(notFound,preset){
|
||||||
if(notFound === true){
|
if(notFound === true){
|
||||||
endData.msg = user.lang['State Configuration Not Found']
|
endData.msg = user.lang['State Configuration Not Found']
|
||||||
s.closeJsonResponse(res,endData)
|
s.closeJsonResponse(res,endData)
|
||||||
|
@ -494,43 +482,8 @@ module.exports = function(s,config,lang,app){
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
default://change monitors according to state
|
default://change monitors according to state
|
||||||
findPreset(function(notFound,preset){
|
s.activateMonitorStates(req.params.ke,req.params.stateName,user,function(endData){
|
||||||
if(notFound === false){
|
s.closeJsonResponse(res,endData)
|
||||||
var sqlQuery = 'SELECT * FROM Monitors WHERE ke=? AND '
|
|
||||||
var monitorQuery = []
|
|
||||||
var sqlQueryValues = [req.params.ke]
|
|
||||||
var monitorPresets = {}
|
|
||||||
preset.details.monitors.forEach(function(monitor){
|
|
||||||
monitorQuery.push('mid=?')
|
|
||||||
sqlQueryValues.push(monitor.mid)
|
|
||||||
monitorPresets[monitor.mid] = monitor
|
|
||||||
})
|
|
||||||
sqlQuery += '('+monitorQuery.join(' OR ')+')'
|
|
||||||
s.sqlQuery(sqlQuery,sqlQueryValues,function(err,monitors){
|
|
||||||
if(monitors && monitors[0]){
|
|
||||||
monitors.forEach(function(monitor){
|
|
||||||
s.checkDetails(monitor)
|
|
||||||
s.checkDetails(monitorPresets[monitor.mid])
|
|
||||||
var monitorPreset = monitorPresets[monitor.mid]
|
|
||||||
monitorPreset.details = Object.assign(monitor.details,monitorPreset.details)
|
|
||||||
monitor = s.cleanMonitorObjectForDatabase(Object.assign(monitor,monitorPreset))
|
|
||||||
monitor.details = JSON.stringify(monitor.details)
|
|
||||||
s.addOrEditMonitor(Object.assign(monitor,{}),function(err,endData){
|
|
||||||
|
|
||||||
},user)
|
|
||||||
})
|
|
||||||
endData.ok = true
|
|
||||||
s.tx({f:'change_group_state',ke:req.params.ke,name:req.params.stateName},'GRP_'+req.params.ke)
|
|
||||||
s.closeJsonResponse(res,endData)
|
|
||||||
}else{
|
|
||||||
endData.msg = user.lang['State Configuration has no monitors associated']
|
|
||||||
s.closeJsonResponse(res,endData)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
endData.msg = user.lang['State Configuration Not Found']
|
|
||||||
s.closeJsonResponse(res,endData)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ var execSync = require('child_process').execSync;
|
||||||
var exec = require('child_process').exec;
|
var exec = require('child_process').exec;
|
||||||
var spawn = require('child_process').spawn;
|
var spawn = require('child_process').spawn;
|
||||||
var httpProxy = require('http-proxy');
|
var httpProxy = require('http-proxy');
|
||||||
|
var onvif = require('node-onvif');
|
||||||
var proxy = httpProxy.createProxyServer({})
|
var proxy = httpProxy.createProxyServer({})
|
||||||
var ejs = require('ejs');
|
var ejs = require('ejs');
|
||||||
var CircularJSON = require('circular-json');
|
var CircularJSON = require('circular-json');
|
||||||
|
@ -286,7 +287,8 @@ module.exports = function(s,config,lang,app,io){
|
||||||
// config: config,
|
// config: config,
|
||||||
$user: req.resp,
|
$user: req.resp,
|
||||||
lang: r.lang,
|
lang: r.lang,
|
||||||
define: s.getDefinitonFile(r.details.lang)
|
define: s.getDefinitonFile(r.details.lang),
|
||||||
|
customAutoLoad: s.customAutoLoadTree
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
|
@ -297,7 +299,8 @@ module.exports = function(s,config,lang,app,io){
|
||||||
// config: config,
|
// config: config,
|
||||||
$user: req.resp,
|
$user: req.resp,
|
||||||
lang: r.lang,
|
lang: r.lang,
|
||||||
define: s.getDefinitonFile(r.details.lang)
|
define: s.getDefinitonFile(r.details.lang),
|
||||||
|
customAutoLoad: s.customAutoLoadTree
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
|
@ -311,17 +314,36 @@ module.exports = function(s,config,lang,app,io){
|
||||||
$subs: rr,
|
$subs: rr,
|
||||||
$mons: rrr,
|
$mons: rrr,
|
||||||
lang: r.lang,
|
lang: r.lang,
|
||||||
define: s.getDefinitonFile(r.details.lang)
|
define: s.getDefinitonFile(r.details.lang),
|
||||||
|
customAutoLoad: s.customAutoLoadTree
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}else{
|
}else{
|
||||||
//not admin user
|
//not admin user
|
||||||
renderPage(config.renderPaths.home,{$user:req.resp,config:config,lang:r.lang,define:s.getDefinitonFile(r.details.lang),addStorage:s.dir.addStorage,fs:fs,__dirname:s.mainDirectory});
|
renderPage(config.renderPaths.home,{
|
||||||
|
$user:req.resp,
|
||||||
|
config:config,
|
||||||
|
lang:r.lang,
|
||||||
|
define:s.getDefinitonFile(r.details.lang),
|
||||||
|
addStorage:s.dir.addStorage,
|
||||||
|
fs:fs,
|
||||||
|
__dirname:s.mainDirectory,
|
||||||
|
customAutoLoad: s.customAutoLoadTree
|
||||||
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
renderPage(config.renderPaths.home,{$user:req.resp,config:config,lang:r.lang,define:s.getDefinitonFile(r.details.lang),addStorage:s.dir.addStorage,fs:fs,__dirname:s.mainDirectory});
|
renderPage(config.renderPaths.home,{
|
||||||
|
$user:req.resp,
|
||||||
|
config:config,
|
||||||
|
lang:r.lang,
|
||||||
|
define:s.getDefinitonFile(r.details.lang),
|
||||||
|
addStorage:s.dir.addStorage,
|
||||||
|
fs:fs,
|
||||||
|
__dirname:s.mainDirectory,
|
||||||
|
customAutoLoad: s.customAutoLoadTree
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
s.userLog({ke:r.ke,mid:'$USER'},{type:r.lang['New Authentication Token'],msg:{for:req.body.function,mail:r.mail,id:r.uid,ip:req.ip}})
|
s.userLog({ke:r.ke,mid:'$USER'},{type:r.lang['New Authentication Token'],msg:{for:req.body.function,mail:r.mail,id:r.uid,ip:req.ip}})
|
||||||
|
@ -511,6 +533,7 @@ module.exports = function(s,config,lang,app,io){
|
||||||
r=[]
|
r=[]
|
||||||
}
|
}
|
||||||
data.Logs = r
|
data.Logs = r
|
||||||
|
data.customAutoLoad = s.customAutoLoadTree
|
||||||
fs.readFile(s.location.config,'utf8',function(err,file){
|
fs.readFile(s.location.config,'utf8',function(err,file){
|
||||||
data.plainConfig = JSON.parse(file)
|
data.plainConfig = JSON.parse(file)
|
||||||
renderPage(config.renderPaths.super,data)
|
renderPage(config.renderPaths.super,data)
|
||||||
|
@ -1375,7 +1398,7 @@ module.exports = function(s,config,lang,app,io){
|
||||||
values.push(time)
|
values.push(time)
|
||||||
})
|
})
|
||||||
s.sqlQuery('SELECT * FROM Videos WHERE '+where.join(' OR '),values,function(err,r){
|
s.sqlQuery('SELECT * FROM Videos WHERE '+where.join(' OR '),values,function(err,r){
|
||||||
var resp = {ok:false}
|
var resp = {ok: false}
|
||||||
if(r && r[0]){
|
if(r && r[0]){
|
||||||
resp.ok = true
|
resp.ok = true
|
||||||
var zipDownload = null
|
var zipDownload = null
|
||||||
|
@ -1396,7 +1419,7 @@ module.exports = function(s,config,lang,app,io){
|
||||||
fs.mkdirSync(fileBinDir);
|
fs.mkdirSync(fileBinDir);
|
||||||
}
|
}
|
||||||
r.forEach(function(video){
|
r.forEach(function(video){
|
||||||
timeFormatted = s.formattedTime(video.time)
|
var timeFormatted = s.formattedTime(video.time)
|
||||||
video.filename = timeFormatted+'.'+video.ext
|
video.filename = timeFormatted+'.'+video.ext
|
||||||
var dir = s.getVideoDirectory(video)+video.filename
|
var dir = s.getVideoDirectory(video)+video.filename
|
||||||
var tempVideoFile = timeFormatted+' - '+video.mid+'.'+video.ext
|
var tempVideoFile = timeFormatted+' - '+video.mid+'.'+video.ext
|
||||||
|
@ -1418,16 +1441,27 @@ module.exports = function(s,config,lang,app,io){
|
||||||
var zipDownload = fs.createReadStream(zippedFile)
|
var zipDownload = fs.createReadStream(zippedFile)
|
||||||
zipDownload.pipe(res)
|
zipDownload.pipe(res)
|
||||||
zipDownload.on('error', function (error) {
|
zipDownload.on('error', function (error) {
|
||||||
s.userLog({ke:req.params.ke,mid:'$USER'},{title:'Zip Download Error',msg:error.toString()})
|
var errorString = error.toString()
|
||||||
|
s.userLog({
|
||||||
|
ke: req.params.ke,
|
||||||
|
mid: '$USER'
|
||||||
|
},{
|
||||||
|
title: 'Zip Download Error',
|
||||||
|
msg: errorString
|
||||||
|
})
|
||||||
if(zipDownload && zipDownload.destroy){
|
if(zipDownload && zipDownload.destroy){
|
||||||
zipDownload.destroy()
|
zipDownload.destroy()
|
||||||
}
|
}
|
||||||
});
|
res.end(s.prettyPrint({
|
||||||
|
ok: false,
|
||||||
|
msg: errorString
|
||||||
|
}))
|
||||||
|
})
|
||||||
zipDownload.on('close', function () {
|
zipDownload.on('close', function () {
|
||||||
res.end()
|
res.end()
|
||||||
zipDownload.destroy();
|
zipDownload.destroy()
|
||||||
fs.unlinkSync(zippedFile);
|
fs.unlinkSync(zippedFile)
|
||||||
});
|
})
|
||||||
})
|
})
|
||||||
}else{
|
}else{
|
||||||
failed({ok:false,msg:'No Videos Found'})
|
failed({ok:false,msg:'No Videos Found'})
|
||||||
|
@ -1437,7 +1471,121 @@ module.exports = function(s,config,lang,app,io){
|
||||||
}else{
|
}else{
|
||||||
failed({ok:false,msg:'"videos" query variable is missing from request.'})
|
failed({ok:false,msg:'"videos" query variable is missing from request.'})
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
/**
|
||||||
|
* API : Zip Cloud Videos and Get Link from fileBin
|
||||||
|
*/
|
||||||
|
app.get(config.webPaths.apiPrefix+':auth/zipCloudVideos/:ke', function (req,res){
|
||||||
|
res.header("Access-Control-Allow-Origin",req.headers.origin);
|
||||||
|
var failed = function(resp){
|
||||||
|
res.setHeader('Content-Type', 'application/json');
|
||||||
|
res.end(s.prettyPrint(resp))
|
||||||
|
}
|
||||||
|
if(req.query.videos && req.query.videos !== ''){
|
||||||
|
s.auth(req.params,function(user){
|
||||||
|
var videosSelected = JSON.parse(req.query.videos)
|
||||||
|
var where = []
|
||||||
|
var values = []
|
||||||
|
videosSelected.forEach(function(video){
|
||||||
|
where.push("(ke=? AND mid=? AND `time`=?)")
|
||||||
|
if(!video.ke)video.ke = req.params.ke
|
||||||
|
values.push(video.ke)
|
||||||
|
values.push(video.mid)
|
||||||
|
var time = s.nameToTime(video.filename)
|
||||||
|
if(req.query.isUTC === 'true'){
|
||||||
|
time = s.utcToLocal(time)
|
||||||
|
}
|
||||||
|
time = new Date(time)
|
||||||
|
values.push(time)
|
||||||
|
})
|
||||||
|
s.sqlQuery('SELECT * FROM `Cloud Videos` WHERE '+where.join(' OR '),values,function(err,r){
|
||||||
|
var resp = {ok: false}
|
||||||
|
if(r && r[0]){
|
||||||
|
resp.ok = true
|
||||||
|
var zipDownload = null
|
||||||
|
var tempFiles = []
|
||||||
|
var fileId = s.gid()
|
||||||
|
var fileBinDir = s.dir.fileBin+req.params.ke+'/'
|
||||||
|
var tempScript = s.dir.streams+req.params.ke+'/'+fileId+'.sh'
|
||||||
|
var zippedFilename = s.formattedTime()+'-'+fileId+'-Shinobi_Cloud_Backed_Recordings.zip'
|
||||||
|
var zippedFile = fileBinDir+zippedFilename
|
||||||
|
var script = 'cd '+fileBinDir+' && zip -9 -r '+zippedFile
|
||||||
|
res.on('close', () => {
|
||||||
|
if(zipDownload && zipDownload.destroy){
|
||||||
|
zipDownload.destroy()
|
||||||
|
}
|
||||||
|
fs.unlink(zippedFile);
|
||||||
|
})
|
||||||
|
if(!fs.existsSync(fileBinDir)){
|
||||||
|
fs.mkdirSync(fileBinDir);
|
||||||
|
}
|
||||||
|
var cloudDownloadCount = 0
|
||||||
|
var getFile = function(video,completed){
|
||||||
|
if(!video)completed();
|
||||||
|
s.checkDetails(video)
|
||||||
|
var filename = video.href.split('/')
|
||||||
|
filename = filename[filename.length - 1]
|
||||||
|
var timeFormatted = s.formattedTime(video.time)
|
||||||
|
var tempVideoFile = video.details.type + '-' + video.mid + '-' + filename
|
||||||
|
var tempFileWriteStream = fs.createWriteStream(fileBinDir+tempVideoFile)
|
||||||
|
tempFileWriteStream.on('finish', function() {
|
||||||
|
++cloudDownloadCount
|
||||||
|
getFile(r[cloudDownloadCount],completed)
|
||||||
|
})
|
||||||
|
var cloudVideoDownload = request(video.href)
|
||||||
|
cloudVideoDownload.on('response', function (res) {
|
||||||
|
res.pipe(tempFileWriteStream)
|
||||||
|
})
|
||||||
|
tempFiles.push(fileBinDir+tempVideoFile)
|
||||||
|
script += ' "'+tempVideoFile+'"'
|
||||||
|
}
|
||||||
|
getFile(r[cloudDownloadCount],function(){
|
||||||
|
fs.writeFileSync(tempScript,script,'utf8')
|
||||||
|
var zipCreate = spawn('sh',(tempScript).split(' '),{detached: true})
|
||||||
|
zipCreate.stderr.on('data',function(data){
|
||||||
|
s.userLog({ke:req.params.ke,mid:'$USER'},{title:'Zip Create Error',msg:data.toString()})
|
||||||
|
})
|
||||||
|
zipCreate.on('exit',function(data){
|
||||||
|
fs.unlinkSync(tempScript)
|
||||||
|
tempFiles.forEach(function(file){
|
||||||
|
fs.unlink(file,function(){})
|
||||||
|
})
|
||||||
|
res.setHeader('Content-Disposition', 'attachment; filename="' + zippedFilename + '"')
|
||||||
|
var zipDownload = fs.createReadStream(zippedFile)
|
||||||
|
zipDownload.pipe(res)
|
||||||
|
zipDownload.on('error', function (error) {
|
||||||
|
var errorString = error.toString()
|
||||||
|
s.userLog({
|
||||||
|
ke: req.params.ke,
|
||||||
|
mid: '$USER'
|
||||||
|
},{
|
||||||
|
title: 'Zip Download Error',
|
||||||
|
msg: errorString
|
||||||
|
})
|
||||||
|
if(zipDownload && zipDownload.destroy){
|
||||||
|
zipDownload.destroy()
|
||||||
|
}
|
||||||
|
res.end(s.prettyPrint({
|
||||||
|
ok: false,
|
||||||
|
msg: errorString
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
zipDownload.on('close', function () {
|
||||||
|
res.end()
|
||||||
|
zipDownload.destroy()
|
||||||
|
fs.unlinkSync(zippedFile)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
failed({ok:false,msg:'No Videos Found'})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},res,req);
|
||||||
|
}else{
|
||||||
|
failed({ok:false,msg:'"videos" query variable is missing from request.'})
|
||||||
|
}
|
||||||
|
})
|
||||||
/**
|
/**
|
||||||
* API : Get Cloud Video File (proxy)
|
* API : Get Cloud Video File (proxy)
|
||||||
*/
|
*/
|
||||||
|
@ -1524,27 +1672,34 @@ module.exports = function(s,config,lang,app,io){
|
||||||
/**
|
/**
|
||||||
* API : Motion Trigger via GET request
|
* API : Motion Trigger via GET request
|
||||||
*/
|
*/
|
||||||
app.get(config.webPaths.apiPrefix+':auth/motion/:ke/:id', function (req,res){
|
app.get(config.webPaths.apiPrefix+':auth/motion/:ke/:id', function (req,res){
|
||||||
s.auth(req.params,function(user){
|
s.auth(req.params,function(user){
|
||||||
if(req.query.data){
|
var endData = {
|
||||||
try{
|
|
||||||
var d={id:req.params.id,ke:req.params.ke,details:JSON.parse(req.query.data)};
|
}
|
||||||
}catch(err){
|
if(req.query.data){
|
||||||
res.end('Data Broken',err);
|
try{
|
||||||
return;
|
var d = {
|
||||||
}
|
id: req.params.id,
|
||||||
}else{
|
ke: req.params.ke,
|
||||||
res.end('No Data');
|
details: JSON.parse(req.query.data)
|
||||||
return;
|
}
|
||||||
}
|
}catch(err){
|
||||||
if(!d.ke||!d.id||!s.group[d.ke]){
|
res.end('Data Broken',err)
|
||||||
res.end(user.lang['No Group with this key exists']);
|
return
|
||||||
return;
|
}
|
||||||
}
|
}else{
|
||||||
s.triggerEvent(d)
|
res.end('No Data')
|
||||||
res.end(user.lang['Trigger Successful'])
|
return
|
||||||
},res,req);
|
}
|
||||||
})
|
if(!d.ke||!d.id||!s.group[d.ke]){
|
||||||
|
res.end(user.lang['No Group with this key exists'])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.triggerEvent(d)
|
||||||
|
res.end(user.lang['Trigger Successful'])
|
||||||
|
},res,req)
|
||||||
|
})
|
||||||
/**
|
/**
|
||||||
* API : WebHook Tester
|
* API : WebHook Tester
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -622,4 +622,16 @@ module.exports = function(s,config,lang,app){
|
||||||
}
|
}
|
||||||
},res,req)
|
},res,req)
|
||||||
})
|
})
|
||||||
|
/**
|
||||||
|
* API : Superuser : Force Check for Stale Purge Locks
|
||||||
|
*/
|
||||||
|
app.all(config.webPaths.superApiPrefix+':auth/system/checkForStalePurgeLocks', function (req,res){
|
||||||
|
s.superAuth(req.params,function(resp){
|
||||||
|
var endData = {
|
||||||
|
ok : true
|
||||||
|
}
|
||||||
|
s.checkForStalePurgeLocks()
|
||||||
|
res.end(s.prettyPrint(endData))
|
||||||
|
},res,req)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
29
package.json
29
package.json
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "shinobi",
|
"name": "shinobi",
|
||||||
"productName": "Shinobi",
|
"productName": "Shinobi",
|
||||||
"version": "1.0.38",
|
"version": "2.0.0",
|
||||||
"description": "CCTV and NVR in Node.js",
|
"description": "CCTV and NVR in Node.js",
|
||||||
"main": "camera.js",
|
"main": "camera.js",
|
||||||
"bin": "camera.js",
|
"bin": "camera.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node test.js",
|
"test": "node camera.js test",
|
||||||
"start": "chmod +x INSTALL/start.sh && INSTALL/start.sh"
|
"start": "chmod +x INSTALL/start.sh && INSTALL/start.sh"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -19,30 +19,33 @@
|
||||||
},
|
},
|
||||||
"homepage": "https://gitlab.com/Shinobi-Systems/Shinobi#readme",
|
"homepage": "https://gitlab.com/Shinobi-Systems/Shinobi#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"aws-sdk": "^2.279.1",
|
||||||
|
"backblaze-b2": "^1.0.4",
|
||||||
"body-parser": "^1.15.2",
|
"body-parser": "^1.15.2",
|
||||||
"circular-json": "0.3.1",
|
"circular-json": "0.3.1",
|
||||||
"connection-tester": "^0.1.1",
|
"connection-tester": "^0.1.1",
|
||||||
"mp4frag": "^0.0.22",
|
"discord.js": "^11.3.2",
|
||||||
"ejs": "^2.5.5",
|
"ejs": "^2.5.5",
|
||||||
"express": "^4.14.0",
|
"express": "^4.14.0",
|
||||||
|
"http-proxy": "^1.17.0",
|
||||||
"jsonfile": "^3.0.1",
|
"jsonfile": "^3.0.1",
|
||||||
"moment": "^2.17.0",
|
|
||||||
"mysql": "^2.12.0",
|
|
||||||
"knex": "^0.14.2",
|
"knex": "^0.14.2",
|
||||||
"aws-sdk": "^2.279.1",
|
"ldapauth-fork": "^4.0.2",
|
||||||
"pam-diff": "^0.10.2",
|
"moment": "^2.17.0",
|
||||||
"pipe2pam": "^0.6.2",
|
"mp4frag": "^0.0.22",
|
||||||
"nodemailer": "^4.0.1",
|
"mysql": "^2.12.0",
|
||||||
"node-onvif": "^0.1.4",
|
"node-onvif": "^0.1.4",
|
||||||
|
"nodemailer": "^4.0.1",
|
||||||
|
"pam-diff": "^0.10.2",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
|
"pipe2pam": "^0.6.2",
|
||||||
"request": "^2.79.0",
|
"request": "^2.79.0",
|
||||||
"socket.io": "^1.7.1",
|
"socket.io": "^1.7.1",
|
||||||
"socket.io-client": "^1.7.2",
|
"socket.io-client": "^1.7.2",
|
||||||
"http-proxy": "^1.17.0",
|
"sqlite3": "^4.0.4",
|
||||||
"webdav-fs": "^1.11.0",
|
"webdav-fs": "^1.11.0",
|
||||||
"discord.js": "^11.3.2",
|
"sat": "^0.7.1",
|
||||||
"backblaze-b2": "^1.0.4",
|
"shinobi-sound-detection": "^0.1.7"
|
||||||
"ldapauth-fork": "^4.0.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {}
|
"devDependencies": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
DIR=`dirname $0`
|
||||||
|
INSTALLERS_DIR="$DIR/../../INSTALL"
|
||||||
|
if ! [ -x "$(command -v dos2unix)" ]; then
|
||||||
|
echo "-----------------------------------"
|
||||||
|
echo "Installing dos2unix"
|
||||||
|
apt install dos2unix -y
|
||||||
|
fi
|
||||||
|
echo "-----------------------------------"
|
||||||
|
if ! [ -x "$(command -v alpr)" ]; then
|
||||||
|
echo "Installing OpenALPR"
|
||||||
|
echo "Do you want to Install OpenALPR with CUDA enabled?"
|
||||||
|
echo "(Y)es or (n)o?"
|
||||||
|
echo "Press [ENTER] for default (Yes)"
|
||||||
|
read openalprcudaenabled
|
||||||
|
if [ "$openalprcudaenabled" = "n" ] || [ "$openalprcudaenabled" = "N" ]; then
|
||||||
|
sed -i -e 's/detector = lbpgpu/detector = lbpcpu/g' "$DIR/openalpr.conf"
|
||||||
|
dos2unix $INSTALLERS_DIR/openalpr-cpu-easy.sh
|
||||||
|
sh $INSTALLERS_DIR/openalpr-cpu-easy.sh
|
||||||
|
else
|
||||||
|
sed -i -e 's/detector = lbpcpu/detector = lbpgpu/g' "$DIR/openalpr.conf"
|
||||||
|
dos2unix $INSTALLERS_DIR/openalpr-gpu-easy.sh
|
||||||
|
sh $INSTALLERS_DIR/openalpr-gpu-easy.sh
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "OpenALPR found... : $(alpr --version)"
|
||||||
|
fi
|
||||||
|
echo "-----------------------------------"
|
||||||
|
if [ ! -e "$DIR/conf.json" ]; then
|
||||||
|
echo "Creating conf.json"
|
||||||
|
cp $DIR/conf.sample.json $DIR/conf.json
|
||||||
|
else
|
||||||
|
echo "conf.json already exists..."
|
||||||
|
fi
|
||||||
|
echo "-----------------------------------"
|
||||||
|
echo "Installing Modules.."
|
||||||
|
npm install --unsafe-perm
|
||||||
|
echo "Finding and Fixing Module Vulnerabilities.."
|
||||||
|
npm audit fix --force
|
||||||
|
echo "Shinobi - Do you want to start the plugin?"
|
||||||
|
echo "(Y)es or (n)o?"
|
||||||
|
echo "Press [ENTER] for default (Yes)"
|
||||||
|
read startplugin
|
||||||
|
if [ "$startplugin" = "n" ] || [ "$startplugin" = "N" ]; then
|
||||||
|
echo "-----------------------------------"
|
||||||
|
echo "Start the plugin with pm2 like so :"
|
||||||
|
echo "pm2 start $DIR/shinobi-openalpr.js"
|
||||||
|
echo "-----------------------------------"
|
||||||
|
echo "Start the plugin without pm2 :"
|
||||||
|
echo "node $DIR/shinobi-openalpr.js"
|
||||||
|
else
|
||||||
|
pm2 start shinobi-openalpr.js
|
||||||
|
pm2 save
|
||||||
|
fi
|
|
@ -1,49 +1,32 @@
|
||||||
# OpenALPR and Motion Detector
|
# OpenALPR
|
||||||
|
|
||||||
Install required libraries.
|
Install required libraries.
|
||||||
|
|
||||||
**Ubuntu and Debian only**
|
**Ubuntu 17.10 and 18.04 only**
|
||||||
|
|
||||||
```
|
> By default plugins run as a client. `camera.js` is running as the host awaiting a plugin to connect to it. To learn about how to connect a plugin as a Host please review the "Run the plugin as a Host" section at the end of this README.
|
||||||
sudo apt update && sudo apt install libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev build-essential g++ openalpr openalpr-daemon openalpr-utils libopenalpr-dev -y
|
|
||||||
```
|
|
||||||
|
|
||||||
**Install the Node.js Canvas engine**
|
1. Go to the plugin's directory and run the installer for OpenALPR. **/home/Shinobi** is the default directory for where Shinobi is installed.
|
||||||
|
```
|
||||||
|
cd /home/Shinobi/plugins/openalpr
|
||||||
|
sh INSTALL.sh
|
||||||
|
```
|
||||||
|
|
||||||
```
|
2. Then add the plugin key to the **Main Configuration** file, the `conf.json` located in **/home/Shinobi**. You will find the `pluginKeys` object empty on a new install as seen below.
|
||||||
sudo npm install canvas@1.6
|
```
|
||||||
```
|
"pluginKeys":{}
|
||||||
Go to the Shinobi directory. **Below is an example.**
|
```
|
||||||
|
> Add the key so it looks something like this.
|
||||||
|
|
||||||
```
|
```
|
||||||
cd /home/Shinobi
|
"pluginKeys":{
|
||||||
```
|
"OpenALPR": "SomeOpenALPRkeySoPeopleDontMessWithYourShinobi"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Copy the config file.
|
3. Restart Shinobi to apply the Plugin Key. Shinobi does not need to be restarted when a plugin is initiated or stopped after applying changes to the Main Configuration file.
|
||||||
|
|
||||||
```
|
> You should change `SomeOpenALPRkeySoPeopleDontMessWithYourShinobi` to something else in both the main configuration and plugin configuration. Both files changed need to be matching keys of course.
|
||||||
cp plugins/openalpr/conf.sample.json plugins/openalpr/conf.json
|
|
||||||
```
|
|
||||||
|
|
||||||
Edit it the new file. Host should be `localhost` and port should match the `listening port for camera.js`.
|
|
||||||
|
|
||||||
```
|
|
||||||
nano plugins/openalpr/conf.json
|
|
||||||
```
|
|
||||||
|
|
||||||
Start the plugin.
|
|
||||||
|
|
||||||
```
|
|
||||||
node plugins/openalpr/shinobi-openalpr.js
|
|
||||||
```
|
|
||||||
|
|
||||||
Or to daemonize with PM2.
|
|
||||||
|
|
||||||
```
|
|
||||||
pm2 start plugins/openalpr/shinobi-openalpr.js
|
|
||||||
```
|
|
||||||
|
|
||||||
Doing this will reveal options in the monitor configuration. Shinobi does not need to be restarted when a plugin is initiated or stopped.
|
|
||||||
|
|
||||||
## Run the plugin as a Host
|
## Run the plugin as a Host
|
||||||
> The main app (Shinobi) will be the client and the plugin will be the host. The purpose of allowing this method is so that you can use one plugin for multiple Shinobi instances. Allowing you to easily manage connections without starting multiple processes.
|
> The main app (Shinobi) will be the client and the plugin will be the host. The purpose of allowing this method is so that you can use one plugin for multiple Shinobi instances. Allowing you to easily manage connections without starting multiple processes.
|
||||||
|
@ -51,7 +34,7 @@ Doing this will reveal options in the monitor configuration. Shinobi does not ne
|
||||||
Edit your plugins configuration file. Set the `hostPort` **to be different** than the `listening port for camera.js`.
|
Edit your plugins configuration file. Set the `hostPort` **to be different** than the `listening port for camera.js`.
|
||||||
|
|
||||||
```
|
```
|
||||||
nano plugins/openalpr/conf.json
|
nano conf.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Here is a sample of a Host configuration for the plugin.
|
Here is a sample of a Host configuration for the plugin.
|
||||||
|
@ -70,7 +53,7 @@ Here is a sample of a Host configuration for the plugin.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Now modify the **main configuration file** located in the main directory of Shinobi. *Where you currently should be.*
|
Now modify the **Main Configuration** file located in the main directory of Shinobi. *Where you currently should be.*
|
||||||
|
|
||||||
```
|
```
|
||||||
nano conf.json
|
nano conf.json
|
||||||
|
@ -90,4 +73,4 @@ Add the `plugins` array if you don't already have it. Add the following *object
|
||||||
"type" : "detector"
|
"type" : "detector"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
```
|
```
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
"description": "OpenALPR plugin for Shinobi",
|
"description": "OpenALPR plugin for Shinobi",
|
||||||
"main": "shinobi-openalpr.js",
|
"main": "shinobi-openalpr.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"canvas": "^1.6.7",
|
|
||||||
"express": "^4.16.2",
|
"express": "^4.16.2",
|
||||||
"moment": "^2.19.2",
|
"moment": "^2.19.2",
|
||||||
"socket.io": "^2.0.4"
|
"socket.io": "^2.0.4"
|
||||||
|
|
|
@ -26,7 +26,9 @@ try{
|
||||||
}
|
}
|
||||||
// Base Init />>
|
// Base Init />>
|
||||||
// OpenALPR Init >>
|
// OpenALPR Init >>
|
||||||
if(config.alprConfig===undefined){config.alprConfig=__dirname+'/openalpr.conf'}
|
if(config.alprConfig === undefined){
|
||||||
|
config.alprConfig = __dirname + '/openalpr.conf'
|
||||||
|
}
|
||||||
// OpenALPR Init />>
|
// OpenALPR Init />>
|
||||||
s.detectObject = function(buffer,d,tx,frameLocation){
|
s.detectObject = function(buffer,d,tx,frameLocation){
|
||||||
var detectStuff = function(frame){
|
var detectStuff = function(frame){
|
||||||
|
|
|
@ -125,6 +125,18 @@ CREATE TABLE IF NOT EXISTS `Files` (
|
||||||
`status` int(1) NOT NULL DEFAULT '0'
|
`status` int(1) NOT NULL DEFAULT '0'
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
ALTER TABLE `Files` ADD COLUMN `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER `status`;
|
ALTER TABLE `Files` ADD COLUMN `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER `status`;
|
||||||
|
|
||||||
|
-- Data exporting was unselected.
|
||||||
|
-- Dumping structure for table ccio.Schedules
|
||||||
|
CREATE TABLE IF NOT EXISTS `Schedules` (
|
||||||
|
`ke` varchar(50) DEFAULT NULL,
|
||||||
|
`name` text,
|
||||||
|
`details` text,
|
||||||
|
`start` varchar(10) DEFAULT NULL,
|
||||||
|
`end` varchar(10) DEFAULT NULL,
|
||||||
|
`enabled` int(1) NOT NULL DEFAULT '1'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
-- Data exporting was unselected.
|
-- Data exporting was unselected.
|
||||||
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
/*!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) */;
|
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||||
|
|
|
@ -12,7 +12,7 @@ processArgv.forEach(function(val) {
|
||||||
var theSplit = val.split('=');
|
var theSplit = val.split('=');
|
||||||
var index = theSplit[0];
|
var index = theSplit[0];
|
||||||
var value = theSplit[1];
|
var value = theSplit[1];
|
||||||
if(index === 'addToConfig'){
|
if(index.indexOf('addToConfig') > -1){
|
||||||
try{
|
try{
|
||||||
value = JSON.parse(value)
|
value = JSON.parse(value)
|
||||||
config = Object.assign(config,value)
|
config = Object.assign(config,value)
|
||||||
|
@ -36,4 +36,4 @@ processArgv.forEach(function(val) {
|
||||||
jsonfile.writeFile(configLocation,config,{spaces: 2},function(){
|
jsonfile.writeFile(configLocation,config,{spaces: 2},function(){
|
||||||
console.log('Changes Complete. Here is what it is now.')
|
console.log('Changes Complete. Here is what it is now.')
|
||||||
console.log(JSON.stringify(config,null,2))
|
console.log(JSON.stringify(config,null,2))
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*Cusotm Bootstrap*/
|
||||||
|
.col-5ths,
|
||||||
|
.col-sm-5ths,
|
||||||
|
.col-md-5ths,
|
||||||
|
.col-lg-5ths {
|
||||||
|
position: relative;
|
||||||
|
min-height: 1px;
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-5ths {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-webkit-flex: 0 0 20%;
|
||||||
|
-ms-flex: 0 0 20%;
|
||||||
|
flex: 0 0 20%;
|
||||||
|
max-width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 576px) {
|
||||||
|
.col-sm-5ths {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-webkit-flex: 0 0 20%;
|
||||||
|
-ms-flex: 0 0 20%;
|
||||||
|
flex: 0 0 20%;
|
||||||
|
max-width: 20%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.col-md-5ths {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-webkit-flex: 0 0 20%;
|
||||||
|
-ms-flex: 0 0 20%;
|
||||||
|
flex: 0 0 20%;
|
||||||
|
max-width: 20%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background-color:#bd9565;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color:#bd9565;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
/**/
|
||||||
|
.flex{display:flex}
|
||||||
|
.flex>div{flex:1}
|
||||||
|
.flex-block{display:inline-flex;width:100%;flex-flow: row wrap;}
|
||||||
|
.flex-unit-3{flex:3}
|
||||||
|
.flex-inline{display: inline-flex;position:relative}
|
||||||
|
@import (less) "../less/pie.less";
|
||||||
|
ul{list-style:none}
|
||||||
|
*{transition:0.2s;box-sizing:border-box}
|
||||||
|
.affix-top{position:fixed}
|
||||||
|
.no-padding{padding:0!important}
|
||||||
|
.no-margin{margin:0!important}
|
||||||
|
.pre-inline{white-space: normal;word-break: normal}
|
||||||
|
.pre-inline>ul{margin:0;padding:0}
|
||||||
|
a{cursor:pointer}
|
||||||
|
nav h4{cursor:default;font-size:95%;padding:16px 40px;font-weight:100;text-transform:uppercase;letter-spacing:2px}
|
||||||
|
.m-r{margin-right:10px}
|
||||||
|
.m-b{margin-bottom:10px}
|
||||||
|
.m-t{margin-top:10px}
|
||||||
|
.m-l{margin-left:10px}
|
||||||
|
.overflow-hidden{overflow: hidden!important}
|
||||||
|
.list-inline{list-style:none}
|
||||||
|
.list-inline li{display:inline-block;vertical-align: top;margin:0;}
|
||||||
|
.truncate{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
||||||
|
img{max-width:100%}
|
||||||
|
.display-table{display:table;width:100%}
|
||||||
|
.display-inline{display:inline-block}
|
||||||
|
.display-table-cell{display:table-cell}
|
||||||
|
.small{font-size:80%}
|
||||||
|
.super-center{position:absolute;left:0;top:0;right:0;bottom:0;margin:auto;width: 4em;height: 1em;}
|
||||||
|
.permission_monitor_edit{display:none}
|
||||||
|
.permission_video_delete{display:none}
|
||||||
|
.nodata .divider{margin:5px 0}
|
||||||
|
.loading .divider{margin:5px 0}
|
||||||
|
/* Video Grid */
|
||||||
|
.video_grid{overflow: auto;height: 100%;display: block;}
|
||||||
|
.video_grid .col-md-2{padding-left:5px;padding-right:5px;padding-bottom:10px}
|
||||||
|
.video_grid .thumb{width:100%;height:150px;display:inline-block;background-size:cover;position:relative;overflow:hidden;border-radius:4px;border:1px solid #000;box-shadow:0 0 10px #151515}
|
||||||
|
.video_grid .thumb .title-strip, .video_grid .thumb .button-strip{width:100%;position:absolute;left:0;background:rgba(0,0,0,0.7);color:#fff;padding:4px}
|
||||||
|
.video_grid .thumb .title-strip{top:0;opacity:0.5}
|
||||||
|
.video_grid .thumb .button-strip{bottom:0;opacity:0}
|
||||||
|
.video_grid .thumb:hover .title-strip, .video_grid .thumb:hover .button-strip{opacity:1}
|
|
@ -0,0 +1,44 @@
|
||||||
|
form.modal-body{margin:0}
|
||||||
|
.form-group label span{padding:5px;font-weight: 400;color: #2d2d2d;display:block;border-bottom: 1px dotted #ddd;font-size: 10pt;}
|
||||||
|
.form-group label{display:table}
|
||||||
|
.form-group label>div{display:table-cell}
|
||||||
|
.form-group label>div:nth-child(2n-1){width:30%}
|
||||||
|
.form-group label>div:nth-child(2){width:70%;padding:5px;border:1px solid #dedede;border-radius:5px}
|
||||||
|
.dark .form-group label>div,.dark .form-group label>div>span{border-color:#454545;color:#fff}
|
||||||
|
.important.form-group label>div:nth-child(2),.important.form-group label>div>span{border-color:red}
|
||||||
|
.form-group label span small{margin-left: 2px;display:block;font-weight: 600;}
|
||||||
|
.form-group-group .round-left{border-radius: 50px 0 0 50px;margin-left:10px}
|
||||||
|
.form-group-group blockquote:before,.form-group-group blockquote:after{display:none!important}
|
||||||
|
.form-group-group blockquote{letter-spacing:normal;font-style:normal}
|
||||||
|
.form-group-group blockquote p:empty{display:none}
|
||||||
|
.form-group-group blockquote p{font-size:inherit}
|
||||||
|
.form-group-group blockquote p:last-child{margin-bottom:0}
|
||||||
|
.form-group-group-group>div,.form-group-group-group .h_us_advanced>div{margin-bottom:15px;}
|
||||||
|
.form-group-group{padding:0 10px 10px 10px;overflow:hidden;margin-bottom:15px;border-radius:5px;border:1px solid #ddd;background:#fff}
|
||||||
|
.form-group-group table{width:100%}
|
||||||
|
.form-group-group table tr td{padding:10px 5px}
|
||||||
|
.form-group-group table tr:not(:last-child) td{border-bottom:1px dotted #eee}
|
||||||
|
.form-group-group .mdl-list__item{border-bottom:1px solid #eee;}
|
||||||
|
.form-group-group .mdl-list__item:hover{background:#e6e6e6;border-radius:4px;}
|
||||||
|
.dark .form-group-group .mdl-list__item{color:#fff;border-bottom:1px solid #444;}
|
||||||
|
.dark .form-group-group .mdl-list__item:hover{background:#555;}
|
||||||
|
.form-group-group:last-child,.form-group-group > .form-group:last-child{margin-bottom:0}
|
||||||
|
.form-group-group h4{margin:0 -10px 15px -10px;padding:15px;background:#ddd;}
|
||||||
|
.form-group-group h4 small{color:#fff;}
|
||||||
|
.form-group-group.red{border-color:#d9534f}
|
||||||
|
.form-group-group.red h4{background:#d9534f;color:#fff}
|
||||||
|
.form-group-group.purple{border-color:#3f51b5}
|
||||||
|
.form-group-group.purple h4{background:#3f51b5;color:#fff}
|
||||||
|
.form-group-group.blue{border-color:#337ab7}
|
||||||
|
.form-group-group.blue h4{background:#337ab7;color:#fff}
|
||||||
|
.form-group-group.navy{border-color:#31708f}
|
||||||
|
.form-group-group.navy h4{background:#31708f;color:#fff}
|
||||||
|
.form-group-group.green{border-color:#449d44}
|
||||||
|
.form-group-group.green h4{background:#449d44;color:#fff}
|
||||||
|
.form-group-group.forestgreen{border-color:#1e4046}
|
||||||
|
.form-group-group.forestgreen h4{background:#1e4046;color:#fff}
|
||||||
|
.form-group-group.orange{border-color:#c49a68}
|
||||||
|
.form-group-group.orange h4{background:#c49a68;color:#fff}
|
||||||
|
.form-group-group.grey{border-color:#777}
|
||||||
|
.form-group-group.grey h4{background:#777;color:#fff}
|
||||||
|
.dark .form-group-group{background:#222}
|
|
@ -0,0 +1,86 @@
|
||||||
|
|
||||||
|
.jpegMode .cpu_load .progress-bar,.jpegMode .ram_load .progress-bar{background-color:#5cb85c}
|
||||||
|
.jpegMode [system="jpegToggle"],[system].text-success{color:#5cb85c!important}
|
||||||
|
|
||||||
|
.monitor_item .stream-hud{opacity:0;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2}
|
||||||
|
.monitor_item .stream-hud .camera_cpu_usage{position:absolute;top:0;left:0;width: 100%;}
|
||||||
|
.monitor_item .stream-hud .camera_cpu_usage .progress{width: 100%;}
|
||||||
|
.monitor_item .stream-hud .camera_cpu_usage:hover .progress{height:20px;transition:0.2s}
|
||||||
|
.monitor_item .stream-hud .controls{position:absolute;top:10px;left:10px;}
|
||||||
|
.monitor_item .stream-hud:hover{opacity:1}
|
||||||
|
.monitor_item .stream-hud .bottom-text{position:absolute;bottom:0;left:0;width:70%;padding:5px;text-shadow: 0 0 10px #333;}
|
||||||
|
.monitor_item .stream-hud:hover .bottom-text{top:0;}
|
||||||
|
.monitor_item .stream-hud .bottom-text .detector-fade{background: rgba(0,0,0,0.4);padding:10px 20px;border-radius:10px}
|
||||||
|
.monitor_item .stream-hud .lamp{position:absolute;top:5px;right:5px;z-index:1;text-shadow: 0 0 15px #333;}
|
||||||
|
.monitor_item[mode="Disabled"] .stream-hud .lamp{color:#5d5d5d}
|
||||||
|
.monitor_item[mode="Watch Only"] .stream-hud .lamp{color:#5da8e8}
|
||||||
|
.monitor_item[mode="Idle"] .stream-hud .lamp{color:#fff}
|
||||||
|
.monitor_item[mode="Record"] .stream-hud .lamp{color:#d9534f}
|
||||||
|
/*.data-menu{max-height:700px}*/
|
||||||
|
.data-menu:not(:last-child){border-right:1px solid #fff;}
|
||||||
|
.data-menu.logs{list-style:none;}
|
||||||
|
.monitor_item .motionVision{display:none}
|
||||||
|
|
||||||
|
.monitor_item .grid-stack-item-content{width:100%!important;left:0!important;right:0!important}
|
||||||
|
.monitor_item .ui-resizable-se {bottom: 10px!important;}
|
||||||
|
.monitor_item .stream-block{position: relative;text-align: center}
|
||||||
|
.monitor_item .mdl-data_window{overflow-x: auto;background:rgba(0,0,0,0.7);color:#fff;height:100%}
|
||||||
|
.monitor_item .mdl-data_window:not(.col-md-6){width:0;min-width:0;height:0px;min-height:0}
|
||||||
|
|
||||||
|
|
||||||
|
.monitor_item.fullscreen img.stream-element{height:100%;width:auto}
|
||||||
|
.monitor_item.fullscreen canvas.stream-element{height:auto;width:auto;background-color:black;}
|
||||||
|
.monitor_item .stream-element{border: 0;object-fit: fill;height: 100%;width:100%}
|
||||||
|
.monitor_item{position:relative;padding:0;transition:none;background:#000}
|
||||||
|
.monitor_item .mdl-card{min-height:auto;border:1px solid #272727;border-radius:0px;overflow:hidden}
|
||||||
|
.monitor_item .mdl-card__media{position:relative;padding:0!important;display:block!important;background:#000;}
|
||||||
|
.monitor_item.selected .stream-element{height:600px}
|
||||||
|
.monitor_item.selected .fa-expand:before{content:"\f066"}
|
||||||
|
.monitor_item .mdl-card__supporting-text{background:#222;color:#fff!important;display:block;min-height:auto!important}
|
||||||
|
.monitor_item.detector_triggered .detector-fade{opacity:1}
|
||||||
|
.monitor_item .detector-fade{opacity:0}
|
||||||
|
.monitor_item .indifference{position:absolute;width:100%;left:0;top:0;transition:0.2s;}
|
||||||
|
.monitor_item .progress{width:100%;background:#333;box-shadow:0;}
|
||||||
|
.monitor_item .indifference:hover .progress{height:20px;transition:0.2s}
|
||||||
|
.hide_indifference .indifference{display:none!important}
|
||||||
|
.hide_indifference [class_toggle="hide_indifference"]{color:#d9534f!important}
|
||||||
|
.monitor_item .mdl-card:not(.mdl-cell--4-col-desktop) .mdl-card__supporting-text .monitor_details{display:none;font-size:90%;margin-bottom:10px}
|
||||||
|
.monitor_item[mode="Record"] [mode="record"]{display:none}
|
||||||
|
.monitor_item[mode="Watch Only"] [mode="start"]{display:none}
|
||||||
|
.monitor_item .stream-hud .controls .btn{opacity:0.7}
|
||||||
|
.monitor_item.doObjectDetection .progress-bar{background-color: #57d94f}
|
||||||
|
|
||||||
|
.data-menu{text-align:left}
|
||||||
|
.data-menu ul,.side-menu ul{list-style:none;margin:0;padding:0;}
|
||||||
|
.data-menu li,.side-menu li:not(.mdl-menu__item){
|
||||||
|
border-bottom:1px solid #54502d;padding:10px;
|
||||||
|
}
|
||||||
|
.data-menu .progress-circle{margin:0 10px 0 0;position:relative;height:40px;width:40px;float:left}
|
||||||
|
.data-menu .progress-circle span:after{content:''}
|
||||||
|
img.circle-img,div.circle-img{border-radius:50%;height:50px;width:50px}
|
||||||
|
.circle-img.sm{height:25px;width:25px}
|
||||||
|
|
||||||
|
@media screen and (max-width:1500px){
|
||||||
|
.monitor_item .mdl-card__supporting-text .btn{
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#monitors_live .monitor_item [class_toggle="show_logs"]{display:none}
|
||||||
|
#monitors_live .monitor_item .indifference{top:-5px}
|
||||||
|
#monitors_live .monitor_item .mdl-cell--8-col{width:100%;border:0;border-radius:0;margin:0;position:relative}
|
||||||
|
#monitors_live .monitor_item .mdl-cell--4-col-desktop,.monitor_item .mdl-card__supporting-text{display:none}
|
||||||
|
#monitors_live .monitor_item .mdl-card__supporting-text .monitor_details,#monitors_live .monitor_item .mdl-card__supporting-text .btn-group{display:none;text-align:center}
|
||||||
|
#monitors_live .monitor_item .mdl-card__supporting-text:not(.meta){display:block;position:absolute;bottom:0;left:0;height:0;padding:0;overflow:visible}
|
||||||
|
#monitors_live .monitor_item.show_data .mdl-card__supporting-text:not(.meta){width:50%}
|
||||||
|
#monitors_live .monitor_item.detector_triggered .mdl-card__supporting-text:not(.meta) .indifference{opacity:0.5;}
|
||||||
|
#monitors_live .monitor_item:hover .mdl-card__supporting-text:not(.meta){padding:15px;z-index:15;height:auto;}
|
||||||
|
#monitors_live .monitor_item:hover .mdl-card__supporting-text .monitor_details{display:block}
|
||||||
|
#monitors_live .monitor_item:hover .mdl-card__supporting-text .btn-group{display:inline-block}
|
||||||
|
|
||||||
|
.signal.green{background:#5cb85c}
|
||||||
|
[status="1"] .btn[video="launch"],[data-status="1"] .btn[video="launch"]{background:#337ab7;border-color:#337ab7}
|
||||||
|
[status="2"] .btn[launch="video"],[status="2"] .btn[video="launch"],[data-status="2"] .btn[video="launch"]{background:#a59100;border-color:#a59100}
|
||||||
|
.signal.red{background:#c9302c}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#pvideo_viewer iframe{border:0;width:100%;height:350px;margin-bottom:10px;overflow:hidden}
|
||||||
|
#pvideo_viewer video{max-height:300px;max-width:100%;}
|
||||||
|
#pvideo_viewer .holder{height:300px;}
|
||||||
|
#pvideo_viewer h3{margin-top:0}
|
||||||
|
#pvideo_viewer .progressBar{position:relative;}
|
||||||
|
#pvideo_viewer .bufferBar{position:absolute;left:0;top:0;opacity:0.4}
|
||||||
|
#pvideo_viewer .timeBar{position:relative;z-index: 222;background:transparent}
|
||||||
|
#pvideo_viewer h3{font-family:monospace}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*Control Pad*/
|
||||||
|
.PTZ_controls {
|
||||||
|
z-index: 111;
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
top: 20px;
|
||||||
|
margin:0;
|
||||||
|
display: inline-block;
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .btn-group{margin-top:10px}
|
||||||
|
.PTZ_controls .pad {
|
||||||
|
position: relative;
|
||||||
|
height: 120px;
|
||||||
|
width: 120px;
|
||||||
|
background: #b7b7b7;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: inset 0 0 1px rgba(120, 120, 120, 0.6), inset 0 2px 2px rgba(0, 0, 0, 0.1), 0 2px 2px rgba(240, 240, 240, 0.4);
|
||||||
|
}
|
||||||
|
.PTZ_controls .control {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .control {
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
background: #636363;
|
||||||
|
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(60, 60, 60, 0.2), 0 0 0 4px rgba(60, 60, 60, 0.2);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .zoom_in{
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.PTZ_controls .zoom_out{
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.PTZ_controls .nv_enabled{
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.PTZ_controls .nv_disable{
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .top {
|
||||||
|
top: 15px;
|
||||||
|
left: 50%;
|
||||||
|
margin: 0 0 0 -15px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .left {
|
||||||
|
top: 45px;
|
||||||
|
left: 15px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .right {
|
||||||
|
top: 45px;
|
||||||
|
right: 15px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .control.right:before {
|
||||||
|
transform: rotate(90deg) translate(-3px, -5px);
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .bottom {
|
||||||
|
bottom: 15px;
|
||||||
|
left: 50%;
|
||||||
|
margin: 0 0 0 -15px;
|
||||||
|
}
|
||||||
|
/* Overlap the other controls to hide box-shadow */
|
||||||
|
.PTZ_controls .pad .middle {
|
||||||
|
height: 34px;
|
||||||
|
width: 34px;
|
||||||
|
z-index: 5;
|
||||||
|
top: 43px;
|
||||||
|
left: 50%;
|
||||||
|
margin: 0 0 0 -17px;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .middle:after {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
margin: -35% 0 0 -35%;
|
||||||
|
content: '';
|
||||||
|
background: #636363;
|
||||||
|
height: 70%;
|
||||||
|
width: 70%;
|
||||||
|
border-radius: 100%;
|
||||||
|
box-shadow: inset 0 0 2px rgba(120, 120, 120, 0.6), inset 0 2px 8px rgba(0, 0, 0, 0.1), 0 2px 2px rgba(240, 240, 240, 0.2);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#region_editor .modal-body{text-align:center;overflow:auto;max-height:800px}
|
||||||
|
#region_editor .canvas_holder{position:relative;display:inline-block;overflow:auto;min-height:450px}
|
||||||
|
#region_editor .cord_element{position:absolute;background:rgba(221, 221, 221, 0.8);z-index:11;padding:5px;}
|
||||||
|
#region_editor .cord_element.selected{z-index:12;}
|
||||||
|
#region_editor .cord_element .controls{margin-bottom:5px;}
|
|
@ -0,0 +1,11 @@
|
||||||
|
.right-to-left {text-align:right}
|
||||||
|
.right-to-left select{direction: rtl;}
|
||||||
|
.right-to-left input,.right-to-left textarea{direction: rtl;text-align:right}
|
||||||
|
.right-to-left .form-group label span{padding-right:10px}
|
||||||
|
.right-to-left .modal-footer{text-align:left}
|
||||||
|
.right-to-left .mdl-menu__item>div>*{flex:1}
|
||||||
|
.right-to-left .mdl-menu__item>div>i{margin-right:0;margin-left:5px}
|
||||||
|
.right-to-left .mdl-menu__item{text-align:right}
|
||||||
|
.right-to-left .mdl-menu__item i{float:right}
|
||||||
|
.right-to-left .pull-right,.right-to-left .close{float:left!important}
|
||||||
|
.right-to-left .pull-left,.right-to-left .mdl-menu__item span{float:right!important}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#timelapse_video_line{overflow-y:scroll;overflow-x:hidden;max-height:400px;margin:0;text-align:left}
|
||||||
|
#timelapse_video_display .videoBefore,#timelapse_video_display .videoAfter{display:none}
|
||||||
|
.timelapse_video:not(:last-child){border-bottom:1px solid #444;}
|
||||||
|
.timelapse_video .frame{width:50px;height:50px;background-size:cover;background-position:center;border-radius:5px}
|
||||||
|
.timelapse_video>div>div:not(:last-child){padding-right:10px}
|
||||||
|
.timelapse_video .flex-block:not(:last-child){padding-bottom:10px}
|
||||||
|
.timelapse_video.list-group-item{padding:10px}
|
||||||
|
.timelapse_hud{position: relative;background:#000}
|
||||||
|
.timelapse_hud .timelapse_playRate{position: absolute;font-family: monospace;top:10px;right:0;left:0;margin:auto;font-size:23px}
|
||||||
|
#timelapse .progress-bar{transition:0.5s!important}
|
||||||
|
.timelapse_hud .controlBar{position: absolute;background:rgba(22,22,22,0.8);width:100%;left:0;bottom:0;}
|
||||||
|
.timelapse_hud .hover-hide{opacity:0}
|
||||||
|
.timelapse_hud:hover .hover-hide{opacity:1;z-index:5}
|
|
@ -1,87 +1,3 @@
|
||||||
/*Cusotm Bootstrap*/
|
|
||||||
.col-5ths,
|
|
||||||
.col-sm-5ths,
|
|
||||||
.col-md-5ths,
|
|
||||||
.col-lg-5ths {
|
|
||||||
position: relative;
|
|
||||||
min-height: 1px;
|
|
||||||
padding-right: 15px;
|
|
||||||
padding-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-5ths {
|
|
||||||
-webkit-box-flex: 0;
|
|
||||||
-webkit-flex: 0 0 20%;
|
|
||||||
-ms-flex: 0 0 20%;
|
|
||||||
flex: 0 0 20%;
|
|
||||||
max-width: 20%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 576px) {
|
|
||||||
.col-sm-5ths {
|
|
||||||
-webkit-box-flex: 0;
|
|
||||||
-webkit-flex: 0 0 20%;
|
|
||||||
-ms-flex: 0 0 20%;
|
|
||||||
flex: 0 0 20%;
|
|
||||||
max-width: 20%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.col-md-5ths {
|
|
||||||
-webkit-box-flex: 0;
|
|
||||||
-webkit-flex: 0 0 20%;
|
|
||||||
-ms-flex: 0 0 20%;
|
|
||||||
flex: 0 0 20%;
|
|
||||||
max-width: 20%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
|
||||||
background-color:#bd9565;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background-color:#bd9565;
|
|
||||||
border: 2px solid transparent;
|
|
||||||
border-radius: 10px;
|
|
||||||
background-clip: padding-box;
|
|
||||||
}
|
|
||||||
/**/
|
|
||||||
.flex{display:flex}
|
|
||||||
.flex>div{flex:1}
|
|
||||||
.flex-block{display:inline-flex;width:100%;flex-flow: row wrap;}
|
|
||||||
.flex-unit-3{flex:3}
|
|
||||||
.flex-inline{display: inline-flex;position:relative}
|
|
||||||
@import (less) "../less/pie.less";
|
|
||||||
ul{list-style:none}
|
|
||||||
*{transition:0.2s;box-sizing:border-box}
|
|
||||||
.affix-top{position:fixed}
|
|
||||||
.no-padding{padding:0!important}
|
|
||||||
.no-margin{margin:0!important}
|
|
||||||
.pre-inline{white-space: normal;word-break: normal}
|
|
||||||
.pre-inline>ul{margin:0;padding:0}
|
|
||||||
a{cursor:pointer}
|
|
||||||
nav h4{cursor:default;font-size:95%;padding:16px 40px;font-weight:100;text-transform:uppercase;letter-spacing:2px}
|
|
||||||
.m-r{margin-right:10px}
|
|
||||||
.m-b{margin-bottom:10px}
|
|
||||||
.m-t{margin-top:10px}
|
|
||||||
.m-l{margin-left:10px}
|
|
||||||
.overflow-hidden{overflow: hidden!important}
|
|
||||||
.list-inline{list-style:none}
|
|
||||||
.list-inline li{display:inline-block;vertical-align: top;margin:0;}
|
|
||||||
.truncate{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
|
||||||
img{max-width:100%}
|
|
||||||
.display-table{display:table;width:100%}
|
|
||||||
.display-inline{display:inline-block}
|
|
||||||
.display-table-cell{display:table-cell}
|
|
||||||
.small{font-size:80%}
|
|
||||||
.super-center{position:absolute;left:0;top:0;right:0;bottom:0;margin:auto;width: 4em;height: 1em;}
|
|
||||||
.jpegMode .cpu_load .progress-bar,.jpegMode .ram_load .progress-bar{background-color:#5cb85c}
|
|
||||||
.jpegMode [system="jpegToggle"],[system].text-success{color:#5cb85c!important}
|
|
||||||
.permission_monitor_edit{display:none}
|
|
||||||
.permission_video_delete{display:none}
|
|
||||||
.nodata .divider{margin:5px 0}
|
|
||||||
.loading .divider{margin:5px 0}
|
|
||||||
|
|
||||||
#accbtn{
|
#accbtn{
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -89,75 +5,6 @@ img{max-width:100%}
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.monitor_item .stream-hud{opacity:0;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2}
|
|
||||||
.monitor_item .stream-hud .camera_cpu_usage{position:absolute;top:0;left:0;width: 100%;}
|
|
||||||
.monitor_item .stream-hud .camera_cpu_usage .progress{width: 100%;}
|
|
||||||
.monitor_item .stream-hud .camera_cpu_usage:hover .progress{height:20px;transition:0.2s}
|
|
||||||
.monitor_item .stream-hud .controls{position:absolute;top:10px;left:10px;}
|
|
||||||
.monitor_item .stream-hud:hover{opacity:1}
|
|
||||||
.monitor_item .stream-hud .bottom-text{position:absolute;bottom:0;left:0;width:100%;padding:5px;text-shadow: 0 0 10px #333;}
|
|
||||||
.monitor_item .stream-hud .bottom-text .detector-fade{background: rgba(0,0,0,0.4);padding:10px 20px;border-radius:10px}
|
|
||||||
.monitor_item .stream-hud .lamp{position:absolute;top:5px;right:5px;z-index:1;text-shadow: 0 0 15px #333;}
|
|
||||||
.monitor_item[mode="Disabled"] .stream-hud .lamp{color:#5d5d5d}
|
|
||||||
.monitor_item[mode="Watch Only"] .stream-hud .lamp{color:#5da8e8}
|
|
||||||
.monitor_item[mode="Idle"] .stream-hud .lamp{color:#fff}
|
|
||||||
.monitor_item[mode="Record"] .stream-hud .lamp{color:#d9534f}
|
|
||||||
/*.data-menu{max-height:700px}*/
|
|
||||||
.data-menu:not(:last-child){border-right:1px solid #fff;}
|
|
||||||
.data-menu.logs{list-style:none;}
|
|
||||||
.monitor_item .motionVision{display:none}
|
|
||||||
|
|
||||||
.monitor_item .grid-stack-item-content{width:100%!important;left:0!important;right:0!important}
|
|
||||||
.monitor_item .ui-resizable-se {bottom: 10px!important;}
|
|
||||||
.monitor_item .stream-block{position: relative;text-align: center}
|
|
||||||
.monitor_item .mdl-data_window{overflow-x: auto;background:rgba(0,0,0,0.7);color:#fff;height:100%}
|
|
||||||
.monitor_item .mdl-data_window:not(.col-md-6){width:0;min-width:0;height:0px;min-height:0}
|
|
||||||
|
|
||||||
|
|
||||||
.monitor_item.fullscreen img.stream-element{height:100%;width:auto}
|
|
||||||
.monitor_item.fullscreen canvas.stream-element{height:auto;width:auto;background-color:black;}
|
|
||||||
.monitor_item .stream-element{border: 0;object-fit: fill;height: 100%;width:100%}
|
|
||||||
.monitor_item{position:relative;padding:0;transition:none;background:#000}
|
|
||||||
.monitor_item .mdl-card{min-height:auto;border:1px solid #272727;border-radius:0px;overflow:hidden}
|
|
||||||
.monitor_item .mdl-card__media{position:relative;padding:0!important;display:block!important;background:#000;}
|
|
||||||
.monitor_item.selected .stream-element{height:600px}
|
|
||||||
.monitor_item.selected .fa-expand:before{content:"\f066"}
|
|
||||||
.monitor_item .mdl-card__supporting-text{background:#222;color:#fff!important;display:block;min-height:auto!important}
|
|
||||||
.monitor_item.detector_triggered .detector-fade{opacity:1}
|
|
||||||
.monitor_item .detector-fade{opacity:0}
|
|
||||||
.monitor_item .indifference{position:absolute;width:100%;left:0;top:0;transition:0.2s;}
|
|
||||||
.monitor_item .progress{width:100%;background:#333;box-shadow:0;}
|
|
||||||
.monitor_item .indifference:hover .progress{height:20px;transition:0.2s}
|
|
||||||
.hide_indifference .indifference{display:none!important}
|
|
||||||
.hide_indifference [class_toggle="hide_indifference"]{color:#d9534f!important}
|
|
||||||
.monitor_item .mdl-card:not(.mdl-cell--4-col-desktop) .mdl-card__supporting-text .monitor_details{display:none;font-size:90%;margin-bottom:10px}
|
|
||||||
.monitor_item[mode="Record"] [mode="record"]{display:none}
|
|
||||||
.monitor_item[mode="Watch Only"] [mode="start"]{display:none}
|
|
||||||
.monitor_item .stream-hud .controls .btn{opacity:0.7}
|
|
||||||
.monitor_item.doObjectDetection .progress-bar{background-color: #57d94f}
|
|
||||||
|
|
||||||
@media screen and (max-width:1500px){
|
|
||||||
.monitor_item .mdl-card__supporting-text .btn{
|
|
||||||
padding: 5px 10px;
|
|
||||||
font-size: 11px;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#monitors_live .monitor_item [class_toggle="show_logs"]{display:none}
|
|
||||||
#monitors_live .monitor_item .indifference{top:-5px}
|
|
||||||
#monitors_live .monitor_item .mdl-cell--8-col{width:100%;border:0;border-radius:0;margin:0;position:relative}
|
|
||||||
#monitors_live .monitor_item .mdl-cell--4-col-desktop,.monitor_item .mdl-card__supporting-text{display:none}
|
|
||||||
#monitors_live .monitor_item .mdl-card__supporting-text .monitor_details,#monitors_live .monitor_item .mdl-card__supporting-text .btn-group{display:none;text-align:center}
|
|
||||||
#monitors_live .monitor_item .mdl-card__supporting-text:not(.meta){display:block;position:absolute;bottom:0;left:0;height:0;padding:0;}
|
|
||||||
#monitors_live .monitor_item.show_data .mdl-card__supporting-text:not(.meta){width:50%}
|
|
||||||
#monitors_live .monitor_item.detector_triggered .mdl-card__supporting-text:not(.meta) .indifference{opacity:0.5;}
|
|
||||||
#monitors_live .monitor_item:hover .mdl-card__supporting-text:not(.meta){padding:15px;z-index:15;height:auto;}
|
|
||||||
#monitors_live .monitor_item:hover .mdl-card__supporting-text .monitor_details{display:block}
|
|
||||||
#monitors_live .monitor_item:hover .mdl-card__supporting-text .btn-group{display:inline-block}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#vis_pwrvideo{height:250px}
|
#vis_pwrvideo{height:250px}
|
||||||
#monSectionStreamChannels,#monSectionInputMaps{margin-bottom: 15px;}
|
#monSectionStreamChannels,#monSectionInputMaps{margin-bottom: 15px;}
|
||||||
#monSectionStreamChannels:empty,#monSectionInputMaps:empty{display:none}
|
#monSectionStreamChannels:empty,#monSectionInputMaps:empty{display:none}
|
||||||
|
@ -169,19 +16,12 @@ img{max-width:100%}
|
||||||
|
|
||||||
.demo-blog .demo-blog__posts.montage{max-width:100%}
|
.demo-blog .demo-blog__posts.montage{max-width:100%}
|
||||||
|
|
||||||
|
.mdl-layout__drawer{overflow-y: visible!important}
|
||||||
|
.hide-side .mdl-layout__drawer{overflow-y: hidden}
|
||||||
.mdl-layout__header-row{padding-left:10!important}
|
.mdl-layout__header-row{padding-left:10!important}
|
||||||
.mdl-layout__header-row .nav>li>a{border-radius:50%;}
|
.mdl-layout__header-row .nav>li>a{border-radius:50%;}
|
||||||
.mdl-layout__drawer-button i{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;height:1em;color:#fff}
|
.mdl-layout__drawer-button i{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;height:1em;color:#fff}
|
||||||
.data-menu{text-align:left}
|
|
||||||
.data-menu ul,.side-menu ul{list-style:none;margin:0;padding:0;}
|
|
||||||
.data-menu li,.side-menu li{
|
|
||||||
border-bottom:1px solid #54502d;padding:10px;
|
|
||||||
}
|
|
||||||
.data-menu .progress-circle{margin:0 10px 0 0;position:relative;height:40px;width:40px;float:left}
|
|
||||||
.data-menu .progress-circle span:after{content:''}
|
|
||||||
img.circle-img,div.circle-img{border-radius:50%;height:50px;width:50px}
|
|
||||||
.circle-img.sm{height:25px;width:25px}
|
|
||||||
|
|
||||||
.video_video{margin:auto;max-width:100%;max-height:600px;}
|
.video_video{margin:auto;max-width:100%;max-height:600px;}
|
||||||
#confirm_window .video_video{margin-top:15px}
|
#confirm_window .video_video{margin-top:15px}
|
||||||
|
@ -200,60 +40,9 @@ img.circle-img,div.circle-img{border-radius:50%;height:50px;width:50px}
|
||||||
.flex-container-modal-body .flex-block>div{flex:1;float:none}
|
.flex-container-modal-body .flex-block>div{flex:1;float:none}
|
||||||
|
|
||||||
.modal{overflow:auto!important}
|
.modal{overflow:auto!important}
|
||||||
form.modal-body{margin:0}
|
|
||||||
#region_editor .modal-body{text-align:center;overflow:auto;max-height:800px}
|
|
||||||
#region_editor .canvas_holder{position:relative;display:inline-block;overflow:auto;min-height:450px}
|
|
||||||
#region_editor .cord_element{position:absolute;background:rgba(221, 221, 221, 0.8);z-index:11;padding:5px;}
|
|
||||||
#region_editor .cord_element.selected{z-index:12;}
|
|
||||||
#region_editor .cord_element .controls{margin-bottom:5px;}
|
|
||||||
.form-group label span{padding:5px;font-weight: 400;color: #2d2d2d;display:block;border-bottom: 1px dotted #ddd;font-size: 10pt;}
|
|
||||||
.form-group label{display:table}
|
|
||||||
.form-group label>div{display:table-cell}
|
|
||||||
.form-group label>div:nth-child(2n-1){width:30%}
|
|
||||||
.form-group label>div:nth-child(2){width:70%;padding:5px;border:1px solid #dedede;border-radius:5px}
|
|
||||||
.dark .form-group label>div,.dark .form-group label>div>span{border-color:#454545;color:#fff}
|
|
||||||
.important.form-group label>div:nth-child(2),.important.form-group label>div>span{border-color:red}
|
|
||||||
.form-group label span small{margin-left: 2px;display:block;font-weight: 600;}
|
|
||||||
.form-group-group .round-left{border-radius: 50px 0 0 50px;margin-left:10px}
|
|
||||||
.form-group-group blockquote:before,.form-group-group blockquote:after{display:none!important}
|
|
||||||
.form-group-group blockquote{letter-spacing:normal;font-style:normal}
|
|
||||||
.form-group-group blockquote p:empty{display:none}
|
|
||||||
.form-group-group blockquote p{font-size:inherit}
|
|
||||||
.form-group-group blockquote p:last-child{margin-bottom:0}
|
|
||||||
.form-group-group-group>div,.form-group-group-group .h_us_advanced>div{margin-bottom:15px;}
|
|
||||||
.form-group-group{padding:0 10px 10px 10px;overflow:hidden;margin-bottom:15px;border-radius:5px;border:1px solid #ddd;background:#fff}
|
|
||||||
.form-group-group table{width:100%}
|
|
||||||
.form-group-group table tr td{padding:10px 5px}
|
|
||||||
.form-group-group table tr:not(:last-child) td{border-bottom:1px dotted #eee}
|
|
||||||
.form-group-group .mdl-list__item{border-bottom:1px solid #eee;}
|
|
||||||
.form-group-group .mdl-list__item:hover{background:#e6e6e6;border-radius:4px;}
|
|
||||||
.dark .form-group-group .mdl-list__item{color:#fff;border-bottom:1px solid #444;}
|
|
||||||
.dark .form-group-group .mdl-list__item:hover{background:#555;}
|
|
||||||
.form-group-group:last-child,.form-group-group > .form-group:last-child{margin-bottom:0}
|
|
||||||
.form-group-group h4{margin:0 -10px 15px -10px;padding:15px;background:#ddd;}
|
|
||||||
.form-group-group h4 small{color:#fff;}
|
|
||||||
.form-group-group.red{border-color:#d9534f}
|
|
||||||
.form-group-group.red h4{background:#d9534f;color:#fff}
|
|
||||||
.form-group-group.purple{border-color:#3f51b5}
|
|
||||||
.form-group-group.purple h4{background:#3f51b5;color:#fff}
|
|
||||||
.form-group-group.blue{border-color:#337ab7}
|
|
||||||
.form-group-group.blue h4{background:#337ab7;color:#fff}
|
|
||||||
.form-group-group.navy{border-color:#31708f}
|
|
||||||
.form-group-group.navy h4{background:#31708f;color:#fff}
|
|
||||||
.form-group-group.green{border-color:#449d44}
|
|
||||||
.form-group-group.green h4{background:#449d44;color:#fff}
|
|
||||||
.form-group-group.forestgreen{border-color:#1e4046}
|
|
||||||
.form-group-group.forestgreen h4{background:#1e4046;color:#fff}
|
|
||||||
.form-group-group.orange{border-color:#c49a68}
|
|
||||||
.form-group-group.orange h4{background:#c49a68;color:#fff}
|
|
||||||
.form-group-group.grey{border-color:#777}
|
|
||||||
.form-group-group.grey h4{background:#777;color:#fff}
|
|
||||||
.dark .form-group-group{background:#222}
|
|
||||||
.videos_list .title{font-size:12pt;padding:0 10px}
|
.videos_list .title{font-size:12pt;padding:0 10px}
|
||||||
[status="1"] .btn[video="launch"],[data-status="1"] .btn[video="launch"]{background:#337ab7;border-color:#337ab7}
|
|
||||||
[status="2"] .btn[launch="video"],[status="2"] .btn[video="launch"],[data-status="2"] .btn[video="launch"]{background:#a59100;border-color:#a59100}
|
|
||||||
.signal.red{background:#c9302c}
|
|
||||||
.signal.green{background:#5cb85c}
|
|
||||||
.demo-drawer{background:#2b2a2a;color:#fff;}
|
.demo-drawer{background:#2b2a2a;color:#fff;}
|
||||||
.demo-drawer.mdl-layout__drawer .mdl-navigation{padding-top:0;}
|
.demo-drawer.mdl-layout__drawer .mdl-navigation{padding-top:0;}
|
||||||
.demo-drawer::-webkit-scrollbar{display:none;}
|
.demo-drawer::-webkit-scrollbar{display:none;}
|
||||||
|
@ -285,6 +74,8 @@ form.modal-body{margin:0}
|
||||||
.nav-xs.side-menu.list-blocks .monitor_block img{width:40px;height:40px;}
|
.nav-xs.side-menu.list-blocks .monitor_block img{width:40px;height:40px;}
|
||||||
.side-menu.list-blocks .monitor_block .box{width:calc(100% - 70px);display:inline-block}
|
.side-menu.list-blocks .monitor_block .box{width:calc(100% - 70px);display:inline-block}
|
||||||
.nav-xs.side-menu.list-blocks .monitor_block .list-data{display:none}
|
.nav-xs.side-menu.list-blocks .monitor_block .list-data{display:none}
|
||||||
|
.side-menu .mdl-menu{z-index: 12}
|
||||||
|
|
||||||
#monitors_list .monitor_block{transition:none}
|
#monitors_list .monitor_block{transition:none}
|
||||||
.dropdown-menu.scrollable{max-height:300px}
|
.dropdown-menu.scrollable{max-height:300px}
|
||||||
.upload_file input{display:none}
|
.upload_file input{display:none}
|
||||||
|
@ -306,39 +97,11 @@ form.modal-body{margin:0}
|
||||||
|
|
||||||
.form-group label{width:100%}
|
.form-group label{width:100%}
|
||||||
|
|
||||||
#pvideo_viewer iframe{border:0;width:100%;height:350px;margin-bottom:10px;overflow:hidden}
|
|
||||||
#pvideo_viewer video{max-height:300px;max-width:100%;}
|
|
||||||
#pvideo_viewer .holder{height:300px;}
|
|
||||||
#pvideo_viewer h3{margin-top:0}
|
|
||||||
#pvideo_viewer .progressBar{position:relative;}
|
|
||||||
#pvideo_viewer .bufferBar{position:absolute;left:0;top:0;opacity:0.4}
|
|
||||||
#pvideo_viewer .timeBar{position:relative;z-index: 222;background:transparent}
|
|
||||||
#pvideo_viewer h3{font-family:monospace}
|
|
||||||
|
|
||||||
#vis_monitors{overflow:auto;max-height:400px}
|
#vis_monitors{overflow:auto;max-height:400px}
|
||||||
#vis_monitors .btn-group-vertical{width:100%}
|
#vis_monitors .btn-group-vertical{width:100%}
|
||||||
|
|
||||||
/*timeline*/
|
|
||||||
#timelapse_video_line{overflow-y:scroll;overflow-x:hidden;max-height:400px;margin:0;text-align:left}
|
|
||||||
#timelapse_video_display .videoBefore,#timelapse_video_display .videoAfter{display:none}
|
|
||||||
.timelapse_video:not(:last-child){border-bottom:1px solid #444;}
|
|
||||||
.timelapse_video .frame{width:50px;height:50px;background-size:cover;background-position:center;border-radius:5px}
|
|
||||||
.timelapse_video>div>div:not(:last-child){padding-right:10px}
|
|
||||||
.timelapse_video .flex-block:not(:last-child){padding-bottom:10px}
|
|
||||||
.timelapse_video.list-group-item{padding:10px}
|
|
||||||
.timelapse_hud{position: relative;background:#000}
|
|
||||||
.timelapse_hud .timelapse_playRate{position: absolute;font-family: monospace;top:10px;right:0;left:0;margin:auto;font-size:23px}
|
|
||||||
#timelapse .progress-bar{transition:0.5s!important}
|
|
||||||
.timelapse_hud .controlBar{position: absolute;background:rgba(22,22,22,0.8);width:100%;left:0;bottom:0;}
|
|
||||||
.timelapse_hud .hover-hide{opacity:0}
|
|
||||||
.timelapse_hud:hover .hover-hide{opacity:1;z-index:5}
|
|
||||||
.video_grid{overflow: auto;height: 100%;display: block;}
|
|
||||||
.video_grid .col-md-2{padding-left:5px;padding-right:5px;padding-bottom:10px}
|
|
||||||
.video_grid .thumb{width:100%;height:150px;display:inline-block;background-size:cover;position:relative;overflow:hidden;border-radius:4px;border:1px solid #000;box-shadow:0 0 10px #151515}
|
|
||||||
.video_grid .thumb .title-strip, .video_grid .thumb .button-strip{width:100%;position:absolute;left:0;background:rgba(0,0,0,0.7);color:#fff;padding:4px}
|
|
||||||
.video_grid .thumb .title-strip{top:0;opacity:0.5}
|
|
||||||
.video_grid .thumb .button-strip{bottom:0;opacity:0}
|
|
||||||
.video_grid .thumb:hover .title-strip, .video_grid .thumb:hover .button-strip{opacity:1}
|
|
||||||
|
|
||||||
.table-striped>tbody>tr>td{vertical-align:middle}
|
.table-striped>tbody>tr>td{vertical-align:middle}
|
||||||
.table-striped .thumbnail{width:100px;height:80px;border-radius:5px;margin:0;display:inline-block;}
|
.table-striped .thumbnail{width:100px;height:80px;border-radius:5px;margin:0;display:inline-block;}
|
||||||
|
@ -352,13 +115,6 @@ form.modal-body{margin:0}
|
||||||
background-color: #c49a68;
|
background-color: #c49a68;
|
||||||
border-color: #c49a68;
|
border-color: #c49a68;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark.modal .modal-header,.dark.modal .modal-footer{background:#333;border-color:#444;}
|
|
||||||
.dark.modal .modal-header{color:#fff;}
|
|
||||||
.dark.modal .modal-footer>*:not(.btn){color:#fff;}
|
|
||||||
.dark.modal .modal-body{background:#333;}
|
|
||||||
.dark.modal .close{color:#fff;}
|
|
||||||
.dark.modal{color:#fff;}
|
|
||||||
.dark .table-striped>tbody>tr:nth-of-type(even){background:#616161}
|
.dark .table-striped>tbody>tr:nth-of-type(even){background:#616161}
|
||||||
.dark .table-striped>tbody>tr>td{border-color:#222;color:#fff}
|
.dark .table-striped>tbody>tr>td{border-color:#222;color:#fff}
|
||||||
.dark .table-striped>thead>tr>th{border-color:#222;color:#fff;background:#616161;vertical-align:middle;}
|
.dark .table-striped>thead>tr>th{border-color:#222;color:#fff;background:#616161;vertical-align:middle;}
|
||||||
|
@ -481,95 +237,10 @@ ul.msg_list li .message {
|
||||||
.mdl-js-layout.hide-side:not(.is-small-screen)>.mdl-layout__header{
|
.mdl-js-layout.hide-side:not(.is-small-screen)>.mdl-layout__header{
|
||||||
margin-left: 0px;width:100%;transition:0.2s
|
margin-left: 0px;width:100%;transition:0.2s
|
||||||
}
|
}
|
||||||
/*Control Pad*/
|
.mdl-menu__item>div{display:flex;align-items: center;width:100%}
|
||||||
.PTZ_controls {
|
.mdl-menu__item>div>i{margin-right:5px}
|
||||||
z-index: 111;
|
|
||||||
position: absolute;
|
|
||||||
left: 20px;
|
|
||||||
top: 20px;
|
|
||||||
margin:0;
|
|
||||||
display: inline-block;
|
|
||||||
width: 120px;
|
|
||||||
}
|
|
||||||
.PTZ_controls .btn-group{margin-top:10px}
|
|
||||||
.PTZ_controls .pad {
|
|
||||||
position: relative;
|
|
||||||
height: 120px;
|
|
||||||
width: 120px;
|
|
||||||
background: #b7b7b7;
|
|
||||||
border-radius: 50%;
|
|
||||||
box-shadow: inset 0 0 1px rgba(120, 120, 120, 0.6), inset 0 2px 2px rgba(0, 0, 0, 0.1), 0 2px 2px rgba(240, 240, 240, 0.4);
|
|
||||||
}
|
|
||||||
.PTZ_controls .control {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
.PTZ_controls .pad .control {
|
|
||||||
height: 30px;
|
|
||||||
width: 30px;
|
|
||||||
background: #636363;
|
|
||||||
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(60, 60, 60, 0.2), 0 0 0 4px rgba(60, 60, 60, 0.2);
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
.PTZ_controls .zoom_in{
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
.PTZ_controls .zoom_out{
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
.PTZ_controls .nv_enabled{
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
.PTZ_controls .nv_disable{
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
.PTZ_controls .pad .top {
|
|
||||||
top: 15px;
|
|
||||||
left: 50%;
|
|
||||||
margin: 0 0 0 -15px;
|
|
||||||
}
|
|
||||||
.PTZ_controls .pad .left {
|
|
||||||
top: 45px;
|
|
||||||
left: 15px;
|
|
||||||
}
|
|
||||||
.PTZ_controls .pad .right {
|
|
||||||
top: 45px;
|
|
||||||
right: 15px;
|
|
||||||
}
|
|
||||||
.PTZ_controls .pad .control.right:before {
|
|
||||||
transform: rotate(90deg) translate(-3px, -5px);
|
|
||||||
}
|
|
||||||
.PTZ_controls .pad .bottom {
|
|
||||||
bottom: 15px;
|
|
||||||
left: 50%;
|
|
||||||
margin: 0 0 0 -15px;
|
|
||||||
}
|
|
||||||
/* Overlap the other controls to hide box-shadow */
|
|
||||||
.PTZ_controls .pad .middle {
|
|
||||||
height: 34px;
|
|
||||||
width: 34px;
|
|
||||||
z-index: 5;
|
|
||||||
top: 43px;
|
|
||||||
left: 50%;
|
|
||||||
margin: 0 0 0 -17px;
|
|
||||||
box-shadow: none;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
.PTZ_controls .pad .middle:after {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
margin: -35% 0 0 -35%;
|
|
||||||
content: '';
|
|
||||||
background: #636363;
|
|
||||||
height: 70%;
|
|
||||||
width: 70%;
|
|
||||||
border-radius: 100%;
|
|
||||||
box-shadow: inset 0 0 2px rgba(120, 120, 120, 0.6), inset 0 2px 8px rgba(0, 0, 0, 0.1), 0 2px 2px rgba(240, 240, 240, 0.2);
|
|
||||||
}
|
|
||||||
/*Digital Zoom*/
|
/*Digital Zoom*/
|
||||||
.stream-block{
|
.stream-block{
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -663,20 +334,7 @@ ul.msg_list li .message {
|
||||||
-moz-animation: blink 1s linear infinite;
|
-moz-animation: blink 1s linear infinite;
|
||||||
animation: blink 1s linear infinite;
|
animation: blink 1s linear infinite;
|
||||||
}
|
}
|
||||||
.mdl-menu__item>div{display:flex;align-items: center;width:100%}
|
|
||||||
.mdl-menu__item>div>i{margin-right:5px}
|
|
||||||
/*For languages that are right to left*/
|
|
||||||
.right-to-left {text-align:right}
|
|
||||||
.right-to-left select{direction: rtl;}
|
|
||||||
.right-to-left input,.right-to-left textarea{direction: rtl;text-align:right}
|
|
||||||
.right-to-left .form-group label span{padding-right:10px}
|
|
||||||
.right-to-left .modal-footer{text-align:left}
|
|
||||||
.right-to-left .mdl-menu__item>div>*{flex:1}
|
|
||||||
.right-to-left .mdl-menu__item>div>i{margin-right:0;margin-left:5px}
|
|
||||||
.right-to-left .mdl-menu__item{text-align:right}
|
|
||||||
.right-to-left .mdl-menu__item i{float:right}
|
|
||||||
.right-to-left .pull-right,.right-to-left .close{float:left!important}
|
|
||||||
.right-to-left .pull-left,.right-to-left .mdl-menu__item span{float:right!important}
|
|
||||||
/* All-CSS Toggle Switch (Checkbox Hack) by Marcus Burnette - https://codepen.io/mburnette/pen/LxNxNg */
|
/* All-CSS Toggle Switch (Checkbox Hack) by Marcus Burnette - https://codepen.io/mburnette/pen/LxNxNg */
|
||||||
.marc-toggle {
|
.marc-toggle {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
|
|
|
@ -0,0 +1,742 @@
|
||||||
|
/*Cusotm Bootstrap*/
|
||||||
|
.col-5ths,
|
||||||
|
.col-sm-5ths,
|
||||||
|
.col-md-5ths,
|
||||||
|
.col-lg-5ths {
|
||||||
|
position: relative;
|
||||||
|
min-height: 1px;
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-5ths {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-webkit-flex: 0 0 20%;
|
||||||
|
-ms-flex: 0 0 20%;
|
||||||
|
flex: 0 0 20%;
|
||||||
|
max-width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 576px) {
|
||||||
|
.col-sm-5ths {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-webkit-flex: 0 0 20%;
|
||||||
|
-ms-flex: 0 0 20%;
|
||||||
|
flex: 0 0 20%;
|
||||||
|
max-width: 20%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.col-md-5ths {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-webkit-flex: 0 0 20%;
|
||||||
|
-ms-flex: 0 0 20%;
|
||||||
|
flex: 0 0 20%;
|
||||||
|
max-width: 20%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background-color:#bd9565;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color:#bd9565;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
/**/
|
||||||
|
.flex{display:flex}
|
||||||
|
.flex>div{flex:1}
|
||||||
|
.flex-block{display:inline-flex;width:100%;flex-flow: row wrap;}
|
||||||
|
.flex-unit-3{flex:3}
|
||||||
|
.flex-inline{display: inline-flex;position:relative}
|
||||||
|
@import (less) "../less/pie.less";
|
||||||
|
ul{list-style:none}
|
||||||
|
*{transition:0.2s;box-sizing:border-box}
|
||||||
|
.affix-top{position:fixed}
|
||||||
|
.no-padding{padding:0!important}
|
||||||
|
.no-margin{margin:0!important}
|
||||||
|
.pre-inline{white-space: normal;word-break: normal}
|
||||||
|
.pre-inline>ul{margin:0;padding:0}
|
||||||
|
a{cursor:pointer}
|
||||||
|
nav h4{cursor:default;font-size:95%;padding:16px 40px;font-weight:100;text-transform:uppercase;letter-spacing:2px}
|
||||||
|
.m-r{margin-right:10px}
|
||||||
|
.m-b{margin-bottom:10px}
|
||||||
|
.m-t{margin-top:10px}
|
||||||
|
.m-l{margin-left:10px}
|
||||||
|
.overflow-hidden{overflow: hidden!important}
|
||||||
|
.list-inline{list-style:none}
|
||||||
|
.list-inline li{display:inline-block;vertical-align: top;margin:0;}
|
||||||
|
.truncate{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
||||||
|
img{max-width:100%}
|
||||||
|
.display-table{display:table;width:100%}
|
||||||
|
.display-inline{display:inline-block}
|
||||||
|
.display-table-cell{display:table-cell}
|
||||||
|
.small{font-size:80%}
|
||||||
|
.super-center{position:absolute;left:0;top:0;right:0;bottom:0;margin:auto;width: 4em;height: 1em;}
|
||||||
|
.jpegMode .cpu_load .progress-bar,.jpegMode .ram_load .progress-bar{background-color:#5cb85c}
|
||||||
|
.jpegMode [system="jpegToggle"],[system].text-success{color:#5cb85c!important}
|
||||||
|
.permission_monitor_edit{display:none}
|
||||||
|
.permission_video_delete{display:none}
|
||||||
|
.nodata .divider{margin:5px 0}
|
||||||
|
.loading .divider{margin:5px 0}
|
||||||
|
|
||||||
|
#accbtn{
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.monitor_item .stream-hud{opacity:0;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2}
|
||||||
|
.monitor_item .stream-hud .camera_cpu_usage{position:absolute;top:0;left:0;width: 100%;}
|
||||||
|
.monitor_item .stream-hud .camera_cpu_usage .progress{width: 100%;}
|
||||||
|
.monitor_item .stream-hud .camera_cpu_usage:hover .progress{height:20px;transition:0.2s}
|
||||||
|
.monitor_item .stream-hud .controls{position:absolute;top:10px;left:10px;}
|
||||||
|
.monitor_item .stream-hud:hover{opacity:1}
|
||||||
|
.monitor_item .stream-hud .bottom-text{position:absolute;bottom:0;left:0;width:100%;padding:5px;text-shadow: 0 0 10px #333;}
|
||||||
|
.monitor_item .stream-hud .bottom-text .detector-fade{background: rgba(0,0,0,0.4);padding:10px 20px;border-radius:10px}
|
||||||
|
.monitor_item .stream-hud .lamp{position:absolute;top:5px;right:5px;z-index:1;text-shadow: 0 0 15px #333;}
|
||||||
|
.monitor_item[mode="Disabled"] .stream-hud .lamp{color:#5d5d5d}
|
||||||
|
.monitor_item[mode="Watch Only"] .stream-hud .lamp{color:#5da8e8}
|
||||||
|
.monitor_item[mode="Idle"] .stream-hud .lamp{color:#fff}
|
||||||
|
.monitor_item[mode="Record"] .stream-hud .lamp{color:#d9534f}
|
||||||
|
/*.data-menu{max-height:700px}*/
|
||||||
|
.data-menu:not(:last-child){border-right:1px solid #fff;}
|
||||||
|
.data-menu.logs{list-style:none;}
|
||||||
|
.monitor_item .motionVision{display:none}
|
||||||
|
|
||||||
|
.monitor_item .grid-stack-item-content{width:100%!important;left:0!important;right:0!important}
|
||||||
|
.monitor_item .ui-resizable-se {bottom: 10px!important;}
|
||||||
|
.monitor_item .stream-block{position: relative;text-align: center}
|
||||||
|
.monitor_item .mdl-data_window{overflow-x: auto;background:rgba(0,0,0,0.7);color:#fff;height:100%}
|
||||||
|
.monitor_item .mdl-data_window:not(.col-md-6){width:0;min-width:0;height:0px;min-height:0}
|
||||||
|
|
||||||
|
|
||||||
|
.monitor_item.fullscreen img.stream-element{height:100%;width:auto}
|
||||||
|
.monitor_item.fullscreen canvas.stream-element{height:auto;width:auto;background-color:black;}
|
||||||
|
.monitor_item .stream-element{border: 0;object-fit: fill;height: 100%;width:100%}
|
||||||
|
.monitor_item{position:relative;padding:0;transition:none;background:#000}
|
||||||
|
.monitor_item .mdl-card{min-height:auto;border:1px solid #272727;border-radius:0px;overflow:hidden}
|
||||||
|
.monitor_item .mdl-card__media{position:relative;padding:0!important;display:block!important;background:#000;}
|
||||||
|
.monitor_item.selected .stream-element{height:600px}
|
||||||
|
.monitor_item.selected .fa-expand:before{content:"\f066"}
|
||||||
|
.monitor_item .mdl-card__supporting-text{background:#222;color:#fff!important;display:block;min-height:auto!important}
|
||||||
|
.monitor_item.detector_triggered .detector-fade{opacity:1}
|
||||||
|
.monitor_item .detector-fade{opacity:0}
|
||||||
|
.monitor_item .indifference{position:absolute;width:100%;left:0;top:0;transition:0.2s;}
|
||||||
|
.monitor_item .progress{width:100%;background:#333;box-shadow:0;}
|
||||||
|
.monitor_item .indifference:hover .progress{height:20px;transition:0.2s}
|
||||||
|
.hide_indifference .indifference{display:none!important}
|
||||||
|
.hide_indifference [class_toggle="hide_indifference"]{color:#d9534f!important}
|
||||||
|
.monitor_item .mdl-card:not(.mdl-cell--4-col-desktop) .mdl-card__supporting-text .monitor_details{display:none;font-size:90%;margin-bottom:10px}
|
||||||
|
.monitor_item[mode="Record"] [mode="record"]{display:none}
|
||||||
|
.monitor_item[mode="Watch Only"] [mode="start"]{display:none}
|
||||||
|
.monitor_item .stream-hud .controls .btn{opacity:0.7}
|
||||||
|
.monitor_item.doObjectDetection .progress-bar{background-color: #57d94f}
|
||||||
|
|
||||||
|
@media screen and (max-width:1500px){
|
||||||
|
.monitor_item .mdl-card__supporting-text .btn{
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#monitors_live .monitor_item [class_toggle="show_logs"]{display:none}
|
||||||
|
#monitors_live .monitor_item .indifference{top:-5px}
|
||||||
|
#monitors_live .monitor_item .mdl-cell--8-col{width:100%;border:0;border-radius:0;margin:0;position:relative}
|
||||||
|
#monitors_live .monitor_item .mdl-cell--4-col-desktop,.monitor_item .mdl-card__supporting-text{display:none}
|
||||||
|
#monitors_live .monitor_item .mdl-card__supporting-text .monitor_details,#monitors_live .monitor_item .mdl-card__supporting-text .btn-group{display:none;text-align:center}
|
||||||
|
#monitors_live .monitor_item .mdl-card__supporting-text:not(.meta){display:block;position:absolute;bottom:0;left:0;height:0;padding:0;overflow:visible;}
|
||||||
|
#monitors_live .monitor_item.show_data .mdl-card__supporting-text:not(.meta){width:50%}
|
||||||
|
#monitors_live .monitor_item.detector_triggered .mdl-card__supporting-text:not(.meta) .indifference{opacity:0.5;}
|
||||||
|
#monitors_live .monitor_item:hover .mdl-card__supporting-text:not(.meta){padding:15px;z-index:15;height:auto;}
|
||||||
|
#monitors_live .monitor_item:hover .mdl-card__supporting-text .monitor_details{display:block}
|
||||||
|
#monitors_live .monitor_item:hover .mdl-card__supporting-text .btn-group{display:inline-block}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#vis_pwrvideo{height:250px}
|
||||||
|
#monSectionStreamChannels,#monSectionInputMaps{margin-bottom: 15px;}
|
||||||
|
#monSectionStreamChannels:empty,#monSectionInputMaps:empty{display:none}
|
||||||
|
#region_editor_live iframe,.canvas_holder canvas{border:0;position:absolute;left:0;top:0}
|
||||||
|
.canvas_holder canvas{z-index:11}
|
||||||
|
|
||||||
|
.demo-blog .mdl-card__media ~ .mdl-card__supporting-text{position:relative;overflow:initial;cursor:move}
|
||||||
|
.demo-blog .mdl-card__media ~ .mdl-card__supporting-text .btn-group{cursor: default}
|
||||||
|
|
||||||
|
.demo-blog .demo-blog__posts.montage{max-width:100%}
|
||||||
|
|
||||||
|
|
||||||
|
.mdl-layout__header-row{padding-left:10!important}
|
||||||
|
.mdl-layout__header-row .nav>li>a{border-radius:50%;}
|
||||||
|
.mdl-layout__drawer-button i{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;height:1em;color:#fff}
|
||||||
|
.data-menu{text-align:left}
|
||||||
|
.data-menu ul,.side-menu ul{list-style:none;margin:0;padding:0;}
|
||||||
|
.data-menu li,.side-menu li{
|
||||||
|
border-bottom:1px solid #54502d;padding:10px;
|
||||||
|
}
|
||||||
|
.data-menu .progress-circle{margin:0 10px 0 0;position:relative;height:40px;width:40px;float:left}
|
||||||
|
.data-menu .progress-circle span:after{content:''}
|
||||||
|
img.circle-img,div.circle-img{border-radius:50%;height:50px;width:50px}
|
||||||
|
.circle-img.sm{height:25px;width:25px}
|
||||||
|
|
||||||
|
.video_video{margin:auto;max-width:100%;max-height:600px;}
|
||||||
|
#confirm_window .video_video{margin-top:15px}
|
||||||
|
#confirm_window .info-table{margin-top:15px}
|
||||||
|
@media (max-width: 768px){
|
||||||
|
.full.modal .modal-body,.medium.modal .modal-body{max-height:400px;overflow:auto}
|
||||||
|
}
|
||||||
|
@media (min-width: 768px){
|
||||||
|
.modal.full,.modal.medium{padding-left:0!important;}
|
||||||
|
.modal.full .modal-dialog{width:calc(100% - 10px)!important;margin: 30px auto;}
|
||||||
|
.modal.medium .modal-dialog{width:calc(70% - 10px)!important;margin: 30px auto;}
|
||||||
|
.full.modal .modal-body,.medium.modal .modal-body{height:calc(100% - 200px);overflow:auto}
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container-modal-body{overflow: auto}
|
||||||
|
.flex-container-modal-body .flex-block>div{flex:1;float:none}
|
||||||
|
|
||||||
|
.modal{overflow:auto!important}
|
||||||
|
form.modal-body{margin:0}
|
||||||
|
#region_editor .modal-body{text-align:center;overflow:auto;max-height:800px}
|
||||||
|
#region_editor .canvas_holder{position:relative;display:inline-block;overflow:auto;min-height:450px}
|
||||||
|
#region_editor .cord_element{position:absolute;background:rgba(221, 221, 221, 0.8);z-index:11;padding:5px;}
|
||||||
|
#region_editor .cord_element.selected{z-index:12;}
|
||||||
|
#region_editor .cord_element .controls{margin-bottom:5px;}
|
||||||
|
.form-group label span{padding:5px;font-weight: 400;color: #2d2d2d;display:block;border-bottom: 1px dotted #ddd;font-size: 10pt;}
|
||||||
|
.form-group label{display:table}
|
||||||
|
.form-group label>div{display:table-cell}
|
||||||
|
.form-group label>div:nth-child(2n-1){width:30%}
|
||||||
|
.form-group label>div:nth-child(2){width:70%;padding:5px;border:1px solid #dedede;border-radius:5px}
|
||||||
|
.dark .form-group label>div,.dark .form-group label>div>span{border-color:#454545;color:#fff}
|
||||||
|
.important.form-group label>div:nth-child(2),.important.form-group label>div>span{border-color:red}
|
||||||
|
.form-group label span small{margin-left: 2px;display:block;font-weight: 600;}
|
||||||
|
.form-group-group .round-left{border-radius: 50px 0 0 50px;margin-left:10px}
|
||||||
|
.form-group-group blockquote:before,.form-group-group blockquote:after{display:none!important}
|
||||||
|
.form-group-group blockquote{letter-spacing:normal;font-style:normal}
|
||||||
|
.form-group-group blockquote p:empty{display:none}
|
||||||
|
.form-group-group blockquote p{font-size:inherit}
|
||||||
|
.form-group-group blockquote p:last-child{margin-bottom:0}
|
||||||
|
.form-group-group-group>div,.form-group-group-group .h_us_advanced>div{margin-bottom:15px;}
|
||||||
|
.form-group-group{padding:0 10px 10px 10px;overflow:hidden;margin-bottom:15px;border-radius:5px;border:1px solid #ddd;background:#fff}
|
||||||
|
.form-group-group table{width:100%}
|
||||||
|
.form-group-group table tr td{padding:10px 5px}
|
||||||
|
.form-group-group table tr:not(:last-child) td{border-bottom:1px dotted #eee}
|
||||||
|
.form-group-group .mdl-list__item{border-bottom:1px solid #eee;}
|
||||||
|
.form-group-group .mdl-list__item:hover{background:#e6e6e6;border-radius:4px;}
|
||||||
|
.dark .form-group-group .mdl-list__item{color:#fff;border-bottom:1px solid #444;}
|
||||||
|
.dark .form-group-group .mdl-list__item:hover{background:#555;}
|
||||||
|
.form-group-group:last-child,.form-group-group > .form-group:last-child{margin-bottom:0}
|
||||||
|
.form-group-group h4{margin:0 -10px 15px -10px;padding:15px;background:#ddd;}
|
||||||
|
.form-group-group h4 small{color:#fff;}
|
||||||
|
.form-group-group.red{border-color:#d9534f}
|
||||||
|
.form-group-group.red h4{background:#d9534f;color:#fff}
|
||||||
|
.form-group-group.purple{border-color:#3f51b5}
|
||||||
|
.form-group-group.purple h4{background:#3f51b5;color:#fff}
|
||||||
|
.form-group-group.blue{border-color:#337ab7}
|
||||||
|
.form-group-group.blue h4{background:#337ab7;color:#fff}
|
||||||
|
.form-group-group.navy{border-color:#31708f}
|
||||||
|
.form-group-group.navy h4{background:#31708f;color:#fff}
|
||||||
|
.form-group-group.green{border-color:#449d44}
|
||||||
|
.form-group-group.green h4{background:#449d44;color:#fff}
|
||||||
|
.form-group-group.forestgreen{border-color:#1e4046}
|
||||||
|
.form-group-group.forestgreen h4{background:#1e4046;color:#fff}
|
||||||
|
.form-group-group.orange{border-color:#c49a68}
|
||||||
|
.form-group-group.orange h4{background:#c49a68;color:#fff}
|
||||||
|
.form-group-group.grey{border-color:#777}
|
||||||
|
.form-group-group.grey h4{background:#777;color:#fff}
|
||||||
|
.dark .form-group-group{background:#222}
|
||||||
|
.videos_list .title{font-size:12pt;padding:0 10px}
|
||||||
|
[status="1"] .btn[video="launch"],[data-status="1"] .btn[video="launch"]{background:#337ab7;border-color:#337ab7}
|
||||||
|
[status="2"] .btn[launch="video"],[status="2"] .btn[video="launch"],[data-status="2"] .btn[video="launch"]{background:#a59100;border-color:#a59100}
|
||||||
|
.signal.red{background:#c9302c}
|
||||||
|
.signal.green{background:#5cb85c}
|
||||||
|
.demo-drawer{background:#2b2a2a;color:#fff;}
|
||||||
|
.demo-drawer.mdl-layout__drawer .mdl-navigation{padding-top:0;}
|
||||||
|
.demo-drawer::-webkit-scrollbar{display:none;}
|
||||||
|
.small-square-img{height:40px;width:40px;border-radius:5px}
|
||||||
|
|
||||||
|
.side-menu .monitor_block{padding:0;position:relative}
|
||||||
|
.side-menu .monitor_block img{width:100%;height:75px;cursor:pointer;border: 0.5px inset #263238;}
|
||||||
|
@media screen and (max-width:1025px){
|
||||||
|
.side-menu .monitor_block img{height:175px;}
|
||||||
|
}
|
||||||
|
.side-menu .monitor_block:hover .icons{opacity:1}
|
||||||
|
.side-menu .monitor_block:hover .title{opacity:1}
|
||||||
|
.side-menu .monitor_block .icons,.side-menu .monitor_block .title{opacity:0;width:100%;bottom:0;left:0;background:rgba(0,0,0,0.6);position:absolute;padding:2.5px;z-index:11;cursor:move}
|
||||||
|
.side-menu .monitor_block .title{bottom:auto;top:0;color:#fff}
|
||||||
|
.nav-xs.side-menu .monitor_block{width:100%}
|
||||||
|
.side-menu .monitor_block .list-data{display:none}
|
||||||
|
.output_data:empty{display:none}
|
||||||
|
.output_data{max-height:500px;font-family:monospace;padding:10px;border-radius:5px;background:#f3f3f3;overflow:auto}
|
||||||
|
.dark .output_data{background:#222;}
|
||||||
|
#probe .output_data div>div{margin-left:10px}
|
||||||
|
.side-menu.list-blocks .monitor_block .icons,.side-menu.list-blocks .monitor_block .title{position:inherit;opacity:1;background:none}
|
||||||
|
.side-menu.list-blocks .monitor_block .title{padding:5px;border-radius:5px;background:#222;}
|
||||||
|
.side-menu.list-blocks .monitor_block:not(:last-child){border-bottom: 1px solid #54502d;}
|
||||||
|
.side-menu.list-blocks .monitor_block:first-child{border-top: 1px solid #54502d;}
|
||||||
|
.side-menu.list-blocks .monitor_block{float:none;width:100%;padding: 10px}
|
||||||
|
.side-menu.list-blocks .monitor_block.ui-sortable-helper{background:rgba(0,0,0,0.6);border-radius:5px;padding:5px;border:0}
|
||||||
|
.side-menu.list-blocks .monitor_block .list-data{display:block}
|
||||||
|
.side-menu.list-blocks .monitor_block img{width:60px;height:60px;cursor:pointer;display:inline-block;margin-right:10px;border-radius:50%;vertical-align:top;border:0}
|
||||||
|
.nav-xs.side-menu.list-blocks .monitor_block img{width:40px;height:40px;}
|
||||||
|
.side-menu.list-blocks .monitor_block .box{width:calc(100% - 70px);display:inline-block}
|
||||||
|
.nav-xs.side-menu.list-blocks .monitor_block .list-data{display:none}
|
||||||
|
#monitors_list .monitor_block{transition:none}
|
||||||
|
.dropdown-menu.scrollable{max-height:300px}
|
||||||
|
.upload_file input{display:none}
|
||||||
|
#video_preview .stream-objects{right:0;margin:auto;display:inline-block;position:relative;width:auto}
|
||||||
|
.stream-block,.stream-objects{overflow: hidden!important}
|
||||||
|
.stream-objects{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}
|
||||||
|
.stream-objects .tag{position:absolute;bottom:100%;left:0;background:red;color:#fff;font-family:monospace;font-size:80%;border-radius:5px 5px 0 0 ;padding:3px 5px;}
|
||||||
|
.stream-objects .stream-detected-object{position:absolute;top:0;left:0;border:3px solid red;background:transparent;border-radius:5px}
|
||||||
|
.stream-objects .stream-detected-point{position:absolute;top:0;left:0;border:3px solid yellow;background:transparent;border-radius:5px}
|
||||||
|
.stream-objects .point{position:absolute;top:0;left:0;border:3px solid red;border-radius:50%}
|
||||||
|
|
||||||
|
|
||||||
|
#side_menu_right.nav-xs{width:0!important;overflow:hidden}
|
||||||
|
.side-menu table{color:#fff;}
|
||||||
|
#main_canvas{background:#333;color:#fff;padding-top:0}
|
||||||
|
#main_header{background:#222;color:#fff;}
|
||||||
|
#logs_modal table tr td:first-child{width:10%}
|
||||||
|
[class_toggle]{cursor:pointer}
|
||||||
|
|
||||||
|
.form-group label{width:100%}
|
||||||
|
|
||||||
|
#pvideo_viewer iframe{border:0;width:100%;height:350px;margin-bottom:10px;overflow:hidden}
|
||||||
|
#pvideo_viewer video{max-height:300px;max-width:100%;}
|
||||||
|
#pvideo_viewer .holder{height:300px;}
|
||||||
|
#pvideo_viewer h3{margin-top:0}
|
||||||
|
#pvideo_viewer .progressBar{position:relative;}
|
||||||
|
#pvideo_viewer .bufferBar{position:absolute;left:0;top:0;opacity:0.4}
|
||||||
|
#pvideo_viewer .timeBar{position:relative;z-index: 222;background:transparent}
|
||||||
|
#pvideo_viewer h3{font-family:monospace}
|
||||||
|
|
||||||
|
#vis_monitors{overflow:auto;max-height:400px}
|
||||||
|
#vis_monitors .btn-group-vertical{width:100%}
|
||||||
|
|
||||||
|
/*timeline*/
|
||||||
|
#timelapse_video_line{overflow-y:scroll;overflow-x:hidden;max-height:400px;margin:0;text-align:left}
|
||||||
|
#timelapse_video_display .videoBefore,#timelapse_video_display .videoAfter{display:none}
|
||||||
|
.timelapse_video:not(:last-child){border-bottom:1px solid #444;}
|
||||||
|
.timelapse_video .frame{width:50px;height:50px;background-size:cover;background-position:center;border-radius:5px}
|
||||||
|
.timelapse_video>div>div:not(:last-child){padding-right:10px}
|
||||||
|
.timelapse_video .flex-block:not(:last-child){padding-bottom:10px}
|
||||||
|
.timelapse_video.list-group-item{padding:10px}
|
||||||
|
.timelapse_hud{position: relative;background:#000}
|
||||||
|
.timelapse_hud .timelapse_playRate{position: absolute;font-family: monospace;top:10px;right:0;left:0;margin:auto;font-size:23px}
|
||||||
|
#timelapse .progress-bar{transition:0.5s!important}
|
||||||
|
.timelapse_hud .controlBar{position: absolute;background:rgba(22,22,22,0.8);width:100%;left:0;bottom:0;}
|
||||||
|
.timelapse_hud .hover-hide{opacity:0}
|
||||||
|
.timelapse_hud:hover .hover-hide{opacity:1;z-index:5}
|
||||||
|
.video_grid{overflow: auto;height: 100%;display: block;}
|
||||||
|
.video_grid .col-md-2{padding-left:5px;padding-right:5px;padding-bottom:10px}
|
||||||
|
.video_grid .thumb{width:100%;height:150px;display:inline-block;background-size:cover;position:relative;overflow:hidden;border-radius:4px;border:1px solid #000;box-shadow:0 0 10px #151515}
|
||||||
|
.video_grid .thumb .title-strip, .video_grid .thumb .button-strip{width:100%;position:absolute;left:0;background:rgba(0,0,0,0.7);color:#fff;padding:4px}
|
||||||
|
.video_grid .thumb .title-strip{top:0;opacity:0.5}
|
||||||
|
.video_grid .thumb .button-strip{bottom:0;opacity:0}
|
||||||
|
.video_grid .thumb:hover .title-strip, .video_grid .thumb:hover .button-strip{opacity:1}
|
||||||
|
|
||||||
|
.table-striped>tbody>tr>td{vertical-align:middle}
|
||||||
|
.table-striped .thumbnail{width:100px;height:80px;border-radius:5px;margin:0;display:inline-block;}
|
||||||
|
#motion_list{height:155px;overflow:auto;border-radius:5px;border:1px solid #444;position:relative;background: #222;margin:0}
|
||||||
|
.dark .list-group-item{border-color: #444;background:#222}
|
||||||
|
.dark .list-group-item.active{background:#c49a68;border-color:#a7865f}
|
||||||
|
.novideos{text-transform: uppercase;text-align: center;border-bottom:0!important;padding-top: 55%!important;letter-spacing:2px}
|
||||||
|
|
||||||
|
.btn-warning {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #c49a68;
|
||||||
|
border-color: #c49a68;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark.modal .modal-header,.dark.modal .modal-footer{background:#333;border-color:#444;}
|
||||||
|
.dark.modal .modal-header{color:#fff;}
|
||||||
|
.dark.modal .modal-footer>*:not(.btn){color:#fff;}
|
||||||
|
.dark.modal .modal-body{background:#333;}
|
||||||
|
.dark.modal .close{color:#fff;}
|
||||||
|
.dark.modal{color:#fff;}
|
||||||
|
.dark .table-striped>tbody>tr:nth-of-type(even){background:#616161}
|
||||||
|
.dark .table-striped>tbody>tr>td{border-color:#222;color:#fff}
|
||||||
|
.dark .table-striped>thead>tr>th{border-color:#222;color:#fff;background:#616161;vertical-align:middle;}
|
||||||
|
.dark .table-striped>tbody>tr:nth-of-type(odd){background-color: #4c4747;}
|
||||||
|
.dark .table>tbody>tr.active>td{background:inherit;border:0}
|
||||||
|
.dark code{color: #c49a68;background-color: #36333d;}
|
||||||
|
.dark a:not(.btn){color: #c49a68;}
|
||||||
|
.follow-list ul{padding:0;margin:0;font-family:"Roboto","Helvetica","Arial",sans-serif;}
|
||||||
|
.follow-list ul a:not(.btn){color:#fff}
|
||||||
|
.os_bars{width:600px;display:inline-block;padding:5px 0 0 10px}
|
||||||
|
@media screen and (max-width: 600px){
|
||||||
|
.os_bars{width:200px;}
|
||||||
|
.os_bars label{padding:2.5px 0;margin:0;font-size:8pt}
|
||||||
|
}
|
||||||
|
.os_bars .display-table .display-table-cell{padding:5px;vertical-align:center;width:33%}
|
||||||
|
.progress{height:5px;margin:0;}
|
||||||
|
.os_bars label,.os_bars .percent{padding:2.5px 0;margin:0;font-size:7.5pt}
|
||||||
|
.ui-pnotify-hide .ui-pnotify{display:none!important}
|
||||||
|
/*cool dropdown thing*/
|
||||||
|
ul.msg_list li {
|
||||||
|
background: #f7f7f7;color:#333;
|
||||||
|
padding: 5px;
|
||||||
|
display: list-item;
|
||||||
|
margin: 6px 6px 0;
|
||||||
|
width: 96% !important
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.msg_list li div{display:block}
|
||||||
|
|
||||||
|
ul.msg_list li:last-child {
|
||||||
|
margin-bottom: 6px;
|
||||||
|
padding: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.msg_list li a {
|
||||||
|
padding: 3px 5px !important
|
||||||
|
}
|
||||||
|
ul.msg_list li .progress {
|
||||||
|
height:5px;margin:10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.msg_list li .image img {
|
||||||
|
border-radius: 2px 2px 2px 2px;
|
||||||
|
-webkit-border-radius: 2px 2px 2px 2px;
|
||||||
|
float: left;
|
||||||
|
margin-right: 10px;
|
||||||
|
width: 11%
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.msg_list li .time {
|
||||||
|
font-size: 11px;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: bold;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.msg_list li .message {
|
||||||
|
display: block !important;
|
||||||
|
font-size: 11px
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu.msg_list span {
|
||||||
|
white-space: normal
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
border: medium none;
|
||||||
|
box-shadow: none;
|
||||||
|
display: none;
|
||||||
|
float: left;
|
||||||
|
font-size: 12px;
|
||||||
|
left: 0;
|
||||||
|
list-style: none outside none;
|
||||||
|
padding: 0;
|
||||||
|
position: absolute;
|
||||||
|
text-shadow: none;
|
||||||
|
top: 100%;
|
||||||
|
z-index: 9998;
|
||||||
|
border: 1px solid #D9DEE4;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu>li>a {
|
||||||
|
color: #5A738E
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav .open .dropdown-menu {
|
||||||
|
position: absolute;
|
||||||
|
background: #fff;
|
||||||
|
margin-top: 0;
|
||||||
|
border: 1px solid #D9DEE4;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
width: 220px
|
||||||
|
}
|
||||||
|
.is-small-screen .nav>li{display:inline-block}
|
||||||
|
.navbar-nav .open .dropdown-menu li a{padding:7px 15px}
|
||||||
|
.navbar-nav .open .dropdown-menu.msg_list {
|
||||||
|
width: 300px
|
||||||
|
}
|
||||||
|
.nav>li>a{color:#fff}
|
||||||
|
.nav>li>a:focus, .nav>li>a:hover,.nav .open>a, .nav .open>a:focus, .nav .open>a:hover{background:#867560}
|
||||||
|
|
||||||
|
.mdl-js-layout.hide-side:not(.is-small-screen){
|
||||||
|
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 1025px){
|
||||||
|
.mdl-js-layout.hide-side:not(.is-small-screen)>.mdl-layout__drawer {
|
||||||
|
width: 0px;transition:0.2s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mdl-js-layout.hide-side:not(.is-small-screen) .mdl-layout__header .mdl-layout__drawer-button{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.mdl-js-layout.hide-side:not(.is-small-screen)>.mdl-layout__content{
|
||||||
|
margin-left: 0px;transition:0.2s
|
||||||
|
}
|
||||||
|
.mdl-js-layout.hide-side:not(.is-small-screen)>.mdl-layout__header{
|
||||||
|
margin-left: 0px;width:100%;transition:0.2s
|
||||||
|
}
|
||||||
|
/*Control Pad*/
|
||||||
|
.PTZ_controls {
|
||||||
|
z-index: 111;
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
top: 20px;
|
||||||
|
margin:0;
|
||||||
|
display: inline-block;
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .btn-group{margin-top:10px}
|
||||||
|
.PTZ_controls .pad {
|
||||||
|
position: relative;
|
||||||
|
height: 120px;
|
||||||
|
width: 120px;
|
||||||
|
background: #b7b7b7;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: inset 0 0 1px rgba(120, 120, 120, 0.6), inset 0 2px 2px rgba(0, 0, 0, 0.1), 0 2px 2px rgba(240, 240, 240, 0.4);
|
||||||
|
}
|
||||||
|
.PTZ_controls .control {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .control {
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
background: #636363;
|
||||||
|
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(60, 60, 60, 0.2), 0 0 0 4px rgba(60, 60, 60, 0.2);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .zoom_in{
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.PTZ_controls .zoom_out{
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.PTZ_controls .nv_enabled{
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.PTZ_controls .nv_disable{
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .top {
|
||||||
|
top: 15px;
|
||||||
|
left: 50%;
|
||||||
|
margin: 0 0 0 -15px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .left {
|
||||||
|
top: 45px;
|
||||||
|
left: 15px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .right {
|
||||||
|
top: 45px;
|
||||||
|
right: 15px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .control.right:before {
|
||||||
|
transform: rotate(90deg) translate(-3px, -5px);
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .bottom {
|
||||||
|
bottom: 15px;
|
||||||
|
left: 50%;
|
||||||
|
margin: 0 0 0 -15px;
|
||||||
|
}
|
||||||
|
/* Overlap the other controls to hide box-shadow */
|
||||||
|
.PTZ_controls .pad .middle {
|
||||||
|
height: 34px;
|
||||||
|
width: 34px;
|
||||||
|
z-index: 5;
|
||||||
|
top: 43px;
|
||||||
|
left: 50%;
|
||||||
|
margin: 0 0 0 -17px;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.PTZ_controls .pad .middle:after {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
margin: -35% 0 0 -35%;
|
||||||
|
content: '';
|
||||||
|
background: #636363;
|
||||||
|
height: 70%;
|
||||||
|
width: 70%;
|
||||||
|
border-radius: 100%;
|
||||||
|
box-shadow: inset 0 0 2px rgba(120, 120, 120, 0.6), inset 0 2px 8px rgba(0, 0, 0, 0.1), 0 2px 2px rgba(240, 240, 240, 0.2);
|
||||||
|
}
|
||||||
|
/*Digital Zoom*/
|
||||||
|
.stream-block{
|
||||||
|
position: relative;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.zoomGlass {
|
||||||
|
overflow: hidden;
|
||||||
|
transition: none;
|
||||||
|
width: 175px; height: 175px;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 15px;
|
||||||
|
border: 3px solid #ddd;
|
||||||
|
z-index:9999;
|
||||||
|
}
|
||||||
|
.zoomGlass iframe,.zoomGlass canvas{position:absolute;transition: none;}
|
||||||
|
.zoomGlass .hoverShade{position:absolute;width:100%;height:100%}
|
||||||
|
|
||||||
|
.dark.form-control,.dark .form-control {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 35px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #eee;
|
||||||
|
background-color: #36333d;
|
||||||
|
background-image: none;
|
||||||
|
border: 1px solid #444;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||||
|
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark.form-control:focus,.dark .form-control:focus {
|
||||||
|
color: #ddd;
|
||||||
|
background-color: #333;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*** custom checkboxes ***/
|
||||||
|
|
||||||
|
.checkbox input[type=checkbox] { display:none; } /* to hide the checkbox itself */
|
||||||
|
.checkbox input[type=checkbox] + label:before {
|
||||||
|
font-family: FontAwesome;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox input[type=checkbox] + label:before { content: "\f096"; } /* unchecked icon */
|
||||||
|
.checkbox input[type=checkbox] + label:before { letter-spacing: 10px; } /* space between checkbox and label */
|
||||||
|
|
||||||
|
.checkbox input[type=checkbox]:checked + label:before { content: "\f046"; } /* checked icon */
|
||||||
|
.checkbox input[type=checkbox]:checked + label:before { letter-spacing: 5px; } /* allow space for check mark */
|
||||||
|
|
||||||
|
/*Clock*/
|
||||||
|
#time-date {font-size:12px; text-align:center;}
|
||||||
|
@media screen and (min-width:1025px){
|
||||||
|
#clock {padding-right:35px}
|
||||||
|
}
|
||||||
|
#clock ul { width:150px; margin:0 auto; padding:0px; list-style:none; text-align:center; }
|
||||||
|
#clock ul li { display:inline; font-size:1.6em; text-align:center;font-family:monospace;}
|
||||||
|
|
||||||
|
#clock .point { position:relative; -moz-animation:mymove 1s ease infinite; -webkit-animation:mymove 1s ease infinite; }
|
||||||
|
|
||||||
|
/*custom vis.js css*/
|
||||||
|
.vis-timeline{background:#212121;color:#fff;border-color:#444}
|
||||||
|
.vis-time-axis .vis-text{color: #dedede}
|
||||||
|
.vis-item.vis-range .vis-item-content{background:#333;color:#fff}
|
||||||
|
.vis-time-axis .vis-grid.vis-minor{border-color:#444}
|
||||||
|
|
||||||
|
|
||||||
|
@-moz-document url-prefix() {
|
||||||
|
.full.modal .modal-body, .medium.modal .modal-body {
|
||||||
|
height:70%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*animations*/
|
||||||
|
@keyframes blink {
|
||||||
|
0% { opacity:1 }
|
||||||
|
50% { opacity:0 }
|
||||||
|
100% { opacity:1 }
|
||||||
|
}
|
||||||
|
@-webkit-keyframes blink {
|
||||||
|
0% { opacity:1 }
|
||||||
|
50% { opacity:0 }
|
||||||
|
100% { opacity:1 }
|
||||||
|
}
|
||||||
|
.blink,[mode="Record"] .lamp {
|
||||||
|
-webkit-animation: blink 1s linear infinite;
|
||||||
|
-moz-animation: blink 1s linear infinite;
|
||||||
|
animation: blink 1s linear infinite;
|
||||||
|
}
|
||||||
|
.mdl-menu__item>div{display:flex;align-items: center;width:100%}
|
||||||
|
.mdl-menu__item>div>i{margin-right:5px}
|
||||||
|
/*For languages that are right to left*/
|
||||||
|
.right-to-left {text-align:right}
|
||||||
|
.right-to-left select{direction: rtl;}
|
||||||
|
.right-to-left input,.right-to-left textarea{direction: rtl;text-align:right}
|
||||||
|
.right-to-left .form-group label span{padding-right:10px}
|
||||||
|
.right-to-left .modal-footer{text-align:left}
|
||||||
|
.right-to-left .mdl-menu__item>div>*{flex:1}
|
||||||
|
.right-to-left .mdl-menu__item>div>i{margin-right:0;margin-left:5px}
|
||||||
|
.right-to-left .mdl-menu__item{text-align:right}
|
||||||
|
.right-to-left .mdl-menu__item i{float:right}
|
||||||
|
.right-to-left .pull-right,.right-to-left .close{float:left!important}
|
||||||
|
.right-to-left .pull-left,.right-to-left .mdl-menu__item span{float:right!important}
|
||||||
|
/* All-CSS Toggle Switch (Checkbox Hack) by Marcus Burnette - https://codepen.io/mburnette/pen/LxNxNg */
|
||||||
|
.marc-toggle {
|
||||||
|
width: 50px;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
.marc-toggle.abs-bot-left {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
left: 10px;
|
||||||
|
}
|
||||||
|
.marc-toggle.abs-bot-right {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
.marc-toggle input[type=checkbox]{
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marc-toggle label {
|
||||||
|
cursor: pointer;
|
||||||
|
text-indent: -9999px;
|
||||||
|
width: 100px;
|
||||||
|
height: 20px;
|
||||||
|
background: grey;
|
||||||
|
display: block;
|
||||||
|
border-radius: 100px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marc-toggle label:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
left: 5px;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 90px;
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marc-toggle input:checked + label {
|
||||||
|
background: #00118c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marc-toggle input:checked + label:after {
|
||||||
|
left: calc(100% - 5px);
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.marc-toggle label:active:after {
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*hexagon pattern*/
|
||||||
|
.bg-hexagon {
|
||||||
|
background-color: #054e9f;
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='49' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg id='hexagons' fill='%23fdfdfd' fill-opacity='0.4' fill-rule='nonzero'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
|
||||||
|
}
|
|
@ -608,15 +608,6 @@ _:-ms-input-placeholder, :root .demo-graph {
|
||||||
opacity: 0.46;
|
opacity: 0.46;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
.social-btn__twitter {
|
|
||||||
background-image: url('https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png');
|
|
||||||
}
|
|
||||||
.social-btn__blogger {
|
|
||||||
background-image: url('https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png');
|
|
||||||
}
|
|
||||||
.social-btn__gplus {
|
|
||||||
background-image: url('https://www.gstatic.com/images/icons/material/system/2x/post_gplus_black_24dp.png');
|
|
||||||
}
|
|
||||||
.social-btn__share {
|
.social-btn__share {
|
||||||
color: rgba(0, 0, 0, 0.54);
|
color: rgba(0, 0, 0, 0.54);
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//api window
|
||||||
|
$.apM={e:$('#apis')};$.apM.f=$.apM.e.find('form');
|
||||||
|
$.apM.md=$.apM.f.find('[detail]');
|
||||||
|
$.apM.md.change($.ccio.form.details).first().change();
|
||||||
|
$.apM.f.submit(function(e){
|
||||||
|
e.preventDefault();e.e=$(this),e.s=e.e.serializeObject();
|
||||||
|
e.er=[];
|
||||||
|
if(!e.s.ip||e.s.ip.length<7){e.er.push('Enter atleast one IP')}
|
||||||
|
if(e.er.length>0){$.apM.e.find('.msg').html(e.er.join('<br>'));return;}
|
||||||
|
$.each(e.s,function(n,v){e.s[n]=v.trim()})
|
||||||
|
// e.s = {
|
||||||
|
// "ip": "",
|
||||||
|
// "details": "{\"get_monitors\":\"1\",\"control_monitors\":\"1\",\"get_logs\":\"1\",\"watch_stream\":\"1\",\"watch_snapshot\":\"1\",\"watch_videos\":\"1\",\"delete_videos\":\"1\"}"
|
||||||
|
// }
|
||||||
|
$.post($.ccio.init('location',$user)+$user.auth_token+'/api/'+$user.ke+'/add',{data:JSON.stringify(e.s)},function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
$.apM.e.on('click','.delete',function(e){
|
||||||
|
e.e=$(this);e.p=e.e.parents('[api_key]'),e.code=e.p.attr('api_key');
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text('Delete API Key');
|
||||||
|
e.html='Do you want to delete this API key? You cannot recover it.';
|
||||||
|
$.confirm.body.html(e.html);
|
||||||
|
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||||
|
$.post($.ccio.init('location',$user)+$user.auth_token+'/api/'+$user.ke+'/delete',{data:JSON.stringify({code:e.code})},function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,299 @@
|
||||||
|
$.ccio.permissionCheck = function(toCheck,monitorId){
|
||||||
|
var details = $user.details
|
||||||
|
if(details.sub && details.allmonitors === '0'){
|
||||||
|
var chosenValue = details[toCheck]
|
||||||
|
if(details[toCheck] instanceof Array && chosenValue.indexOf(monitorId) > -1){
|
||||||
|
return true
|
||||||
|
}else if(chosenValue === '1'){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
$.ccio.op = function(r,rr,rrr){
|
||||||
|
if(!rrr){rrr={};};if(typeof rrr === 'string'){rrr={n:rrr}};if(!rrr.n){rrr.n='ShinobiOptions_'+location.host}
|
||||||
|
ii={o:localStorage.getItem(rrr.n)};try{ii.o=JSON.parse(ii.o)}catch(e){ii.o={}}
|
||||||
|
if(!ii.o){ii.o={}}
|
||||||
|
if(r&&rr&&!rrr.x){
|
||||||
|
ii.o[r]=rr;
|
||||||
|
}
|
||||||
|
switch(rrr.x){
|
||||||
|
case 0:
|
||||||
|
delete(ii.o[r])
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
delete(ii.o[r][rr])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
localStorage.setItem(rrr.n,JSON.stringify(ii.o))
|
||||||
|
return ii.o
|
||||||
|
}
|
||||||
|
$.ccio.log = function(x,y,z){
|
||||||
|
if($.ccio.op().browserLog==="1"){
|
||||||
|
if(!y){y=''};if(!z){z=''};
|
||||||
|
console.log(x,y,z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.ccio.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;
|
||||||
|
};
|
||||||
|
$.ccio.downloadJSON = function(jsonToDownload,filename,errorResponse){
|
||||||
|
var arr = jsonToDownload;
|
||||||
|
if(arr.length===0 && errorResponse){
|
||||||
|
errorResponse.type = 'error'
|
||||||
|
$.ccio.init('note',errorResponse);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(arr,null,3));
|
||||||
|
$('#temp').html('<a></a>')
|
||||||
|
.find('a')
|
||||||
|
.attr('href',dataStr)
|
||||||
|
.attr('download',filename)
|
||||||
|
[0].click()
|
||||||
|
}
|
||||||
|
$.ccio.timeObject = function(time,isUTC){
|
||||||
|
if(isUTC === true){
|
||||||
|
return moment(time).utc()
|
||||||
|
}
|
||||||
|
return moment(time)
|
||||||
|
}
|
||||||
|
$.ccio.base64ArrayBuffer = function(arrayBuffer) {
|
||||||
|
var base64 = ''
|
||||||
|
var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||||
|
|
||||||
|
var bytes = new Uint8Array(arrayBuffer)
|
||||||
|
var byteLength = bytes.byteLength
|
||||||
|
var byteRemainder = byteLength % 3
|
||||||
|
var mainLength = byteLength - byteRemainder
|
||||||
|
|
||||||
|
var a, b, c, d
|
||||||
|
var chunk
|
||||||
|
|
||||||
|
// Main loop deals with bytes in chunks of 3
|
||||||
|
for (var i = 0; i < mainLength; i = i + 3) {
|
||||||
|
// Combine the three bytes into a single integer
|
||||||
|
chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
|
||||||
|
|
||||||
|
// Use bitmasks to extract 6-bit segments from the triplet
|
||||||
|
a = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18
|
||||||
|
b = (chunk & 258048) >> 12 // 258048 = (2^6 - 1) << 12
|
||||||
|
c = (chunk & 4032) >> 6 // 4032 = (2^6 - 1) << 6
|
||||||
|
d = chunk & 63 // 63 = 2^6 - 1
|
||||||
|
|
||||||
|
// Convert the raw binary segments to the appropriate ASCII encoding
|
||||||
|
base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deal with the remaining bytes and padding
|
||||||
|
if (byteRemainder == 1) {
|
||||||
|
chunk = bytes[mainLength]
|
||||||
|
|
||||||
|
a = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2
|
||||||
|
|
||||||
|
// Set the 4 least significant bits to zero
|
||||||
|
b = (chunk & 3) << 4 // 3 = 2^2 - 1
|
||||||
|
|
||||||
|
base64 += encodings[a] + encodings[b] + '=='
|
||||||
|
} else if (byteRemainder == 2) {
|
||||||
|
chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]
|
||||||
|
|
||||||
|
a = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10
|
||||||
|
b = (chunk & 1008) >> 4 // 1008 = (2^6 - 1) << 4
|
||||||
|
|
||||||
|
// Set the 2 least significant bits to zero
|
||||||
|
c = (chunk & 15) << 2 // 15 = 2^4 - 1
|
||||||
|
|
||||||
|
base64 += encodings[a] + encodings[b] + encodings[c] + '='
|
||||||
|
}
|
||||||
|
|
||||||
|
return base64
|
||||||
|
}
|
||||||
|
$.ccio.snapshot=function(e,cb){
|
||||||
|
var image_data,url;
|
||||||
|
e.details=JSON.parse(e.mon.details);
|
||||||
|
if($.ccio.op().jpeg_on!==true){
|
||||||
|
var extend=function(image_data,width,height){
|
||||||
|
var len = image_data.length
|
||||||
|
var arraybuffer = new Uint8Array( len );
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
arraybuffer[i] = image_data.charCodeAt(i);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var blob = new Blob([arraybuffer], {type: 'application/octet-stream'});
|
||||||
|
} catch (e) {
|
||||||
|
var bb = new (window.WebKitBlobBuilder || window.MozBlobBuilder);
|
||||||
|
bb.append(arraybuffer);
|
||||||
|
var blob = bb.getBlob('application/octet-stream');
|
||||||
|
}
|
||||||
|
url = (window.URL || window.webkitURL).createObjectURL(blob);
|
||||||
|
finish(url,image_data,width,height);
|
||||||
|
try{
|
||||||
|
setTimeout(function(){
|
||||||
|
URL.revokeObjectURL(url)
|
||||||
|
},10000)
|
||||||
|
}catch(er){}
|
||||||
|
}
|
||||||
|
var finish = function(url,image_data,width,height){
|
||||||
|
cb(url,image_data,width,height);
|
||||||
|
}
|
||||||
|
switch(JSON.parse(e.mon.details).stream_type){
|
||||||
|
case'hls':case'flv':case'mp4':
|
||||||
|
$.ccio.snapshotVideo($('[mid='+e.mon.mid+'].monitor_item video')[0],function(base64,video_data,width,height){
|
||||||
|
extend(video_data,width,height)
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case'mjpeg':
|
||||||
|
$('#temp').html('<canvas></canvas>')
|
||||||
|
var c = $('#temp canvas')[0];
|
||||||
|
var img = $('img',$('[mid='+e.mon.mid+'].monitor_item .stream-element').contents())[0];
|
||||||
|
c.width = img.width;
|
||||||
|
c.height = img.height;
|
||||||
|
var ctx = c.getContext('2d');
|
||||||
|
ctx.drawImage(img, 0, 0,c.width,c.height);
|
||||||
|
extend(atob(c.toDataURL('image/jpeg').split(',')[1]),c.width,c.height)
|
||||||
|
break;
|
||||||
|
case'h265':
|
||||||
|
var c = $('[mid='+e.mon.mid+'].monitor_item canvas')[0];
|
||||||
|
var ctx = c.getContext('2d');
|
||||||
|
extend(atob(c.toDataURL('image/jpeg').split(',')[1]),c.width,c.height)
|
||||||
|
break;
|
||||||
|
case'b64':
|
||||||
|
base64 = e.mon.last_frame.split(',')[1];
|
||||||
|
var image_data = new Image();
|
||||||
|
image_data.src = base64;
|
||||||
|
extend(atob(base64),image_data.width,image_data.height)
|
||||||
|
break;
|
||||||
|
case'jpeg':case'h265':
|
||||||
|
url=e.p.find('.stream-element').attr('src');
|
||||||
|
image_data = new Image();
|
||||||
|
image_data.src = url;
|
||||||
|
finish(url,image_data,image_data.width,image_data.height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
url=e.p.find('.stream-element').attr('src');
|
||||||
|
image_data = new Image();
|
||||||
|
image_data.src = url;
|
||||||
|
cb(url,image_data,image_data.width,image_data.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.ccio.snapshotVideo=function(videoElement,cb){
|
||||||
|
var image_data;
|
||||||
|
var base64
|
||||||
|
$('#temp').html('<canvas></canvas>')
|
||||||
|
var c = $('#temp canvas')[0];
|
||||||
|
var img = videoElement;
|
||||||
|
c.width = img.videoWidth;
|
||||||
|
c.height = img.videoHeight;
|
||||||
|
var ctx = c.getContext('2d');
|
||||||
|
ctx.drawImage(img, 0, 0,c.width,c.height);
|
||||||
|
base64=c.toDataURL('image/jpeg')
|
||||||
|
image_data=atob(base64.split(',')[1]);
|
||||||
|
var arraybuffer = new ArrayBuffer(image_data.length);
|
||||||
|
var view = new Uint8Array(arraybuffer);
|
||||||
|
for (var i=0; i<image_data.length; i++) {
|
||||||
|
view[i] = image_data.charCodeAt(i) & 0xff;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var blob = new Blob([arraybuffer], {type: 'application/octet-stream'});
|
||||||
|
} catch (e) {
|
||||||
|
var bb = new (window.WebKitBlobBuilder || window.MozBlobBuilder);
|
||||||
|
bb.append(arraybuffer);
|
||||||
|
var blob = bb.getBlob('application/octet-stream');
|
||||||
|
}
|
||||||
|
cb(base64,image_data,c.width,c.height);
|
||||||
|
}
|
||||||
|
$.ccio.magnifyStream = function(e){
|
||||||
|
if(!e.p){
|
||||||
|
e.e=$(this),
|
||||||
|
e.p=e.e.parents('[mid]')
|
||||||
|
}
|
||||||
|
if(e.animate === true){
|
||||||
|
var zoomGlassAnimate = 'animate'
|
||||||
|
}else{
|
||||||
|
var zoomGlassAnimate = 'css'
|
||||||
|
}
|
||||||
|
if(e.auto === true){
|
||||||
|
var streamBlockOperator = 'position'
|
||||||
|
}else{
|
||||||
|
var streamBlockOperator = 'offset'
|
||||||
|
}
|
||||||
|
if(e.useCanvas === true){
|
||||||
|
var magnifiedElement = 'canvas'
|
||||||
|
}else{
|
||||||
|
var magnifiedElement = 'iframe'
|
||||||
|
}
|
||||||
|
e.ke=e.p.attr('ke'),//group key
|
||||||
|
e.mid=e.p.attr('mid'),//monitor id
|
||||||
|
e.auth=e.p.attr('auth'),//authkey
|
||||||
|
e.mon=$.ccio.mon[e.ke+e.mid+e.auth]//monitor configuration
|
||||||
|
if(e.zoomAmount)e.mon.zoomAmount=3;
|
||||||
|
if(!e.mon.zoomAmount)e.mon.zoomAmount=3;
|
||||||
|
e.height=parseFloat(e.p.attr('realHeight')) * e.mon.zoomAmount//height of stream
|
||||||
|
e.width=parseFloat(e.p.attr('realWidth')) * e.mon.zoomAmount;//width of stream
|
||||||
|
var targetForZoom = e.p.find('.stream-element');
|
||||||
|
zoomGlass = e.p.find(".zoomGlass");
|
||||||
|
var zoomFrame = function(){
|
||||||
|
var magnify_offset = e.p.find('.stream-block')[streamBlockOperator]();
|
||||||
|
var mx = e.pageX - magnify_offset.left;
|
||||||
|
var my = e.pageY - magnify_offset.top;
|
||||||
|
var rx = Math.round(mx/targetForZoom.width()*e.width - zoomGlass.width()/2)*-1;
|
||||||
|
var ry = Math.round(my/targetForZoom.height()*e.height - zoomGlass.height()/2)*-1;
|
||||||
|
var px = mx - zoomGlass.width()/2;
|
||||||
|
var py = my - zoomGlass.height()/2;
|
||||||
|
zoomGlass[zoomGlassAnimate]({left: px, top: py}).find(magnifiedElement)[zoomGlassAnimate]({left: rx, top: ry});
|
||||||
|
}
|
||||||
|
if(!e.height||!e.width||zoomGlass.length===0){
|
||||||
|
$.ccio.snapshot(e,function(url,buffer,width,height){
|
||||||
|
e.width = width * e.mon.zoomAmount;
|
||||||
|
e.height = height * e.mon.zoomAmount;
|
||||||
|
e.p.attr('realWidth',width)
|
||||||
|
e.p.attr('realHeight',height)
|
||||||
|
zoomGlass = e.p.find(".zoomGlass");
|
||||||
|
if(zoomGlass.length===0){
|
||||||
|
if(e.useCanvas === true){
|
||||||
|
e.p.append('<div class="zoomGlass"><canvas class="blenderCanvas"></canvas></div>');
|
||||||
|
}else{
|
||||||
|
e.p.append('<div class="zoomGlass"><iframe src="'+e.auth+'/embed/'+e.ke+'/'+e.mid+'/fullscreen|jquery|relative"/><div class="hoverShade"></div></div>');
|
||||||
|
}
|
||||||
|
zoomGlass = e.p.find(".zoomGlass");
|
||||||
|
}
|
||||||
|
zoomGlass.find(magnifiedElement).css({height:e.height,width:e.width});
|
||||||
|
zoomFrame()
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
zoomGlass.find(magnifiedElement).css({height:e.height,width:e.width});
|
||||||
|
zoomFrame()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.ccio.destroyStream = function(d,user,killElement){
|
||||||
|
if(d.mid && !d.id)d.id = d.mid
|
||||||
|
console.log(d.ke+d.id+user.auth_token)
|
||||||
|
console.log($.ccio.mon[d.ke+d.id+user.auth_token])
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token]){
|
||||||
|
console.log('destroy')
|
||||||
|
$.ccio.init('closeVideo',{mid:d.id,ke:d.ke},user);
|
||||||
|
$.ccio.init('jpegModeStop',{mid:d.id,ke:d.ke},user);
|
||||||
|
$.ccio.init('clearTimers',d,user)
|
||||||
|
clearInterval($.ccio.mon[d.ke+d.id+user.auth_token].signal);delete($.ccio.mon[d.ke+d.id+user.auth_token].signal);
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].watch = 0;
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].PoseidonErrorCount = 0
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].hls){$.ccio.mon[d.ke+d.id+user.auth_token].hls.destroy()}
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].Poseidon){$.ccio.mon[d.ke+d.id+user.auth_token].Poseidon.stop()}
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].Base64){$.ccio.mon[d.ke+d.id+user.auth_token].Base64.disconnect()}
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].h265Socket){$.ccio.mon[d.ke+d.id+user.auth_token].h265Socket.disconnect()}
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].h265Player){$.ccio.mon[d.ke+d.id+user.auth_token].h265Player.stop()}
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].dash){$.ccio.mon[d.ke+d.id+user.auth_token].dash.reset()}
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].h265HttpStream && $.ccio.mon[d.ke+d.id+user.auth_token].abort){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].h265HttpStream.abort()
|
||||||
|
}
|
||||||
|
if(killElement){
|
||||||
|
$.grid.data().removeWidget($('#monitor_live_'+d.id+user.auth_token))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
$.ccio={
|
||||||
|
fr:$('#files_recent'),
|
||||||
|
mon:{},
|
||||||
|
useUTC: <%- config.useUTC || false %>,
|
||||||
|
definitions: <%-JSON.stringify(define)%>,
|
||||||
|
libURL: '<%-window.libURL%>'
|
||||||
|
};
|
||||||
|
<% if(config.DropboxAppKey){ %>
|
||||||
|
$.ccio.DropboxAppKey = '<%-window.DropboxAppKey%>'
|
||||||
|
<% } %>
|
||||||
|
$.ccio.HWAccelChoices = [
|
||||||
|
<% if(config.availableHWAccels) {
|
||||||
|
var methods = {
|
||||||
|
auto: {label:lang['Auto'],value:'auto'},
|
||||||
|
drm: {label:lang['drm'],value:'drm'},
|
||||||
|
cuvid: {label:lang['cuvid'],value:'cuvid'},
|
||||||
|
vaapi: {label:lang['vaapi'],value:'vaapi'},
|
||||||
|
qsv: {label:lang['qsv'],value:'qsv'},
|
||||||
|
vdpau: {label:lang['vdpau'],value:'vdpau'},
|
||||||
|
dxva2: {label:lang['dxva2'],value:'dxva2'},
|
||||||
|
vdpau: {label:lang['vdpau'],value:'vdpau'},
|
||||||
|
videotoolbox: {label:lang['videotoolbox'],value:'videotoolbox'}
|
||||||
|
}
|
||||||
|
config.availableHWAccels.forEach(function(availibleMethod){
|
||||||
|
if(methods[availibleMethod]){ %>
|
||||||
|
<%- JSON.stringify(methods[availibleMethod]) %>,
|
||||||
|
<% }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
]
|
||||||
|
try{
|
||||||
|
$user.details = JSON.parse($user.details)
|
||||||
|
}catch(err){
|
||||||
|
|
||||||
|
}
|
||||||
|
if(!$user.details.lang||$user.details.lang==''){
|
||||||
|
$user.details.lang="<%-config.language%>"
|
||||||
|
}
|
||||||
|
switch($user.details.lang){
|
||||||
|
case'ar'://Arabic
|
||||||
|
case'bn'://Bengali
|
||||||
|
$('body').addClass('right-to-left')
|
||||||
|
$('.mdl-menu__item').each(function(n,v){
|
||||||
|
v=$(v).find('i')
|
||||||
|
v.appendTo(v.parent())
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
window.chartColors = {
|
||||||
|
red: 'rgb(255, 99, 132)',
|
||||||
|
orange: 'rgb(255, 159, 64)',
|
||||||
|
yellow: 'rgb(255, 205, 86)',
|
||||||
|
green: 'rgb(75, 192, 192)',
|
||||||
|
blue: 'rgb(54, 162, 235)',
|
||||||
|
purple: 'rgb(153, 102, 255)',
|
||||||
|
grey: 'rgb(201, 203, 207)'
|
||||||
|
};
|
||||||
|
//global form functions
|
||||||
|
$.ccio.form={};
|
||||||
|
$.ccio.form.details=function(e){
|
||||||
|
e.ar={},e.f=$(this).parents('form');
|
||||||
|
$.each(e.f.find('[detail]'),function(n,v){
|
||||||
|
v=$(v);e.ar[v.attr('detail')]=v.val();
|
||||||
|
});
|
||||||
|
e.f.find('[name="details"]').val(JSON.stringify(e.ar));
|
||||||
|
};
|
||||||
|
$(document).ready(function(e){
|
||||||
|
|
||||||
|
//check switch UI
|
||||||
|
e.o=$.ccio.op().switches;
|
||||||
|
if(e.o){
|
||||||
|
$.each(e.o,function(n,v){
|
||||||
|
$('[system="switch"][switch="'+n+'"]').each(function(m,b){
|
||||||
|
b=$(b);
|
||||||
|
switch(b.attr('type')){
|
||||||
|
case'text':
|
||||||
|
if(v===1){
|
||||||
|
b.addClass('text-success')
|
||||||
|
}else{
|
||||||
|
b.removeClass('text-success')
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
$.ccio.op('switches',{notifyHide:0})
|
||||||
|
}
|
||||||
|
//set class toggle preferences
|
||||||
|
e.o=$.ccio.op().class_toggle;
|
||||||
|
if(e.o){
|
||||||
|
$.each(e.o,function(n,v){
|
||||||
|
if(v[1]===1){
|
||||||
|
$(n).addClass(v[0])
|
||||||
|
}else{
|
||||||
|
$(n).removeClass(v[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//set dropdown toggle preferences
|
||||||
|
e.o = $.ccio.op().dropdown_toggle
|
||||||
|
if(e.o){
|
||||||
|
$.each(e.o,function(n,v){
|
||||||
|
$('[dropdown_toggle="'+n+'"]').val(v).change()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//set localStorage input values
|
||||||
|
e.o = $.ccio.op()
|
||||||
|
if(e.o){
|
||||||
|
$.each(e.o,function(n,v){
|
||||||
|
if(typeof v==='string'){
|
||||||
|
var el = $('[localStorage="'+n+'"]')
|
||||||
|
if(el.is(':checkbox') === false){
|
||||||
|
el.val(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
document.addEventListener("fullscreenchange", onFullScreenChange, false);
|
||||||
|
document.addEventListener("webkitfullscreenchange", onFullScreenChange, false);
|
||||||
|
document.addEventListener("mozfullscreenchange", onFullScreenChange, false);
|
||||||
|
function onFullScreenChange() {
|
||||||
|
var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement;
|
||||||
|
if(!fullscreenElement){
|
||||||
|
$('.fullscreen').removeClass('fullscreen')
|
||||||
|
setTimeout(function(){
|
||||||
|
$('canvas.stream-element').resize();
|
||||||
|
},2000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,61 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//filters window
|
||||||
|
if(!$user.details.filters)$user.details.filters={};
|
||||||
|
$.fI={e:$('#filters')};$.fI.f=$.fI.e.find('form');
|
||||||
|
$.fI.md=$.fI.f.find('[detail]');
|
||||||
|
$.ccio.init('filters');
|
||||||
|
$.ccio.tm('filters-where');
|
||||||
|
$.fI.e.on('click','.where .add',function(e){
|
||||||
|
$.ccio.tm('filters-where');
|
||||||
|
})
|
||||||
|
$.fI.e.on('click','.where .remove',function(e){
|
||||||
|
e.e=$('#filters_where .row');
|
||||||
|
if(e.e.length>1){
|
||||||
|
e.e.last().remove();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$('#saved_filters').change(function(e){
|
||||||
|
e.e=$(this),e.id=e.e.val();
|
||||||
|
$('#filters_where').empty()
|
||||||
|
if(e.id&&e.id!==''){
|
||||||
|
e.name=$user.details.filters[e.id].name;
|
||||||
|
$.each($user.details.filters[e.id].where,function(n,v){
|
||||||
|
$.ccio.tm('filters-where',v)
|
||||||
|
});
|
||||||
|
$.each($user.details.filters[e.id],function(n,v){
|
||||||
|
if(n==='where'){return}
|
||||||
|
$.fI.f.find('[name="'+n+'"]').val(v);
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
e.name=lang['Add New'];
|
||||||
|
$.fI.f.find('[name="id"]').val($.ccio.gid(5));
|
||||||
|
$.ccio.tm('filters-where');
|
||||||
|
}
|
||||||
|
$.fI.e.find('.filter_name').text(e.name)
|
||||||
|
}).change()
|
||||||
|
$.fI.f.find('.delete').click(function(e){
|
||||||
|
e.s=$.fI.f.serializeObject();
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text(lang['Delete Filter']);
|
||||||
|
e.html=lang.confirmDeleteFilter;
|
||||||
|
$.confirm.body.html(e.html);
|
||||||
|
$.confirm.click({title:lang['Delete Filter'],class:'btn-danger'},function(){
|
||||||
|
$.ccio.cx({f:'settings',ff:'filters',fff:'delete',form:e.s})
|
||||||
|
});
|
||||||
|
})
|
||||||
|
$.fI.f.submit(function(e){
|
||||||
|
e.preventDefault();e.e=$(this),e.s=e.e.serializeObject();
|
||||||
|
e.er=[];
|
||||||
|
$.each(e.s,function(n,v){e.s[n]=v.trim()})
|
||||||
|
e.s.where=[];
|
||||||
|
e.e.find('.where-row').each(function(n,v){
|
||||||
|
n={};
|
||||||
|
$(v).find('[where]').each(function(m,b){
|
||||||
|
b=$(b);
|
||||||
|
n[b.attr('where')]=b.val().trim();
|
||||||
|
})
|
||||||
|
e.s.where.push(n)
|
||||||
|
})
|
||||||
|
$.ccio.cx({f:'settings',ff:'filters',fff:'save',form:e.s})
|
||||||
|
});
|
||||||
|
})
|
|
@ -0,0 +1,143 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//detector filters window
|
||||||
|
$.detectorFilters={e:$('#detector_filter')};
|
||||||
|
$.detectorFilters.f=$.detectorFilters.e.find('form');
|
||||||
|
$.detectorFilters.md=$.detectorFilters.f.find('[detail]');
|
||||||
|
$.detectorFilters.getSelected = function(){
|
||||||
|
return $('#detector_filters').val()
|
||||||
|
}
|
||||||
|
$.detectorFilters.drawOptions = function(){
|
||||||
|
var dFilters = $.detectorFilters.getCurrent()
|
||||||
|
$('#detector_filters optgroup').empty()
|
||||||
|
$.each(dFilters,function(n,dFilter){
|
||||||
|
$.ccio.tm('option',{auth_token:$user.auth_token,id:dFilter.id,name:dFilter.filter_name},'#detector_filters optgroup')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$.detectorFilters.getCurrent = function(){
|
||||||
|
try{
|
||||||
|
return JSON.parse($.aM.e.find('[detail="detector_filters"]').val())
|
||||||
|
}catch(err){
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.detectorFilters.save = function(){
|
||||||
|
var currentVals = $.detectorFilters.getCurrent()
|
||||||
|
currentVals[$.detectorFilters.lastSave.id] = $.detectorFilters.lastSave
|
||||||
|
$.aM.e.find('[detail="detector_filters"]').val(JSON.stringify(currentVals)).change()
|
||||||
|
}
|
||||||
|
$.ccio.tm('detector-filters-where');
|
||||||
|
$.detectorFilters.e.on('change','[where="p1"]',function(e){
|
||||||
|
var el = $(this)
|
||||||
|
var p1v = el.val()
|
||||||
|
var parent = el.parents('.row')
|
||||||
|
var p3 = parent.find('[where="p3"]')
|
||||||
|
var options = []
|
||||||
|
switch(p1v){
|
||||||
|
case'time':
|
||||||
|
options = [
|
||||||
|
'00:00:00'
|
||||||
|
]
|
||||||
|
break;
|
||||||
|
case'reason':
|
||||||
|
options = [
|
||||||
|
'licensePlate',
|
||||||
|
'object',
|
||||||
|
'motion',
|
||||||
|
]
|
||||||
|
break;
|
||||||
|
case'plug':
|
||||||
|
options = [
|
||||||
|
'PythonYolo',
|
||||||
|
'OpenCV',
|
||||||
|
'built-in',
|
||||||
|
]
|
||||||
|
break;
|
||||||
|
case'tag':
|
||||||
|
options = [
|
||||||
|
'car',
|
||||||
|
'tree',
|
||||||
|
'pottedplant',
|
||||||
|
]
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var msg = 'Value'
|
||||||
|
if(options.length > 0){
|
||||||
|
msg = 'Example : '+options.join(', ')
|
||||||
|
}
|
||||||
|
p3.attr('placeholder',msg)
|
||||||
|
})
|
||||||
|
$.detectorFilters.e.on('shown.bs.modal',function(e){
|
||||||
|
$.detectorFilters.drawOptions()
|
||||||
|
})
|
||||||
|
$.detectorFilters.e.on('click','.where .add',function(e){
|
||||||
|
$.ccio.tm('detector-filters-where');
|
||||||
|
})
|
||||||
|
$.detectorFilters.e.on('click','.where .remove',function(e){
|
||||||
|
e.e=$('#detector_filters_where .row');
|
||||||
|
if(e.e.length>1){
|
||||||
|
e.e.last().remove();
|
||||||
|
$('#detector_filters_where .row:last [where="p4"]').prop('disabled',true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.detectorFilters.f.find('.delete').click(function(e){
|
||||||
|
var currentVals = $.detectorFilters.getCurrent()
|
||||||
|
var newObject = {}
|
||||||
|
var deleteId = $.detectorFilters.getSelected()
|
||||||
|
$.each(currentVals,function(id,obj){
|
||||||
|
if(id === deleteId)return false;
|
||||||
|
newObject[id] = obj
|
||||||
|
})
|
||||||
|
$.aM.e.find('[detail="detector_filters"]').val(JSON.stringify(newObject)).change()
|
||||||
|
$.detectorFilters.drawOptions()
|
||||||
|
})
|
||||||
|
$('#detector_filters').change(function(){
|
||||||
|
e = {}
|
||||||
|
e.e=$(this),e.id=e.e.val();
|
||||||
|
$('#detector_filters_where').empty()
|
||||||
|
if(e.id&&e.id!==''){
|
||||||
|
var currentFilter = $.detectorFilters.getCurrent()[e.id]
|
||||||
|
e.name=currentFilter.name;
|
||||||
|
$.each(currentFilter.where,function(n,v){
|
||||||
|
$.ccio.tm('detector-filters-where',v)
|
||||||
|
});
|
||||||
|
$.each(currentFilter.actions,function(action,val){
|
||||||
|
$.detectorFilters.e.find('[actions="'+action+'"]').val(val)
|
||||||
|
});
|
||||||
|
$.each(currentFilter,function(n,v){
|
||||||
|
if(n==='where'){return}
|
||||||
|
$.detectorFilters.f.find('[name="'+n+'"]').val(v);
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
e.name=lang['Add New'];
|
||||||
|
$.detectorFilters.f.find('[name="id"]').val($.ccio.gid(5));
|
||||||
|
$.ccio.tm('detector-filters-where');
|
||||||
|
}
|
||||||
|
$.detectorFilters.e.find('.filter_name').text(e.name)
|
||||||
|
}).change()
|
||||||
|
$.detectorFilters.f.submit(function(ee){
|
||||||
|
ee.preventDefault()
|
||||||
|
e = {}
|
||||||
|
e.e=$(this),e.s=e.e.serializeObject();
|
||||||
|
e.er=[];
|
||||||
|
$.each(e.s,function(n,v){e.s[n]=v.trim()})
|
||||||
|
//create conditions object (where)
|
||||||
|
e.s.where=[];
|
||||||
|
e.e.find('.where-row').each(function(n,v){
|
||||||
|
n={};
|
||||||
|
$(v).find('[where]').each(function(m,b){
|
||||||
|
b=$(b);
|
||||||
|
n[b.attr('where')]=b.val().trim();
|
||||||
|
})
|
||||||
|
e.s.where.push(n)
|
||||||
|
})
|
||||||
|
// create actions object (do)
|
||||||
|
e.s.actions={};
|
||||||
|
e.e.find('.actions-row').each(function(n,v){
|
||||||
|
b=$(v).find('[actions]');
|
||||||
|
e.s.actions[b.attr('actions')] = b.val()
|
||||||
|
})
|
||||||
|
$.detectorFilters.lastSave = e.s
|
||||||
|
$.detectorFilters.save()
|
||||||
|
$.detectorFilters.e.modal('hide')
|
||||||
|
});
|
||||||
|
})
|
|
@ -0,0 +1,915 @@
|
||||||
|
$.ccio.tm=function(x,d,z,user){
|
||||||
|
var tmp='';if(!d){d={}};
|
||||||
|
var k={}
|
||||||
|
if(d&&d.user){
|
||||||
|
user=d.user
|
||||||
|
}
|
||||||
|
if(!user){
|
||||||
|
user=$user
|
||||||
|
}
|
||||||
|
if(d.id&&!d.mid){d.mid=d.id;}
|
||||||
|
switch(x){
|
||||||
|
case 0://video
|
||||||
|
var url = $.ccio.init('videoUrlBuild',d)
|
||||||
|
href = 'href="'+url+'"'
|
||||||
|
// if(!d.filename){d.filename=$.ccio.init('tf',d.time)+'.'+d.ext;}
|
||||||
|
d.dlname=d.mid+'-'+d.filename;
|
||||||
|
d.startMoment=$.ccio.timeObject(d.time),
|
||||||
|
d.endMoment=$.ccio.timeObject(d.end),
|
||||||
|
d.hr=parseInt(d.startMoment.format('HH')),
|
||||||
|
d.per=parseInt(d.hr/24*100);
|
||||||
|
d.circle='<div title="at '+d.hr+' hours of '+d.startMoment.format('MMMM DD')+'" '+href+' video="launch" class="progress-circle progress-'+d.per+'"><span>'+d.hr+'</span></div>'
|
||||||
|
tmp+='<li class="video-item glM'+d.mid+user.auth_token+'" auth="'+user.auth_token+'" mid="'+d.mid+'" ke="'+d.ke+'" status="'+d.status+'" status="'+d.status+'" file="'+d.filename+'">'+d.circle+'<div><span title="'+d.endMoment.format()+'" class="livestamp"></span></div><div><div class="small"><b>'+lang.Start+'</b> : '+d.startMoment.format('h:mm:ss , MMMM Do YYYY')+'</div><div class="small"><b>'+lang.End+'</b> : '+d.endMoment.format('h:mm:ss , MMMM Do YYYY')+'</div></div><div><span class="pull-right">'+(parseInt(d.size)/1000000).toFixed(2)+'mb</span><div class="controls btn-group"><a class="btn btn-sm btn-primary" video="launch" '+href+'><i class="fa fa-play-circle"></i></a> <a download="'+d.dlname+'" '+href+' class="btn btn-sm btn-default"><i class="fa fa-download"></i></a>'
|
||||||
|
if($.ccio.DropboxAppKey){ tmp+='<a video="download" host="dropbox" download="'+d.dlname+'" '+href+' class="btn btn-sm btn-default"><i class="fa fa-dropbox"></i></a>' }
|
||||||
|
tmp+='<a title="'+lang['Delete Video']+'" video="delete" href="'+$.ccio.init('videoHrefToDelete',url)+'" class="btn btn-sm btn-danger permission_video_delete"><i class="fa fa-trash"></i></a></div></div></li>';
|
||||||
|
$(z).each(function(n,v){
|
||||||
|
v=$(v);
|
||||||
|
if(v.find('.video-item').length>10){v.find('.video-item:last').remove()}
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 1://monitor icon
|
||||||
|
d.src=placeholder.getData(placeholder.plcimg({bgcolor:'#b57d00',text:'...'}));
|
||||||
|
tmp+='<div auth="'+user.auth_token+'" mid="'+d.mid+'" ke="'+d.ke+'" title="'+d.mid+' : '+d.name+'" class="monitor_block glM'+d.mid+user.auth_token+' col-md-4"><img monitor="watch" class="snapshot" src="'+d.src+'"><div class="box"><div class="title monitor_name truncate">'+d.name+'</div><div class="list-data"><div class="monitor_mid">'+d.mid+'</div><div><b>'+lang['Save as']+' :</b> <span class="monitor_ext">'+d.ext+'</span></div><div><b>Status :</b> <span class="monitor_status">'+d.status+'</span></div></div><div class="icons text-center">'
|
||||||
|
tmp+='<div class="btn-group btn-group-xs">'
|
||||||
|
var buttons = {
|
||||||
|
"Pop": {
|
||||||
|
"label": "Pop",
|
||||||
|
"attr": "monitor=\"pop\"",
|
||||||
|
"class": "default",
|
||||||
|
"icon": "external-link"
|
||||||
|
},
|
||||||
|
"Power Viewer": {
|
||||||
|
"label": "Power Viewer",
|
||||||
|
"attr": "monitor=\"powerview\"",
|
||||||
|
"class": "default",
|
||||||
|
"icon": "map-marker"
|
||||||
|
},
|
||||||
|
"Videos List": {
|
||||||
|
"label": "Videos List",
|
||||||
|
"attr": "monitor=\"videos_table\"",
|
||||||
|
"class": "default",
|
||||||
|
"icon": "film"
|
||||||
|
},
|
||||||
|
"Monitor Settings": {
|
||||||
|
"label": "Monitor Settings",
|
||||||
|
"attr": "monitor=\"edit\"",
|
||||||
|
"class": "default",
|
||||||
|
"icon": "wrench"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!$.ccio.permissionCheck('video_view',d.mid)){
|
||||||
|
delete(buttons["Videos List"])
|
||||||
|
delete(buttons["Power Viewer"])
|
||||||
|
}
|
||||||
|
if(!$.ccio.permissionCheck('monitor_edit',d.mid)){
|
||||||
|
delete(buttons["Monitor Settings"])
|
||||||
|
}
|
||||||
|
$.each(buttons,function(n,v){
|
||||||
|
tmp+='<a class="btn btn-'+v.class+'" '+v.attr+' title="'+v.label+'"><i class="fa fa-'+v.icon+'"></i></a>'
|
||||||
|
})
|
||||||
|
tmp+='</div>\
|
||||||
|
</div></div></div>';
|
||||||
|
delete(d.src);
|
||||||
|
break;
|
||||||
|
case 2://monitor stream
|
||||||
|
try{k.d=JSON.parse(d.details);}catch(er){k.d=d.details;}
|
||||||
|
k.mode=$.ccio.init('humanReadMode',d.mode);
|
||||||
|
var dataTarget = '.monitor_item[mid=\''+d.mid+'\'][ke=\''+d.ke+'\'][auth=\''+user.auth_token+'\']';
|
||||||
|
tmp+='<div id="monitor_live_'+d.mid+user.auth_token+'" auth="'+user.auth_token+'" mid="'+d.mid+'" ke="'+d.ke+'" mode="'+k.mode+'" class="grid-stack-item monitor_item glM'+d.mid+user.auth_token+'"><div class="grid-stack-item-content">';
|
||||||
|
tmp+='<div class="stream-block no-padding mdl-card__media mdl-color-text--grey-50">';
|
||||||
|
tmp+='<div class="stream-objects"></div>';
|
||||||
|
tmp+='<div class="stream-hud">'
|
||||||
|
tmp+='<div class="camera_cpu_usage"><div class="progress"><div class="progress-bar progress-bar-danger" role="progressbar"><span></span></div></div></div>';
|
||||||
|
tmp+='<div class="lamp" title="'+k.mode+'"><i class="fa fa-eercast"></i></div><div class="controls"><span title="'+lang['Currently viewing']+'" class="label label-default"><span class="viewers"></span></span> <a class="btn-xs btn-danger btn" monitor="mode" mode="record"><i class="fa fa-circle"></i> '+lang['Start Recording']+'</a> <a class="btn-xs btn-primary btn" monitor="mode" mode="start"><i class="fa fa-eye"></i> '+lang['Set to Watch Only']+'</a></div></div></div></div>'
|
||||||
|
tmp+='<div class="mdl-card__supporting-text text-center">';
|
||||||
|
tmp+='<div class="indifference detector-fade"><div class="progress"><div class="progress-bar progress-bar-danger" role="progressbar"><span></span></div></div></div>';
|
||||||
|
tmp+='<div class="monitor_details">';
|
||||||
|
tmp+='<div><span class="monitor_name">'+d.name+'</span><span class="monitor_not_record_copy">, '+lang['Recording FPS']+' : <span class="monitor_fps">'+d.fps+'</span></span></div>';
|
||||||
|
tmp+='</div>';
|
||||||
|
tmp+='<div class="btn-group btn-group-sm">'//start of btn list
|
||||||
|
var buttons = {
|
||||||
|
"Snapshot": {
|
||||||
|
"label": "Snapshot",
|
||||||
|
"attr": "monitor=\"snapshot\"",
|
||||||
|
"class": "primary",
|
||||||
|
"icon": "camera"
|
||||||
|
},
|
||||||
|
"Show Logs": {
|
||||||
|
"label": "Show Logs",
|
||||||
|
"attr": "monitor=\"show_data\"",
|
||||||
|
"class": "warning",
|
||||||
|
"icon": "exclamation-triangle"
|
||||||
|
},
|
||||||
|
"Control": {
|
||||||
|
"label": "Control",
|
||||||
|
"attr": "monitor=\"control_toggle\"",
|
||||||
|
"class": "default arrows",
|
||||||
|
"icon": "arrows"
|
||||||
|
},
|
||||||
|
"Status Indicator": {
|
||||||
|
"label": "Status Indicator",
|
||||||
|
"attr": "monitor=\"watch_on\"",
|
||||||
|
"class": "success signal",
|
||||||
|
"icon": "plug"
|
||||||
|
},
|
||||||
|
"Pop": {
|
||||||
|
"label": "Pop",
|
||||||
|
"attr": "monitor=\"pop\"",
|
||||||
|
"class": "default",
|
||||||
|
"icon": "external-link"
|
||||||
|
},
|
||||||
|
"Calendar": {
|
||||||
|
"label": "Calendar",
|
||||||
|
"attr": "monitor=\"calendar\"",
|
||||||
|
"class": "default ",
|
||||||
|
"icon": "calendar"
|
||||||
|
},
|
||||||
|
"Power Viewer": {
|
||||||
|
"label": "Power Viewer",
|
||||||
|
"attr": "monitor=\"powerview\"",
|
||||||
|
"class": "default",
|
||||||
|
"icon": "map-marker"
|
||||||
|
},
|
||||||
|
"Time-lapse": {
|
||||||
|
"label": "Time-lapse",
|
||||||
|
"attr": "monitor=\"timelapse\"",
|
||||||
|
"class": "default",
|
||||||
|
"icon": "angle-double-right"
|
||||||
|
},
|
||||||
|
"Video Grid": {
|
||||||
|
"label": "Video Grid",
|
||||||
|
"attr": "monitor=\"video_grid\"",
|
||||||
|
"class": "default",
|
||||||
|
"icon": "th"
|
||||||
|
},
|
||||||
|
"Videos List": {
|
||||||
|
"label": "Videos List",
|
||||||
|
"attr": "monitor=\"videos_table\"",
|
||||||
|
"class": "default",
|
||||||
|
"icon": "film"
|
||||||
|
},
|
||||||
|
"Monitor Settings": {
|
||||||
|
"label": "Monitor Settings",
|
||||||
|
"attr": "monitor=\"edit\"",
|
||||||
|
"class": "default",
|
||||||
|
"icon": "wrench"
|
||||||
|
},
|
||||||
|
"Fullscreen": {
|
||||||
|
"label": "Fullscreen",
|
||||||
|
"attr": "monitor=\"fullscreen\"",
|
||||||
|
"class": "default",
|
||||||
|
"icon": "arrows-alt"
|
||||||
|
},
|
||||||
|
"Close": {
|
||||||
|
"label": "Close",
|
||||||
|
"attr": "monitor=\"watch_off\"",
|
||||||
|
"class": "danger",
|
||||||
|
"icon": "times"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!$.ccio.permissionCheck('video_view',d.mid)){
|
||||||
|
delete(buttons["Videos List"])
|
||||||
|
delete(buttons["Time-lapse"])
|
||||||
|
delete(buttons["Power Viewer"])
|
||||||
|
delete(buttons["Calendar"])
|
||||||
|
}
|
||||||
|
if(!$.ccio.permissionCheck('monitor_edit',d.mid)){
|
||||||
|
delete(buttons["Monitor Settings"])
|
||||||
|
}
|
||||||
|
$.each(buttons,function(n,v){
|
||||||
|
tmp+='<a class="btn btn-'+v.class+'" '+v.attr+' title="'+v.label+'"><i class="fa fa-'+v.icon+'"></i></a>'
|
||||||
|
})
|
||||||
|
tmp+='</div>';//end of btn list
|
||||||
|
tmp+='</div>';//.stream-block
|
||||||
|
tmp+='<div class="mdl-data_window pull-right">';
|
||||||
|
tmp+='<div>';
|
||||||
|
tmp+='<div class="data-menu col-md-6 no-padding videos_monitor_list glM'+d.mid+user.auth_token+' scrollable"><ul></ul></div>';
|
||||||
|
tmp+='<div class="data-menu col-md-6 no-padding logs scrollable"></div>';
|
||||||
|
tmp+='</div>';
|
||||||
|
tmp+='</div>';//.mdl-data_window
|
||||||
|
tmp+='</div>';//.grid-stack-content
|
||||||
|
tmp+='</div>';//#monitor_live_...
|
||||||
|
break;
|
||||||
|
case 3://api key row
|
||||||
|
tmp+='<tr api_key="'+d.code+'"><td class="code">'+d.code+'</td><td class="ip">'+d.ip+'</td><td class="time">'+d.time+'</td><td class="text-right"><a class="delete btn btn-xs btn-danger"> <i class="fa fa-trash"></i> </a></td></tr>';
|
||||||
|
break;
|
||||||
|
case 4://log row, draw to global and monitor
|
||||||
|
if(!d.time){d.time=$.ccio.init('t')}
|
||||||
|
tmp+='<li class="log-item">'
|
||||||
|
tmp+='<span>'
|
||||||
|
tmp+='<div>'+d.ke+' : <b>'+d.mid+'</b></div>'
|
||||||
|
tmp+='<span>'+d.log.type+'</span> '
|
||||||
|
tmp+='<b class="time livestamp" title="'+d.time+'"></b>'
|
||||||
|
tmp+='</span>'
|
||||||
|
tmp+='<div class="message">'
|
||||||
|
tmp+=$.ccio.init('jsontoblock',d.log.msg);
|
||||||
|
tmp+='</div>'
|
||||||
|
tmp+='</li>';
|
||||||
|
$(z).each(function(n,v){
|
||||||
|
v=$(v);
|
||||||
|
if(v.find('.log-item').length>10){v.find('.log-item:last').remove()}
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 6://notification row
|
||||||
|
if(!d.time){d.time=$.ccio.init('t')}
|
||||||
|
if(!d.note.class){d.note.class=''}
|
||||||
|
tmp+='<li class="note-item '+d.note.class+'" ke="'+d.ke+'" auth="'+user.auth_token+'" mid="'+d.id+'">'
|
||||||
|
tmp+='<span>'
|
||||||
|
tmp+='<div>'+d.ke+' : <b>'+d.id+'</b></div>'
|
||||||
|
tmp+='<span>'+d.note.type+'</span> '
|
||||||
|
tmp+='<b class="time livestamp" title="'+d.time+'"></b>'
|
||||||
|
tmp+='</span>'
|
||||||
|
tmp+='<div class="message">'
|
||||||
|
tmp+=d.note.msg
|
||||||
|
tmp+='</div>'
|
||||||
|
tmp+='</li>';
|
||||||
|
break;
|
||||||
|
case'option':
|
||||||
|
var selected = ''
|
||||||
|
if(d.selected === true){selected = ' selected'}
|
||||||
|
tmp+='<option auth="'+user.auth_token+'"'+selected+' value="'+d.id+'">'+d.name+'</option>'
|
||||||
|
break;
|
||||||
|
case'stream-element':
|
||||||
|
try{k.d=JSON.parse(d.details);}catch(er){k.d=d.details}
|
||||||
|
if($.ccio.mon[d.ke+d.mid+user.auth_token]&&$.ccio.mon[d.ke+d.mid+user.auth_token].previousStreamType===k.d.stream_type){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
k.e=$('#monitor_live_'+d.mid+user.auth_token+' .stream-block');
|
||||||
|
k.e.find('.stream-element').remove();
|
||||||
|
if($.ccio.op().jpeg_on===true){
|
||||||
|
tmp+='<img class="stream-element">';
|
||||||
|
}else{
|
||||||
|
switch(k.d.stream_type){
|
||||||
|
case'hls':case'flv':case'mp4':
|
||||||
|
tmp+='<video class="stream-element" autoplay></video>';
|
||||||
|
break;
|
||||||
|
case'mjpeg':
|
||||||
|
tmp+='<iframe class="stream-element"></iframe>';
|
||||||
|
break;
|
||||||
|
case'jpeg':
|
||||||
|
tmp+='<img class="stream-element">';
|
||||||
|
break;
|
||||||
|
default://base64//h265
|
||||||
|
tmp+='<canvas class="stream-element"></canvas>';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k.e.append(tmp).find('.stream-element').resize();
|
||||||
|
if($.ccio.op().switches.monitorMuteAudio === 1){
|
||||||
|
k.e.find('video').each(function(n,el){
|
||||||
|
el.muted = "muted"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'user-row':
|
||||||
|
d.e=$('.user-row[uid="'+d.uid+'"][ke="'+d.ke+'"]')
|
||||||
|
if(d.e.length===0){
|
||||||
|
tmp+='<li class="user-row" uid="'+d.uid+'" ke="'+d.ke+'">';
|
||||||
|
tmp+='<span><div><span class="mail">'+d.mail+'</span> : <b class="uid">'+d.uid+'</b></div><span>Logged in</span> <b class="time livestamped" title="'+d.logged_in_at+'"></b></span>';
|
||||||
|
tmp+='</li>';
|
||||||
|
}else{
|
||||||
|
d.e.find('.mail').text(d.mail)
|
||||||
|
d.e.find('.time').livestamp('destroy').toggleClass('livestamped livestamp').text(d.logged_in_at)
|
||||||
|
}
|
||||||
|
$.ccio.init('ls')
|
||||||
|
break;
|
||||||
|
case'detector-filters-where':
|
||||||
|
if(!d)d={};
|
||||||
|
d.id=$('#filters_where .row').length;
|
||||||
|
if(!d.p1){d.p1='indifference'}
|
||||||
|
if(!d.p2){d.p2='='}
|
||||||
|
if(!d.p3){d.p3=''}
|
||||||
|
if(!d.p4){d.p4='&&'}
|
||||||
|
tmp+='<div class="row where-row">'
|
||||||
|
tmp+=' <div class="form-group col-md-3">'
|
||||||
|
tmp+=' <label>'
|
||||||
|
tmp+=' <select class="form-control" where="p1">'
|
||||||
|
tmp+=' <option value="indifference" selected>'+lang['Indifference']+'</option>'
|
||||||
|
tmp+=' <option value="name">'+lang['Region Name']+'</option>'
|
||||||
|
tmp+=' <option value="reason">'+lang['Reason']+'</option>'
|
||||||
|
tmp+=' <option value="time">'+lang['Time']+'</option>'
|
||||||
|
tmp+=' <option value="plug">'+lang['Detection Engine']+'</option>'
|
||||||
|
tmp+=' <optgroup label="Matrix">'
|
||||||
|
tmp+=' <option value="tag">'+lang['Object Tag']+'</option>'
|
||||||
|
tmp+=' <option value="confidence">'+lang['Confidence']+'</option>'
|
||||||
|
tmp+=' <option value="x">'+lang['X Point']+'</option>'
|
||||||
|
tmp+=' <option value="y">'+lang['Y Point']+'</option>'
|
||||||
|
tmp+=' <option value="height">'+lang['Height']+'</option>'
|
||||||
|
tmp+=' <option value="width">'+lang['Width']+'</option>'
|
||||||
|
tmp+=' </optgroup>'
|
||||||
|
tmp+=' </select>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group col-md-3">'
|
||||||
|
tmp+=' <label>'
|
||||||
|
tmp+=' <select class="form-control" where="p2">'
|
||||||
|
tmp+=' <option value="===" selected>'+lang['Equal to']+'</option>'
|
||||||
|
tmp+=' <option value="!==">'+lang['Not Equal to']+'</option>'
|
||||||
|
tmp+=' <option value="indexOf">'+lang['Contains']+'</option>'
|
||||||
|
tmp+=' <option value="!indexOf">'+lang['Does Not Contain']+'</option>'
|
||||||
|
tmp+=' <optgroup label="For Numbers">'
|
||||||
|
tmp+=' <option value=">=">'+lang['Greater Than or Equal to']+'</option>'
|
||||||
|
tmp+=' <option value=">">'+lang['Greater Than']+'</option>'
|
||||||
|
tmp+=' <option value="<">'+lang['Less Than']+'</option>'
|
||||||
|
tmp+=' <option value="<=">'+lang['Less Than or Equal to']+'</option>'
|
||||||
|
tmp+=' </optgroup>'
|
||||||
|
tmp+=' </select>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group col-md-3">'
|
||||||
|
tmp+=' <label>'
|
||||||
|
tmp+=' <input class="form-control" placeholder="Value" title="'+lang.Value+'" where="p3">'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group col-md-3">'
|
||||||
|
tmp+=' <label>'
|
||||||
|
tmp+=' <select class="form-control" where="p4">'
|
||||||
|
tmp+=' <option value="&&" selected>'+lang['AND']+'</option>'
|
||||||
|
tmp+=' <option value="||">'+lang['OR']+'</option>'
|
||||||
|
tmp+=' </select>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+='</div>'
|
||||||
|
break;
|
||||||
|
case'filters-where':
|
||||||
|
if(!d)d={};
|
||||||
|
d.id=$('#filters_where .row').length;
|
||||||
|
if(!d.p1){d.p1='mid'}
|
||||||
|
if(!d.p2){d.p2='='}
|
||||||
|
if(!d.p3){d.p3=''}
|
||||||
|
tmp+='<div class="row where-row">';
|
||||||
|
tmp+=' <div class="form-group col-md-4">';
|
||||||
|
tmp+=' <label>';
|
||||||
|
tmp+=' <select class="form-control" where="p1">';
|
||||||
|
tmp+=' <option value="mid" selected>'+lang['Monitor ID']+'</option>';
|
||||||
|
tmp+=' <option value="ext">'+lang['File Type']+'</option>';
|
||||||
|
tmp+=' <option value="time">'+lang['Start Time']+'</option>';
|
||||||
|
tmp+=' <option value="end">'+lang['End Time']+'</option>';
|
||||||
|
tmp+=' <option value="size">'+lang['Filesize']+'</option>';
|
||||||
|
tmp+=' <option value="status">'+lang['Video Status']+'</option>';
|
||||||
|
tmp+=' </select>';
|
||||||
|
tmp+=' </label>';
|
||||||
|
tmp+=' </div>';
|
||||||
|
tmp+=' <div class="form-group col-md-4">';
|
||||||
|
tmp+=' <label>';
|
||||||
|
tmp+=' <select class="form-control" where="p2">';
|
||||||
|
tmp+=' <option value="=" selected>'+lang['Equal to']+'</option>';
|
||||||
|
tmp+=' <option value="!=">'+lang['Not Equal to']+'</option>';
|
||||||
|
tmp+=' <option value=">=">'+lang['Greater Than or Equal to']+'</option>';
|
||||||
|
tmp+=' <option value=">">'+lang['Greater Than']+'</option>';
|
||||||
|
tmp+=' <option value="<">'+lang['Less Than']+'</option>';
|
||||||
|
tmp+=' <option value="<=">'+lang['Less Than or Equal to']+'</option>';
|
||||||
|
tmp+=' <option value="LIKE">'+lang['Like']+'</option>';
|
||||||
|
tmp+=' <option value="=~">'+lang['Matches']+'</option>';
|
||||||
|
tmp+=' <option value="!~">'+lang['Not Matches']+'</option>';
|
||||||
|
tmp+=' <option value="=[]">'+lang['In']+'</option>';
|
||||||
|
tmp+=' <option value="![]">'+lang['Not In']+'</option>';
|
||||||
|
tmp+=' </select>';
|
||||||
|
tmp+=' </label>';
|
||||||
|
tmp+=' </div>';
|
||||||
|
tmp+=' <div class="form-group col-md-4">';
|
||||||
|
tmp+=' <label>';
|
||||||
|
tmp+=' <input class="form-control" placeholder="Value" title="'+lang.Value+'" where="p3">';
|
||||||
|
tmp+=' </label>';
|
||||||
|
tmp+=' </div>';
|
||||||
|
tmp+='</div>';
|
||||||
|
break;
|
||||||
|
case 'link-set'://Link Shinobi - 1 set
|
||||||
|
if(!d.host){d.host=''}
|
||||||
|
if(!d.ke){d.ke=''}
|
||||||
|
if(!d.api){d.api=''}
|
||||||
|
if(!d.secure){d.secure="0"}
|
||||||
|
tmp+='<div class="linksGroup" links="'+d.host+'">'
|
||||||
|
tmp+='<h4 class="round-left">'+d.host+' <small>'+d.ke+'</small> <div class="pull-right"><a class="btn btn-danger btn-xs delete"><i class="fa fa-trash-o"></i></a></div></h4>'
|
||||||
|
tmp+='<div class="form-group"><label><div><span>'+lang.Host+'</span></div><div><input class="form-control" link="host" value="'+d.host+'"></div></label></div>'
|
||||||
|
tmp+='<div class="form-group"><label><div><span>'+lang['Group Key']+'</span></div><div><input class="form-control" link="ke" value="'+d.ke+'"></div></label></div>'
|
||||||
|
tmp+='<div class="form-group"><label><div><span>'+lang['API Key']+'</span></div><div><input class="form-control" link="api" value="'+d.api+'"></div></label></div>'
|
||||||
|
tmp+='<div class="form-group"><label><div><span>'+lang.Secure+' (HTTPS/WSS)</span></div><div><select class="form-control" link="secure"><option value="1">'+lang.Yes+'</option><option selected value="0">'+lang.No+'</option></select></div></label></div>'
|
||||||
|
tmp+='</div>';
|
||||||
|
break;
|
||||||
|
case 'form-group'://Input Map Selector
|
||||||
|
var fields = []
|
||||||
|
if(d.fields){
|
||||||
|
if(d.fields instanceof Object){
|
||||||
|
fields = [d]
|
||||||
|
}else{
|
||||||
|
fields = d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.each(fields,function(n,v){
|
||||||
|
var value,hidden
|
||||||
|
if(!v.attribute)v.attribute='';
|
||||||
|
if(!v.placeholder)v.placeholder='';
|
||||||
|
if(!v.class)v.class='';
|
||||||
|
if(!v.inputType)v.inputType='value';
|
||||||
|
if(v.hidden){hidden='style="display:none"'}else{hidden=''};
|
||||||
|
if(v.value){value='value=""'}else{value=''};
|
||||||
|
tmp+=' <div class="form-group '+v.class+'" '+hidden+'>'
|
||||||
|
tmp+=' <label><div><span>'+v.label+'</span></div>'
|
||||||
|
tmp+=' <div>'
|
||||||
|
switch(v.type){
|
||||||
|
case'text':
|
||||||
|
tmp+='<input class="form-control" '+v.inputType+'="'+v.name+'" placeholder="'+v.placeholder+'" "'+value+'" '+v.attribute+'>'
|
||||||
|
break;
|
||||||
|
case'selector':
|
||||||
|
tmp+='<select class="form-control" '+v.inputType+'="'+v.name+'" placeholder="'+v.placeholder+'" '+v.attribute+'>'
|
||||||
|
$.each(v.choices,function(m,b){
|
||||||
|
tmp+='<option value="'+b.value+'">'+b.label+'</option>'
|
||||||
|
})
|
||||||
|
tmp+='</select>'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'input-map-selector'://Input Map Selector
|
||||||
|
if(!d.map){d.map=''}
|
||||||
|
tmp+=' <div class="form-group map-row">'
|
||||||
|
tmp+=' <label><div><span>'+lang['Map']+'</span></div>'
|
||||||
|
tmp+=' <div>'
|
||||||
|
tmp+=' <div class="input-group input-group-sm">'
|
||||||
|
tmp+='<input class="form-control" map-input="map" value="'+d.map+'" placeholder="0">'
|
||||||
|
tmp+=' <div class="input-group-btn">'
|
||||||
|
tmp+=' <a class="btn btn-danger delete_map_row"> <i class="fa fa-trash-o"></i> </a>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
break;
|
||||||
|
case 'input-map'://Input Map Options
|
||||||
|
var tempID = $.ccio.gid();
|
||||||
|
if(!d.channel){
|
||||||
|
var numberOfChannelsDrawn = $('#monSectionInputMaps .input-map').length
|
||||||
|
d.channel=numberOfChannelsDrawn+1
|
||||||
|
}
|
||||||
|
var fields = [
|
||||||
|
// {
|
||||||
|
// name:'',
|
||||||
|
// class:'',
|
||||||
|
// placeholder:'',
|
||||||
|
// default:'',
|
||||||
|
// attribute:'',
|
||||||
|
// type:'text',
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
name:'type',
|
||||||
|
label:lang['Input Type'],
|
||||||
|
default:'h264',
|
||||||
|
attribute:'selector="h_i_'+tempID+'"',
|
||||||
|
type:'selector',
|
||||||
|
choices:[
|
||||||
|
{label:lang['H.264 / H.265 / H.265+'],value:'h264'},
|
||||||
|
{label:lang['JPEG'],value:'jpeg'},
|
||||||
|
{label:lang['MJPEG'],value:'mjpeg'},
|
||||||
|
{label:lang['HLS (.m3u8)'],value:'hls'},
|
||||||
|
{label:lang['MPEG-4 (.mp4 / .ts)'],value:'mp4'},
|
||||||
|
{label:lang['Local'],value:'local'},
|
||||||
|
{label:lang['Raw'],value:'raw'},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'fulladdress',
|
||||||
|
label:lang['Full URL Path'],
|
||||||
|
placeholder:'Example : rtsp://admin:password@123.123.123.123/stream/1',
|
||||||
|
type:'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'sfps',
|
||||||
|
label:lang['Monitor Capture Rate'],
|
||||||
|
placeholder:'',
|
||||||
|
type:'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'aduration',
|
||||||
|
label:lang['Analyzation Duration'],
|
||||||
|
placeholder:'Example : 1000000',
|
||||||
|
type:'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'probesize',
|
||||||
|
label:lang['Probe Size'],
|
||||||
|
placeholder:'Example : 1000000',
|
||||||
|
type:'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'stream_loop',
|
||||||
|
label:lang['Loop Stream'],
|
||||||
|
class:'h_i_'+tempID+'_input h_i_'+tempID+'_mp4 h_i_'+tempID+'_raw',
|
||||||
|
hidden:true,
|
||||||
|
default:'0',
|
||||||
|
type:'selector',
|
||||||
|
choices:[
|
||||||
|
{label:'No',value:'0'},
|
||||||
|
{label:'Yes',value:'1'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'rtsp_transport',
|
||||||
|
label:lang['RTSP Transport'],
|
||||||
|
class:'h_i_'+tempID+'_input h_i_'+tempID+'_h264',
|
||||||
|
default:'0',
|
||||||
|
type:'selector',
|
||||||
|
choices:[
|
||||||
|
{label:'Auto',value:''},
|
||||||
|
{label:'TCP',value:'tcp'},
|
||||||
|
{label:'UDP',value:'udp'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'accelerator',
|
||||||
|
label:lang['Accelerator'],
|
||||||
|
attribute:'selector="h_accel_'+tempID+'"',
|
||||||
|
default:'0',
|
||||||
|
type:'selector',
|
||||||
|
choices:[
|
||||||
|
{label:'No',value:'0'},
|
||||||
|
{label:'Yes',value:'1'},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'hwaccel',
|
||||||
|
label:lang['hwaccel'],
|
||||||
|
class:'h_accel_'+tempID+'_input h_accel_'+tempID+'_1',
|
||||||
|
hidden:true,
|
||||||
|
default:'',
|
||||||
|
type:'selector',
|
||||||
|
choices: $.ccio.HWAccelChoices
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'hwaccel_vcodec',
|
||||||
|
label:lang['hwaccel_vcodec'],
|
||||||
|
class:'h_accel_'+tempID+'_input h_accel_'+tempID+'_1',
|
||||||
|
hidden:true,
|
||||||
|
default:'auto',
|
||||||
|
type:'selector',
|
||||||
|
choices:[
|
||||||
|
{label:lang['Auto'],value:'auto'},
|
||||||
|
{label:lang['h264_cuvid'],value:'h264_cuvid',group:'NVIDIA'},
|
||||||
|
{label:lang['hevc_cuvid'],value:'hevc_cuvid',group:'NVIDIA'},
|
||||||
|
{label:lang['mjpeg_cuvid'],value:'mjpeg_cuvid',group:'NVIDIA'},
|
||||||
|
{label:lang['mpeg4_cuvid'],value:'mpeg4_cuvid',group:'NVIDIA'},
|
||||||
|
{label:lang['h264_qsv'],value:'h264_qsv',group:'Quick Sync Video'},
|
||||||
|
{label:lang['hevc_qsv'],value:'hevc_qsv',group:'Quick Sync Video'},
|
||||||
|
{label:lang['mpeg2_qsv'],value:'mpeg2_qsv',group:'Quick Sync Video'},
|
||||||
|
{label:lang['h264_mmal'],value:'h264_mmal',group:'Raspberry Pi'},
|
||||||
|
{label:lang['mpeg2_mmal'],value:'mpeg2_mmal',group:'Raspberry Pi'},
|
||||||
|
{label:lang['mpeg4_mmal'],value:'mpeg4_mmal',group:'Raspberry Pi'},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'hwaccel_device',
|
||||||
|
label:lang['hwaccel_device'],
|
||||||
|
class:'h_accel_'+tempID+'_input h_accel_'+tempID+'_1',
|
||||||
|
hidden:true,
|
||||||
|
placeholder:'Example : /dev/dri/video0',
|
||||||
|
type:'text',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
tmp+='<div class="form-group-group forestgreen input-map" section id="monSectionMap'+tempID+'">'
|
||||||
|
tmp+=' <h4>'+lang["Input"]+' <b>'+lang["Map"]+' : <span class="place">'+d.channel+'</span></b>'
|
||||||
|
tmp+=' <div class="pull-right"><a class="btn btn-danger btn-xs delete"><i class="fa fa-trash-o"></i></a></div>'
|
||||||
|
tmp+=' </h4>'
|
||||||
|
$.each(fields,function(n,v){
|
||||||
|
if(!v.attribute)v.attribute='';
|
||||||
|
if(!v.placeholder)v.placeholder='';
|
||||||
|
if(!v.class)v.class='';
|
||||||
|
if(v.hidden){v.hidden='style="display:none"'}else{v.hidden=''};
|
||||||
|
tmp+=' <div class="form-group '+v.class+'" '+v.hidden+'>'
|
||||||
|
tmp+=' <label><div><span>'+v.label+'</span></div>'
|
||||||
|
tmp+=' <div>'
|
||||||
|
switch(v.type){
|
||||||
|
case'text':
|
||||||
|
tmp+='<input class="form-control" map-detail="'+v.name+'" placeholder="'+v.placeholder+'" '+v.attribute+'>'
|
||||||
|
break;
|
||||||
|
case'selector':
|
||||||
|
tmp+='<select class="form-control" map-detail="'+v.name+'" placeholder="'+v.placeholder+'" '+v.attribute+'>'
|
||||||
|
$.each(v.choices,function(m,b){
|
||||||
|
tmp+='<option value="'+b.value+'">'+b.label+'</option>'
|
||||||
|
})
|
||||||
|
tmp+='</select>'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
})
|
||||||
|
tmp+='</div>'
|
||||||
|
break;
|
||||||
|
case 'stream-channel'://Stream Channel
|
||||||
|
var tempID = $.ccio.gid();
|
||||||
|
if(!d.channel){
|
||||||
|
var numberOfChannelsDrawn = $('#monSectionStreamChannels .stream-channel').length
|
||||||
|
d.channel=numberOfChannelsDrawn
|
||||||
|
}
|
||||||
|
tmp+='<div class="form-group-group blue stream-channel" section id="monSectionChannel'+tempID+'">'
|
||||||
|
tmp+=' <h4>'+lang["Stream Channel"]+' <span class="place">'+d.channel+'</span>'
|
||||||
|
tmp+=' <div class="pull-right"><a class="btn btn-danger btn-xs delete"><i class="fa fa-trash-o"></i></a></div>'
|
||||||
|
tmp+=' </h4>'
|
||||||
|
// tmp+=' <div class="form-group">'
|
||||||
|
// tmp+=' <label><div><span>'+lang["Input Selector"]+'</span></div>'
|
||||||
|
// tmp+=' <div><input class="form-control" channel-detail="stream_map" placeholder="0"></div>'
|
||||||
|
// tmp+=' </label>'
|
||||||
|
// tmp+=' </div>'
|
||||||
|
tmp+='<div class="form-group-group forestgreen" input-mapping="stream_channel-'+d.channel+'">'
|
||||||
|
tmp+=' <h4>'+lang['Input Feed']
|
||||||
|
tmp+=' <div class="pull-right">'
|
||||||
|
tmp+=' <a class="btn btn-success btn-xs add_map_row"><i class="fa fa-plus-square-o"></i></a>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </h4>'
|
||||||
|
tmp+=' <div class="choices"></div>'
|
||||||
|
tmp+='</div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Stream Type"]+'</span></div>'
|
||||||
|
tmp+=' <div><select class="form-control" channel-detail="stream_type" selector="h_st_channel_'+tempID+'" triggerChange="#monSectionChannel'+tempID+' [channel-detail=stream_vcodec]" triggerChangeIgnore="b64,mjpeg">'
|
||||||
|
tmp+=' <option value="mp4">'+lang["Poseidon"]+'</option>'
|
||||||
|
tmp+=' <option value="rtmp">'+lang["RTMP Stream"]+'</option>'
|
||||||
|
tmp+=' <option value="flv">'+lang["FLV"]+'</option>'
|
||||||
|
tmp+=' <option value="h264">'+lang["Raw H.264 Stream"]+'</option>'
|
||||||
|
tmp+=' <option value="hls">'+lang["HLS (includes Audio)"]+'</option>'
|
||||||
|
tmp+=' <option value="mjpeg">'+lang["MJPEG"]+'</option>'
|
||||||
|
tmp+=' </select></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="h_st_channel_'+tempID+'_input h_st_channel_'+tempID+'_rtmp">'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Server URL"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" channel-detail="rtmp_server_url" placeholder="Example : rtmp://live-api.facebook.com:80/rtmp/"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Stream Key"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" channel-detail="rtmp_stream_key" placeholder="Example : 1111111111?ds=1&a=xxxxxxxxxx"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group h_st_channel_'+tempID+'_input h_st_channel_'+tempID+'_mjpeg" style="display:none">'
|
||||||
|
tmp+=' <label><div><span>'+lang["# of Allow MJPEG Clients"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" channel-detail="stream_mjpeg_clients" placeholder="20"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="h_st_channel_'+tempID+'_input h_st_channel_'+tempID+'_hls h_st_channel_'+tempID+'_rtmp h_st_channel_'+tempID+'_flv h_st_channel_'+tempID+'_mp4 h_st_channel_'+tempID+'_h264">'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["HLS Video Encoder"]+'</span></div>'
|
||||||
|
tmp+=' <div><select class="form-control" channel-detail="stream_vcodec" selector="h_hls_v_channel_'+tempID+'">'
|
||||||
|
tmp+=' <option value="no" selected>'+lang["Auto"]+'</option>'
|
||||||
|
tmp+=' <option value="libx264">'+lang["libx264"]+'</option>'
|
||||||
|
tmp+=' <option value="libx265">'+lang["libx265"]+'</option>'
|
||||||
|
tmp+=' <option value="copy" selected>'+lang["copy"]+'</option>'
|
||||||
|
tmp+=' <optgroup label="'+lang["Hardware Accelerated"]+'">'
|
||||||
|
tmp+=' <option value="h264_vaapi">'+lang["h264_vaapi"]+'</option>'
|
||||||
|
tmp+=' <option value="hevc_vaapi">'+lang["hevc_vaapi"]+'</option>'
|
||||||
|
tmp+=' <option value="h264_nvenc">'+lang["h264_nvenc"]+'</option>'
|
||||||
|
tmp+=' <option value="hevc_nvenc">'+lang["hevc_nvenc"]+'</option>'
|
||||||
|
tmp+=' <option value="h264_qsv">'+lang["h264_qsv"]+'</option>'
|
||||||
|
tmp+=' <option value="hevc_qsv">'+lang["hevc_qsv"]+'</option>'
|
||||||
|
tmp+=' <option value="mpeg2_qsv">'+lang["mpeg2_qsv"]+'</option>'
|
||||||
|
tmp+=' <option value="h264_omx">'+lang["h264_omx"]+'</option>'
|
||||||
|
tmp+=' </optgroup>'
|
||||||
|
tmp+=' </select></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["HLS Audio Encoder"]+'</span></div>'
|
||||||
|
tmp+=' <div><select class="form-control" channel-detail="stream_acodec">'
|
||||||
|
tmp+=' <option value="no" selected>'+lang["No Audio"]+'</option>'
|
||||||
|
tmp+=' <option value="">'+lang["Auto"]+'</option>'
|
||||||
|
tmp+=' <option value="aac">'+lang["aac"]+'</option>'
|
||||||
|
tmp+=' <option value="ac3">'+lang["ac3"]+'</option>'
|
||||||
|
tmp+=' <option value="libmp3lame">'+lang["libmp3lame"]+'</option>'
|
||||||
|
tmp+=' <option value="copy">'+lang["copy"]+'</option>'
|
||||||
|
tmp+=' </select></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Rate"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" channel-detail="stream_fps" placeholder=""></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="h_st_channel_'+tempID+'_input h_st_channel_'+tempID+'_hls" style="display:none">'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["HLS Segment Length"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" channel-detail="hls_time" placeholder="2"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["HLS Preset"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" channel-detail="preset_stream" placeholder="ultrafast"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["HLS List Size"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" channel-detail="hls_list_size" placeholder="2"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="h_st_channel_'+tempID+'_input h_st_channel_'+tempID+'_mjpeg h_st_channel_'+tempID+'_hls h_st_channel_'+tempID+'_rtmp h_st_channel_'+tempID+'_jsmpeg h_st_channel_'+tempID+'_flv h_st_channel_'+tempID+'_mp4 h_st_channel_'+tempID+'_h264 h_hls_v_channel_'+tempID+'_input h_hls_v_channel_'+tempID+'_libx264 h_hls_v_channel_'+tempID+'_libx265 h_hls_v_channel_'+tempID+'_h264_nvenc h_hls_v_channel_'+tempID+'_hevc_nvenc h_hls_v_channel_'+tempID+'_no" style="display:none">'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Quality"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" placeholder="23" channel-detail="stream_quality"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="h_st_channel_'+tempID+'_input h_st_channel_'+tempID+'_rtmp">'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Video Bit Rate"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" channel-detail="stream_v_br" placeholder=""></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Audio Bit Rate"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" channel-detail="stream_a_br" placeholder="128k"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Width"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" type="number" min="1" channel-detail="stream_scale_x" placeholder="Example : 640"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Height"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" type="number" min="1" channel-detail="stream_scale_y" placeholder="Example : 480"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Rotate"]+'</span></div>'
|
||||||
|
tmp+=' <div><select class="form-control" channel-detail="rotate_stream">'
|
||||||
|
tmp+=' <option value="no" selected>'+lang["No Rotation"]+'</option>'
|
||||||
|
tmp+=' <option value="2,transpose=2">'+lang["180 Degrees"]+'</option>'
|
||||||
|
tmp+=' <option value="0">'+lang["90 Counter Clockwise and Vertical Flip (default)"]+'</option>'
|
||||||
|
tmp+=' <option value="1">'+lang["90 Clockwise"]+'</option>'
|
||||||
|
tmp+=' <option value="2">'+lang["90 Clockwise and Vertical Flip"]+'</option>'
|
||||||
|
tmp+=' <option value="3">'+lang["90 Clockwise and Vertical Flip"]+'</option>'
|
||||||
|
tmp+=' </select></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Video Filter"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" channel-detail="svf"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' <div class="form-group">'
|
||||||
|
tmp+=' <label><div><span>'+lang["Stream Flags"]+'</span></div>'
|
||||||
|
tmp+=' <div><input class="form-control" channel-detail="cust_stream"></div>'
|
||||||
|
tmp+=' </label>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
tmp+=' </div>'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(z && x !== 2){
|
||||||
|
$(z).prepend(tmp)
|
||||||
|
}
|
||||||
|
switch(x){
|
||||||
|
case 1:
|
||||||
|
z='#monitors_list .link-monitors-list[auth="'+user.auth_token+'"][ke="'+d.ke+'"]'
|
||||||
|
if($('.link-monitors-list[auth="'+user.auth_token+'"][ke="'+d.ke+'"]').length===0){
|
||||||
|
$("#monitors_list").append('<div class="link-monitors-list" auth="'+user.auth_token+'" ke="'+d.ke+'"></div>')
|
||||||
|
var options = {
|
||||||
|
cellHeight: 80,
|
||||||
|
verticalMargin: 10,
|
||||||
|
};
|
||||||
|
//monitor="watch_off"
|
||||||
|
$(z).gridstack(options);
|
||||||
|
$(z).on('change', function(event, ui) {
|
||||||
|
var monitors = {}
|
||||||
|
$.grid.e.find(" .monitor_item").each(function(n,v){
|
||||||
|
var el = $(v)
|
||||||
|
var item = {}
|
||||||
|
item.ke = el.attr('ke')
|
||||||
|
item.mid = el.attr('mid')
|
||||||
|
item.x = el.attr('data-gs-x')
|
||||||
|
item.y = el.attr('data-gs-y')
|
||||||
|
item.height = el.attr('data-gs-height')
|
||||||
|
item.width = el.attr('data-gs-width')
|
||||||
|
monitors[item.ke+item.mid] = item
|
||||||
|
})
|
||||||
|
user.details.monitorOrder=monitors;
|
||||||
|
$.ccio.cx({f:'monitorOrder',monitorOrder:monitors},user)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$(z).prepend(tmp)
|
||||||
|
componentHandler.upgradeAllRegistered()
|
||||||
|
break;
|
||||||
|
case 0:case 4:
|
||||||
|
$.ccio.init('ls');
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
var x = 0;
|
||||||
|
var y = 0;
|
||||||
|
var width = $.grid.getMonitorsPerRow()
|
||||||
|
var height = width;
|
||||||
|
if(user.details && user.details.monitorOrder && user.details.monitorOrder[d.ke+d.mid]){
|
||||||
|
var saved = user.details.monitorOrder[d.ke+d.mid];
|
||||||
|
x = saved.x;
|
||||||
|
y = saved.y;
|
||||||
|
width = saved.width;
|
||||||
|
height = saved.height;
|
||||||
|
}
|
||||||
|
var autoPlacement = false
|
||||||
|
if($.ccio.op().switches.monitorOrder !== 1){
|
||||||
|
autoPlacement = true
|
||||||
|
}
|
||||||
|
$(z).data('gridstack').addWidget($(tmp), x, y, width, height, autoPlacement);
|
||||||
|
k.e=$('#monitor_live_'+d.mid+user.auth_token);
|
||||||
|
try{
|
||||||
|
if(JSON.parse(d.details).control=="1"){
|
||||||
|
k.e.find('[monitor="control_toggle"]').show()
|
||||||
|
}else{
|
||||||
|
k.e.find('.pad').remove();
|
||||||
|
k.e.find('[monitor="control_toggle"]').hide()
|
||||||
|
}
|
||||||
|
$.ccio.tm('stream-element',d,null,user)
|
||||||
|
}catch(re){$.ccio.log(re)}
|
||||||
|
k.mid=d.mid
|
||||||
|
k.mon=$.ccio.mon[d.ke+d.mid+user.auth_token]
|
||||||
|
$.ccio.init('monitorInfo',k)
|
||||||
|
break;
|
||||||
|
case'detector-filters-where':
|
||||||
|
$('#detector_filters_where').append(tmp);
|
||||||
|
$('#detector_filters_where .row [where="p4"][disabled]').prop('disabled',false)
|
||||||
|
$('#detector_filters_where .row:last [where="p1"]').val(d.p1)
|
||||||
|
$('#detector_filters_where .row:last [where="p2"]').val(d.p2)
|
||||||
|
$('#detector_filters_where .row:last [where="p3"]').val(d.p3)
|
||||||
|
$('#detector_filters_where .row:last [where="p4"]').val(d.p4).prop('disabled',true)
|
||||||
|
break;
|
||||||
|
case'filters-where':
|
||||||
|
$('#filters_where').append(tmp);
|
||||||
|
$('#filters_where .row:last [where="p1"]').val(d.p1)
|
||||||
|
$('#filters_where .row:last [where="p2"]').val(d.p2)
|
||||||
|
$('#filters_where .row:last [where="p3"]').val(d.p3)
|
||||||
|
break;
|
||||||
|
case'input-map':
|
||||||
|
var mapsList = $.aM.maps
|
||||||
|
mapsList.append(tmp)
|
||||||
|
mapsList.find('.input-map').last().find('[map-detail="aduration"]').change()
|
||||||
|
return tempID;
|
||||||
|
break;
|
||||||
|
case'stream-channel':
|
||||||
|
var channeList = $.aM.channels
|
||||||
|
channeList.append(tmp)
|
||||||
|
channeList.find('.stream-channel').last().find('[channel-detail="stream_vcodec"]').change()
|
||||||
|
return tempID;
|
||||||
|
break;
|
||||||
|
case'link-set':
|
||||||
|
$('[links="'+d.host+'"] [link="secure"]').val(d.secure).change()
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
$.ccio.pm=function(x,d,z,user){
|
||||||
|
var tmp='';if(!d){d={}};
|
||||||
|
if(!user){
|
||||||
|
user=$user
|
||||||
|
}
|
||||||
|
switch(x){
|
||||||
|
case 0:
|
||||||
|
d.mon=$.ccio.mon[d.ke+d.mid+user.auth_token];
|
||||||
|
d.ev='.glM'+d.mid+user.auth_token+'.videos_list ul,.glM'+d.mid+user.auth_token+'.videos_monitor_list ul';d.fr=$.ccio.fr.find(d.ev),d.tmp='';
|
||||||
|
if(d.fr.length===0){$.ccio.fr.append('<div class="videos_list glM'+d.mid+user.auth_token+'"><h3 class="title">'+d.mon.name+'</h3><ul></ul></div>')}
|
||||||
|
if(d.videos&&d.videos.length>0){
|
||||||
|
$.each(d.videos,function(n,v){
|
||||||
|
if(v.status!==0){
|
||||||
|
tmp+=$.ccio.tm(0,v,null,user)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
$('.glM'+d.mid+user.auth_token+'.videos_list,.glM'+d.mid+user.auth_token+'.videos_monitor_list').appendTo($.ccio.fr)
|
||||||
|
tmp+='<li class="notice novideos">No videos</li>';
|
||||||
|
}
|
||||||
|
$(d.ev).html(tmp);
|
||||||
|
$.ccio.init('ls');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
z='#api_list';
|
||||||
|
$(z).empty();
|
||||||
|
$.each(d,function(n,v){
|
||||||
|
tmp+=$.ccio.tm(3,v,null,user);
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case'option':
|
||||||
|
$.each(d,function(n,v){
|
||||||
|
tmp+=$.ccio.tm('option',v,null,user);
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case'user-row':
|
||||||
|
$.each(d,function(n,v){
|
||||||
|
tmp+=$.ccio.tm('user-row',v,null,user);
|
||||||
|
})
|
||||||
|
z='#users_online'
|
||||||
|
break;
|
||||||
|
case'link-set':
|
||||||
|
$.sM.links.empty()
|
||||||
|
$.each(d,function(n,v){
|
||||||
|
tmp+=$.ccio.tm('link-set',v,'#linkShinobi',user)
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(z){
|
||||||
|
$(z).prepend(tmp)
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
|
@ -0,0 +1,767 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
console.log("%cWarning!", "font: 2em monospace; color: red;");
|
||||||
|
console.log('%cLeaving the developer console open is fine if you turn off "Network Recording". This is because it will keep a log of all files, including frames and videos segments.', "font: 1.2em monospace; ");
|
||||||
|
if(!$.ccio.permissionCheck('monitor_create')){
|
||||||
|
$('#add_monitor_button_main').remove()
|
||||||
|
}
|
||||||
|
$.each(['user_change','monitor_create','view_logs'],function(n,permission){
|
||||||
|
if(!$.ccio.permissionCheck(permission)){
|
||||||
|
$('.permission_'+permission).remove()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//Group Selector
|
||||||
|
$.gR={e:$('#group_list'),b:$('#group_list_button')};
|
||||||
|
$.gR.drawList=function(){
|
||||||
|
var e={};
|
||||||
|
e.tmp='';
|
||||||
|
$.each($.ccio.init('monGroup'),function(n,v){
|
||||||
|
if($user.mon_groups[n]){
|
||||||
|
e.tmp+='<li class="mdl-menu__item" groups="'+n+'">'+$user.mon_groups[n].name+'</li>'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.gR.e.html(e.tmp)
|
||||||
|
}
|
||||||
|
$.gR.e.on('click','[groups]',function(){
|
||||||
|
var e={};
|
||||||
|
e.e=$(this),
|
||||||
|
e.a=e.e.attr('groups');
|
||||||
|
var user=$.users[e.e.attr('auth')];
|
||||||
|
if(!user){user=$user}
|
||||||
|
if(user===$user){
|
||||||
|
e.chosen_set='watch_on'
|
||||||
|
}else{
|
||||||
|
e.chosen_set='watch_on_links'
|
||||||
|
}
|
||||||
|
$.each($.ccio.op()[e.chosen_set],function(n,v){
|
||||||
|
$.each(v,function(m,b){
|
||||||
|
$.ccio.cx({f:'monitor',ff:'watch_off',id:m,ke:n},user)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
$.each($.ccio.mon_groups[e.a],function(n,v){
|
||||||
|
$.ccio.cx({f:'monitor',ff:'watch_on',id:v.mid,ke:v.ke},user)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
//open all monitors
|
||||||
|
$('[class_toggle="list-blocks"][data-target="#left_menu"]').dblclick(function(){
|
||||||
|
$('#monitors_list .monitor_block').each(function(n,v){
|
||||||
|
var el = $(v)
|
||||||
|
var ke = el.attr('ke')
|
||||||
|
var mid = el.attr('mid')
|
||||||
|
var auth = el.attr('auth')
|
||||||
|
var monItem = $('.monitor_item[ke='+ke+'][mid='+mid+'][auth='+auth+']')
|
||||||
|
if(monItem.length > 0){
|
||||||
|
monItem.find('[monitor="watch_on"]').click()
|
||||||
|
}else{
|
||||||
|
el.find('[monitor="watch"]').click()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
//search monitors list
|
||||||
|
$('#monitors_list_search').keyup(function(){
|
||||||
|
var monitorBlocks = $('.monitor_block');
|
||||||
|
var searchTerms = $(this).val().toLowerCase().split(' ')
|
||||||
|
if(searchTerms.length === 0 || searchTerms[0] === ''){
|
||||||
|
monitorBlocks.show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
monitorBlocks.hide()
|
||||||
|
$.each($.ccio.mon,function(n,monitor){
|
||||||
|
var searchThis = JSON.stringify($.ccio.init('cleanMon',monitor)).toLowerCase().replace('"','');
|
||||||
|
$.each(searchTerms,function(m,term){
|
||||||
|
if(searchThis.indexOf(term) >-1 ){
|
||||||
|
$('.monitor_block[ke="'+monitor.ke+'"][mid="'+monitor.mid+'"]').show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
//dynamic bindings
|
||||||
|
$.ccio.windowFocus = true
|
||||||
|
$(window).focus(function() {
|
||||||
|
$.ccio.windowFocus = true
|
||||||
|
clearInterval($.ccio.soundAlarmInterval)
|
||||||
|
}).blur(function() {
|
||||||
|
$.ccio.windowFocus = false
|
||||||
|
});
|
||||||
|
$('body')
|
||||||
|
.on('click','.logout',function(e){
|
||||||
|
var logout = function(user,callback){
|
||||||
|
$.get($.ccio.init('location',user)+user.auth_token+'/logout/'+user.ke+'/'+user.uid,callback)
|
||||||
|
}
|
||||||
|
$.each($.users,function(n,linkedShinobiUser){
|
||||||
|
logout(linkedShinobiUser,function(){});
|
||||||
|
})
|
||||||
|
logout($user,function(data){
|
||||||
|
console.log(data)
|
||||||
|
localStorage.removeItem('ShinobiLogin_'+location.host);
|
||||||
|
location.href=location.href;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.on('click','[video]',function(e){
|
||||||
|
e.e=$(this),
|
||||||
|
e.a=e.e.attr('video'),
|
||||||
|
e.p=e.e.parents('[mid]'),
|
||||||
|
e.ke=e.p.attr('ke'),
|
||||||
|
e.mid=e.p.attr('mid'),
|
||||||
|
e.file=e.p.attr('file');
|
||||||
|
e.auth=e.p.attr('auth');
|
||||||
|
e.status=e.p.attr('status');
|
||||||
|
if(!e.ke||!e.mid){
|
||||||
|
//for calendar plugin
|
||||||
|
e.p=e.e.parents('[data-mid]'),
|
||||||
|
e.ke=e.p.data('ke'),
|
||||||
|
e.mid=e.p.data('mid'),
|
||||||
|
e.file=e.p.data('file');
|
||||||
|
e.auth=e.p.data('auth');
|
||||||
|
e.status=e.p.data('status');
|
||||||
|
}
|
||||||
|
e.mon=$.ccio.mon[e.ke+e.mid+e.auth];
|
||||||
|
switch(e.a){
|
||||||
|
case'launch':
|
||||||
|
e.preventDefault();
|
||||||
|
e.href=$(this).attr('href')
|
||||||
|
var el = $('#video_viewer')
|
||||||
|
var modalBody = el.find('.modal-body')
|
||||||
|
el.find('.modal-title span').html(e.mon.name+' - '+e.file)
|
||||||
|
var html = '<video class="video_video" video="'+e.href+'" autoplay loop controls><source src="'+e.href+'" type="video/'+e.mon.ext+'"></video><br><small class="msg"></small>'
|
||||||
|
modalBody.html(html)
|
||||||
|
el.find('video')[0].onerror = function(){
|
||||||
|
modalBody.find('.msg').text(lang.h265BrowserText1)
|
||||||
|
}
|
||||||
|
el.attr('mid',e.mid);
|
||||||
|
footer = el.find('.modal-footer');
|
||||||
|
footer.find('.download_link').attr('href',e.href).attr('download',e.file);
|
||||||
|
footer.find('[monitor="download"][host="dropbox"]').attr('href',e.href);
|
||||||
|
el.modal('show')
|
||||||
|
.attr('ke',e.ke)
|
||||||
|
.attr('mid',e.mid)
|
||||||
|
.attr('auth',e.auth)
|
||||||
|
.attr('file',e.file);
|
||||||
|
if(e.status==1){
|
||||||
|
$.get($.ccio.init('videoHrefToRead',e.href),function(d){
|
||||||
|
if(d.ok !== true)console.log(d,new Error())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'delete':
|
||||||
|
e.preventDefault();
|
||||||
|
var videoLink = e.p.find('[download]').attr('href')
|
||||||
|
var href = $(this).attr('href')
|
||||||
|
console.log('videoLink',videoLink)
|
||||||
|
console.log(href)
|
||||||
|
if(!href){
|
||||||
|
href = $.ccio.init('location',$.users[e.auth])+e.auth+'/videos/'+e.ke+'/'+e.mid+'/'+e.file+'/delete<% if(config.useUTC === true){%>?isUTC=true<%}%>'
|
||||||
|
}
|
||||||
|
console.log(href)
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text(lang['Delete Video']+' : '+e.file)
|
||||||
|
e.html=lang.DeleteVideoMsg
|
||||||
|
e.html+='<video class="video_video" autoplay loop controls><source src="'+videoLink+'" type="video/'+e.mon.ext+'"></video>';
|
||||||
|
$.confirm.body.html(e.html)
|
||||||
|
$.confirm.click({title:'Delete Video',class:'btn-danger'},function(){
|
||||||
|
$.getJSON(href,function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case'download':
|
||||||
|
e.preventDefault();
|
||||||
|
switch(e.e.attr('host')){
|
||||||
|
case'dropbox':
|
||||||
|
if($.ccio.DropboxAppKey){
|
||||||
|
Dropbox.save(e.e.attr('href'),e.e.attr('download'),{progress: function (progress) {$.ccio.log(progress)},success: function () {
|
||||||
|
$.ccio.log(lang.dropBoxSuccess);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on('change','[localStorage]',function(){
|
||||||
|
e = {}
|
||||||
|
e.e=$(this)
|
||||||
|
e.localStorage = e.e.attr('localStorage')
|
||||||
|
e.value = e.e.val()
|
||||||
|
$.ccio.op(e.localStorage,e.value)
|
||||||
|
})
|
||||||
|
.on('click','[system]',function(e){
|
||||||
|
var e={};
|
||||||
|
e.e=$(this),
|
||||||
|
e.a=e.e.attr('system');//the function
|
||||||
|
switch(e.a){
|
||||||
|
case'switch':
|
||||||
|
e.switch=e.e.attr('switch');
|
||||||
|
e.o=$.ccio.op().switches
|
||||||
|
if(!e.o){
|
||||||
|
e.o={}
|
||||||
|
}
|
||||||
|
if(!e.o[e.switch]){
|
||||||
|
e.o[e.switch]=0
|
||||||
|
}
|
||||||
|
if(e.o[e.switch]===1){
|
||||||
|
e.o[e.switch]=0
|
||||||
|
}else{
|
||||||
|
e.o[e.switch]=1
|
||||||
|
}
|
||||||
|
$.ccio.op('switches',e.o)
|
||||||
|
switch(e.switch){
|
||||||
|
case'monitorOrder':
|
||||||
|
if(e.o[e.switch] !== 1){
|
||||||
|
$('.monitor_item').attr('data-gs-auto-position','yes')
|
||||||
|
}else{
|
||||||
|
$('.monitor_item').attr('data-gs-auto-position','no')
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'monitorMuteAudio':
|
||||||
|
$('.monitor_item video').each(function(n,el){
|
||||||
|
if(e.o[e.switch] === 1){
|
||||||
|
el.muted = true
|
||||||
|
}else{
|
||||||
|
el.muted = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch(e.e.attr('type')){
|
||||||
|
case'text':
|
||||||
|
if(e.o[e.switch]===1){
|
||||||
|
e.e.addClass('text-success')
|
||||||
|
}else{
|
||||||
|
e.e.removeClass('text-success')
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'cronStop':
|
||||||
|
$.ccio.cx({f:'cron',ff:'stop'})
|
||||||
|
break;
|
||||||
|
case'cronRestart':
|
||||||
|
$.ccio.cx({f:'cron',ff:'restart'})
|
||||||
|
break;
|
||||||
|
case'jpegToggle':
|
||||||
|
e.cx={f:'monitor',ff:'jpeg_on'};
|
||||||
|
if($.ccio.op().jpeg_on===true){
|
||||||
|
e.cx.ff='jpeg_off';
|
||||||
|
}
|
||||||
|
$.ccio.cx(e.cx)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on('click','[class_toggle]',function(e){
|
||||||
|
e.e=$(this);
|
||||||
|
e.n=e.e.attr('data-target');
|
||||||
|
e.v=e.e.attr('class_toggle');
|
||||||
|
e.o=$.ccio.op().class_toggle;
|
||||||
|
if($(e.n).hasClass(e.v)){e.t=0}else{e.t=1}
|
||||||
|
if(!e.o)e.o={};
|
||||||
|
e.o[e.n]=[e.v,e.t];
|
||||||
|
$.ccio.op('class_toggle',e.o)
|
||||||
|
$(e.n).toggleClass(e.v);
|
||||||
|
})
|
||||||
|
.on('change','[dropdown_toggle]',function(e){
|
||||||
|
e.e=$(this);
|
||||||
|
e.n=e.e.attr('dropdown_toggle');
|
||||||
|
e.v=e.e.val();
|
||||||
|
e.o=$.ccio.op().dropdown_toggle;
|
||||||
|
if(!e.o)e.o={};
|
||||||
|
e.o[e.n]=e.v;
|
||||||
|
$.ccio.op('dropdown_toggle',e.o)
|
||||||
|
})
|
||||||
|
//monitor functions
|
||||||
|
.on('click','[monitor]',function(){
|
||||||
|
var e={};
|
||||||
|
e.e=$(this),
|
||||||
|
e.a=e.e.attr('monitor'),//the function
|
||||||
|
e.p=e.e.parents('[mid]'),//the parent element for monitor item
|
||||||
|
e.ke=e.p.attr('ke'),//group key
|
||||||
|
e.mid=e.p.attr('mid'),//monitor id
|
||||||
|
e.auth=e.p.attr('auth'),//authkey
|
||||||
|
e.mon=$.ccio.mon[e.ke+e.mid+e.auth];//monitor configuration
|
||||||
|
var user
|
||||||
|
if($.users[e.auth]){user=$.users[e.auth]}else{user=$user}
|
||||||
|
if(!user){
|
||||||
|
user=$user
|
||||||
|
}
|
||||||
|
switch(e.a){
|
||||||
|
case'show_data':
|
||||||
|
e.p.toggleClass('show_data')
|
||||||
|
var dataBlocks = e.p.find('.stream-block,.mdl-data_window')
|
||||||
|
if(e.p.hasClass('show_data')){
|
||||||
|
dataBlocks.addClass('col-md-6').removeClass('col-md-12')
|
||||||
|
}else{
|
||||||
|
dataBlocks.addClass('col-md-12').removeClass('col-md-6')
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'motion':
|
||||||
|
if(!e.mon.motionDetectionRunning){
|
||||||
|
$.ccio.init('streamMotionDetectOn',e,user)
|
||||||
|
}else{
|
||||||
|
$.ccio.init('streamMotionDetectOff',e,user)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'pop':
|
||||||
|
e.fin=function(img){
|
||||||
|
if($.ccio.mon[e.ke+e.mid+user.auth_token].popOut){
|
||||||
|
$.ccio.mon[e.ke+e.mid+user.auth_token].popOut.close()
|
||||||
|
}
|
||||||
|
$.ccio.mon[e.ke+e.mid+user.auth_token].popOut = window.open($.ccio.init('location',user)+user.auth_token+'/embed/'+e.ke+'/'+e.mid+'/fullscreen|jquery|relative|gui','pop_'+e.mid+user.auth_token,'height='+img.height+',width='+img.width);
|
||||||
|
}
|
||||||
|
if(e.mon.watch===1){
|
||||||
|
$.ccio.snapshot(e,function(url){
|
||||||
|
$('#temp').html('<img>')
|
||||||
|
var img=$('#temp img')[0]
|
||||||
|
img.onload=function(){
|
||||||
|
e.fin(img)
|
||||||
|
}
|
||||||
|
img.src=url
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
var img={height:720,width:1280}
|
||||||
|
e.fin(img)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'mode':
|
||||||
|
e.mode=e.e.attr('mode')
|
||||||
|
if(e.mode){
|
||||||
|
$.getJSON($.ccio.init('location',user)+user.auth_token+'/monitor/'+e.ke+'/'+e.mid+'/'+e.mode,function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'timelapse':
|
||||||
|
$.timelapse.e.modal('show')
|
||||||
|
$.timelapse.monitors.find('.monitor').remove()
|
||||||
|
$.each($.ccio.mon,function(n,v){
|
||||||
|
$.timelapse.monitors.append('<option class="monitor" value="'+v.mid+'">'+v.name+'</option>')
|
||||||
|
})
|
||||||
|
e.e=$.timelapse.monitors.find('.monitor').prop('selected',false)
|
||||||
|
if(e.mid!==''){
|
||||||
|
e.e=$.timelapse.monitors.find('.monitor[value="'+e.mid+'"]')
|
||||||
|
}
|
||||||
|
e.e.first().prop('selected',true)
|
||||||
|
$.timelapse.f.submit()
|
||||||
|
break;
|
||||||
|
case'powerview':
|
||||||
|
$.pwrvid.e.modal('show')
|
||||||
|
$.pwrvid.m.empty()
|
||||||
|
$.each($.ccio.mon,function(n,v){
|
||||||
|
$.pwrvid.m.append('<option value="'+v.mid+'">'+v.name+'</option>')
|
||||||
|
})
|
||||||
|
e.e=$.pwrvid.m.find('option').prop('selected',false)
|
||||||
|
if(e.mid!==''){
|
||||||
|
e.e=$.pwrvid.m.find('[value="'+e.mid+'"]')
|
||||||
|
}
|
||||||
|
e.e.first().prop('selected',true)
|
||||||
|
$.pwrvid.f.submit()
|
||||||
|
break;
|
||||||
|
case'region':
|
||||||
|
if(!e.mon){
|
||||||
|
$.ccio.init('note',{title:lang['Unable to Launch'],text:lang.UnabletoLaunchText,type:'error'});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.d=JSON.parse(e.mon.details);
|
||||||
|
e.width=$.aM.e.find('[detail="detector_scale_x"]');
|
||||||
|
e.height=$.aM.e.find('[detail="detector_scale_y"]');
|
||||||
|
e.d.cords=$.aM.e.find('[detail="cords"]').val();
|
||||||
|
if(e.width.val()===''){
|
||||||
|
e.d.detector_scale_x=320;
|
||||||
|
e.d.detector_scale_y=240;
|
||||||
|
$.aM.e.find('[detail="detector_scale_x"]').val(e.d.detector_scale_x);
|
||||||
|
$.aM.e.find('[detail="detector_scale_y"]').val(e.d.detector_scale_y);
|
||||||
|
}else{
|
||||||
|
e.d.detector_scale_x=e.width.val();
|
||||||
|
e.d.detector_scale_y=e.height.val();
|
||||||
|
}
|
||||||
|
|
||||||
|
$.zO.e.modal('show');
|
||||||
|
$.zO.o().attr('width',e.d.detector_scale_x).attr('height',e.d.detector_scale_y);
|
||||||
|
$.zO.c.css({width:e.d.detector_scale_x,height:e.d.detector_scale_y});
|
||||||
|
if(e.d.cords&&(e.d.cords instanceof Object)===false){
|
||||||
|
try{e.d.cords=JSON.parse(e.d.cords);}catch(er){}
|
||||||
|
}
|
||||||
|
if(!e.d.cords||e.d.cords===''){
|
||||||
|
e.d.cords={
|
||||||
|
red:{ name:"red",sensitivity:0.0005, max_sensitivity:"",color_threshold:"",points:[[0,0],[0,100],[100,0]] },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.zO.regionViewerDetails=e.d;
|
||||||
|
$.zO.initRegionList()
|
||||||
|
break;
|
||||||
|
case'detector_filters':
|
||||||
|
$.detectorFilters.e.modal('show');
|
||||||
|
break;
|
||||||
|
case'snapshot':
|
||||||
|
$.ccio.snapshot(e,function(url){
|
||||||
|
$('#temp').html('<a href="'+url+'" download="'+$.ccio.init('tf')+'_'+e.ke+'_'+e.mid+'.jpg">a</a>').find('a')[0].click();
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case'control':
|
||||||
|
e.a=e.e.attr('control')
|
||||||
|
$.ccio.cx({f:'monitor',ff:'control',direction:e.a,mid:e.mid,ke:e.ke},user)
|
||||||
|
break;
|
||||||
|
case'videos_table':case'calendar':case'video_grid'://call videos table or calendar or video grid
|
||||||
|
$.vidview.launcher=$(this);
|
||||||
|
e.limit=$.vidview.limit.val();
|
||||||
|
if(!$.vidview.current_mid||$.vidview.current_mid!==e.mid){
|
||||||
|
$.vidview.current_mid=e.mid
|
||||||
|
$.vidview.current_page=1;
|
||||||
|
if(e.limit.replace(/ /g,'')===''){
|
||||||
|
e.limit='100';
|
||||||
|
}
|
||||||
|
if(e.limit.indexOf(',')===-1){
|
||||||
|
e.limit='0,'+e.limit
|
||||||
|
}else{
|
||||||
|
e.limit='0,'+e.limit.split(',')[1]
|
||||||
|
}
|
||||||
|
if(e.limit=='0,0'){
|
||||||
|
e.limit='0'
|
||||||
|
}
|
||||||
|
$.vidview.limit.val(e.limit)
|
||||||
|
}
|
||||||
|
e.dateRange=$('#videos_viewer_daterange').data('daterangepicker');
|
||||||
|
var videoSet = 'videos'
|
||||||
|
switch($.vidview.set.val()){
|
||||||
|
case'cloud':
|
||||||
|
videoSet = 'cloudVideos'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
e.videoURL=$.ccio.init('location',user)+user.auth_token+'/'+videoSet+'/'+e.ke+'/'+e.mid+'?limit='+e.limit+'&start='+$.ccio.init('th',e.dateRange.startDate)+'&end='+$.ccio.init('th',e.dateRange.endDate);
|
||||||
|
$.getJSON(e.videoURL,function(d){
|
||||||
|
d.pages=d.total/100;
|
||||||
|
$('.video_viewer_total').text(d.total)
|
||||||
|
if(d.pages+''.indexOf('.')>-1){++d.pages}
|
||||||
|
$.vidview.page_count=d.pages;
|
||||||
|
d.count=1
|
||||||
|
$.vidview.pages.empty()
|
||||||
|
d.fn=function(drawOne){
|
||||||
|
if(d.count<=$.vidview.page_count){
|
||||||
|
$.vidview.pages.append('<a class="btn btn-primary" page="'+d.count+'">'+d.count+'</a> ')
|
||||||
|
++d.count;
|
||||||
|
d.fn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.fn()
|
||||||
|
$.vidview.pages.find('[page="'+$.vidview.current_page+'"]').addClass('active')
|
||||||
|
e.v=$.vidview.e;
|
||||||
|
$.vidview.loadedVideos = {}
|
||||||
|
e.b=e.v.modal('show').find('.modal-body .contents');
|
||||||
|
e.t=e.v.find('.modal-title i');
|
||||||
|
switch(e.a){
|
||||||
|
case'calendar':
|
||||||
|
$.vidview.e.removeClass('dark')
|
||||||
|
e.t.attr('class','fa fa-calendar')
|
||||||
|
e.ar=[];
|
||||||
|
if(d.videos[0]){
|
||||||
|
$.each(d.videos,function(n,v){
|
||||||
|
if(v.status !== 0){
|
||||||
|
$.vidview.loadedVideos[v.filename] = Object.assign(v,{})
|
||||||
|
var n=$.ccio.mon[v.ke+v.mid+user.auth_token];
|
||||||
|
if(n){v.title=n.name+' - '+(parseInt(v.size)/1000000).toFixed(2)+'mb';}
|
||||||
|
v.start=v.time;
|
||||||
|
// v.filename=$.ccio.init('tf',v.time)+'.'+v.ext;
|
||||||
|
e.ar.push(v);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
e.b.html('')
|
||||||
|
try{e.b.fullCalendar('destroy')}catch(er){}
|
||||||
|
e.b.fullCalendar({
|
||||||
|
header: {
|
||||||
|
left: 'prev,next today',
|
||||||
|
center: 'title',
|
||||||
|
right: 'month,agendaWeek,agendaDay,listWeek'
|
||||||
|
},
|
||||||
|
defaultDate: $.ccio.timeObject(d.videos[0].time).format('YYYY-MM-DD'),
|
||||||
|
navLinks: true,
|
||||||
|
eventLimit: true,
|
||||||
|
events:e.ar,
|
||||||
|
eventClick:function(f){
|
||||||
|
$('#temp').html('<div mid="'+f.mid+'" ke="'+f.ke+'" auth="'+user.auth_token+'" file="'+f.filename+'"><div video="launch" href="'+$.ccio.init('videoUrlBuild',f)+'"></div></div>').find('[video="launch"]').click();
|
||||||
|
$(this).css('border-color', 'red');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setTimeout(function(){e.b.fullCalendar('changeView','month');e.b.find('.fc-scroller').css('height','auto')},500)
|
||||||
|
}else{
|
||||||
|
e.b.html('<div class="text-center">'+lang.NoVideosFoundForDateRange+'</div>')
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'video_grid':
|
||||||
|
$.vidview.e.addClass('dark')
|
||||||
|
var tmp = '<di class="video_grid row">';
|
||||||
|
$.each(d.videos,function(n,v){
|
||||||
|
var href = $.ccio.init('videoUrlBuild',v)
|
||||||
|
v.mon = $.ccio.mon[v.ke+v.mid+user.auth_token]
|
||||||
|
var parentTag = 'ke="'+v.ke+'" status="'+v.status+'" mid="'+v.mid+'" file="'+v.filename+'" auth="'+v.mon.user.auth_token+'"'
|
||||||
|
tmp += '<div class="col-md-2" '+parentTag+'>'
|
||||||
|
tmp += '<div class="thumb">'
|
||||||
|
tmp += '<div class="title-strip">'+$.ccio.timeObject(v.time).format('h:mm:ss A, MMMM Do YYYY')+'</div>'
|
||||||
|
tmp += '<div class="button-strip">'
|
||||||
|
tmp += '<div class="btn-group">'
|
||||||
|
tmp += '<a class="btn btn-xs btn-primary" video="launch" href="'+href+'"> <i class="fa fa-play-circle"></i> </a>'
|
||||||
|
tmp += '<a class="btn btn-xs btn-default preview" href="'+href+'"> <i class="fa fa-play-circle"></i> </a>'
|
||||||
|
tmp += '<a class="btn btn-xs btn-default" download="'+v.mid+'-'+v.filename+'" href="'+href+'"> <i class="fa fa-download"></i> </a>'
|
||||||
|
tmp += '</div>'
|
||||||
|
tmp += '</div>'
|
||||||
|
tmp += '</div>'
|
||||||
|
tmp += '</div>'
|
||||||
|
})
|
||||||
|
tmp += '</div>'
|
||||||
|
e.b.html(tmp)
|
||||||
|
var i = 0
|
||||||
|
var getThumbnail = function(){
|
||||||
|
var v = d.videos[i]
|
||||||
|
if(v){
|
||||||
|
tool.getVideoImage($.ccio.init('videoUrlBuild',v),0,function(err,base64){
|
||||||
|
if(base64){
|
||||||
|
$('[ke="'+v.ke+'"][mid="'+v.mid+'"][file="'+v.filename+'"] .thumb').css('background-image','url('+base64+')')
|
||||||
|
}
|
||||||
|
++i
|
||||||
|
getThumbnail()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getThumbnail()
|
||||||
|
break;
|
||||||
|
case'videos_table':
|
||||||
|
var showThumbnail = $.ccio.op().showThumbnail === '1'
|
||||||
|
$.vidview.e.removeClass('dark')
|
||||||
|
e.t.attr('class','fa fa-film')
|
||||||
|
var tmp = '<table class="table table-striped" style="max-height:500px">';
|
||||||
|
tmp+='<thead>';
|
||||||
|
tmp+='<tr>';
|
||||||
|
tmp+='<th><div class="checkbox"><input id="videos_select_all" type="checkbox"><label for="videos_select_all"></label></div></th>';
|
||||||
|
if(showThumbnail)tmp+='<th data-field="Thumbnail" data-sortable="true">'+lang.Thumbnail+'</th>';
|
||||||
|
tmp+='<th data-field="Closed" data-sortable="true">'+lang.Closed+'</th>';
|
||||||
|
tmp+='<th data-field="Ended" data-sortable="true">'+lang.Ended+'</th>';
|
||||||
|
tmp+='<th data-field="Started" data-sortable="true">'+lang.Started+'</th>';
|
||||||
|
tmp+='<th data-field="Monitor" data-sortable="true">'+lang.Monitor+'</th>';
|
||||||
|
tmp+='<th data-field="Filename" data-sortable="true">'+lang.Filename+'</th>';
|
||||||
|
tmp+='<th data-field="Size" data-sortable="true">'+lang['Size (mb)']+'</th>';
|
||||||
|
tmp+='<th data-field="Preview" data-sortable="true">'+lang.Preview+'</th>';
|
||||||
|
tmp+='<th data-field="Watch" data-sortable="true">'+lang.Watch+'</th>';
|
||||||
|
tmp+='<th data-field="Download" data-sortable="true">'+lang.Download+'</th>';
|
||||||
|
tmp+='<th class="permission_video_delete" data-field="Delete" data-sortable="true">'+lang.Delete+'</th>';
|
||||||
|
// tmp+='<th class="permission_video_delete" data-field="Fix" data-sortable="true">'+lang.Fix+'</th>';
|
||||||
|
tmp+='</tr>';
|
||||||
|
tmp+='</thead>';
|
||||||
|
tmp+='<tbody>';
|
||||||
|
$.each(d.videos,function(n,v){
|
||||||
|
if(v.status!==0){
|
||||||
|
$.vidview.loadedVideos[v.filename] = Object.assign(v,{})
|
||||||
|
var href = $.ccio.init('videoUrlBuild',v)
|
||||||
|
v.mon=$.ccio.mon[v.ke+v.mid+user.auth_token];
|
||||||
|
v.start=v.time;
|
||||||
|
// v.filename=$.ccio.init('tf',v.time)+'.'+v.ext;
|
||||||
|
tmp+='<tr data-ke="'+v.ke+'" data-status="'+v.status+'" data-mid="'+v.mid+'" data-file="'+v.filename+'" data-auth="'+v.mon.user.auth_token+'">';
|
||||||
|
tmp+='<td><div class="checkbox"><input id="'+v.ke+'_'+v.filename+'" name="'+v.filename+'" value="'+v.mid+'" type="checkbox"><label for="'+v.ke+'_'+v.filename+'"></label></div></td>';
|
||||||
|
if(showThumbnail)tmp+='<td class="text-center"><img class="thumbnail"></td>';
|
||||||
|
tmp+='<td><span class="livestamp" title="'+$.ccio.timeObject(v.end).format('YYYY-MM-DD HH:mm:ss')+'"></span></td>';
|
||||||
|
tmp+='<td title="'+v.end+'">'+$.ccio.timeObject(v.end).format('h:mm:ss A, MMMM Do YYYY')+'</td>';
|
||||||
|
tmp+='<td title="'+v.time+'">'+$.ccio.timeObject(v.time).format('h:mm:ss A, MMMM Do YYYY')+'</td>';
|
||||||
|
tmp+='<td>'+v.mon.name+'</td>';
|
||||||
|
tmp+='<td>'+v.filename+'</td>';
|
||||||
|
tmp+='<td>'+(parseInt(v.size)/1000000).toFixed(2)+'</td>';
|
||||||
|
tmp+='<td><a class="btn btn-sm btn-default preview" href="'+href+'"> <i class="fa fa-play-circle"></i> </a></td>';
|
||||||
|
tmp+='<td><a class="btn btn-sm btn-primary" video="launch" href="'+href+'"> <i class="fa fa-play-circle"></i> </a></td>';
|
||||||
|
tmp+='<td><a class="btn btn-sm btn-success" download="'+v.mid+'-'+v.filename+'" href="'+href+'"> <i class="fa fa-download"></i> </a></td>';
|
||||||
|
tmp+='<td class="permission_video_delete"><a class="btn btn-sm btn-danger" video="delete" href="'+$.ccio.init('videoHrefToDelete',href)+'"> <i class="fa fa-trash"></i> </a></td>';
|
||||||
|
// tmp+='<td class="permission_video_delete"><a class="btn btn-sm btn-warning" video="fix"> <i class="fa fa-wrench"></i> </a></td>';
|
||||||
|
tmp+='</tr>';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
tmp+='</tbody>';
|
||||||
|
tmp+='</table>';
|
||||||
|
e.b.html(tmp)
|
||||||
|
if(showThumbnail){
|
||||||
|
var i = 0
|
||||||
|
var getThumbnail = function(){
|
||||||
|
var v = d.videos[i]
|
||||||
|
if(v){
|
||||||
|
tool.getVideoImage($.ccio.init('videoUrlBuild',v),0,function(err,base64){
|
||||||
|
if(base64){
|
||||||
|
$('[data-ke="'+v.ke+'"][data-mid="'+v.mid+'"][data-file="'+v.filename+'"] .thumbnail')[0].src = base64
|
||||||
|
}
|
||||||
|
++i
|
||||||
|
getThumbnail()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getThumbnail()
|
||||||
|
}
|
||||||
|
$.ccio.init('ls');
|
||||||
|
$.vidview.e.find('table').bootstrapTable();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case'fullscreen':
|
||||||
|
e.e=e.e.parents('.monitor_item');
|
||||||
|
e.e.addClass('fullscreen')
|
||||||
|
e.vid=e.e.find('.stream-element')
|
||||||
|
if(e.vid.is('canvas')){
|
||||||
|
e.doc=$('body')
|
||||||
|
e.vid.attr('height',e.doc.height())
|
||||||
|
e.vid.attr('width',e.doc.width())
|
||||||
|
}
|
||||||
|
$.ccio.init('fullscreen',e.vid[0])
|
||||||
|
break;
|
||||||
|
case'watch_on':
|
||||||
|
$.ccio.cx({f:'monitor',ff:'watch_on',id:e.mid},user)
|
||||||
|
break;
|
||||||
|
case'control_toggle':
|
||||||
|
e.e=e.p.find('.PTZ_controls');
|
||||||
|
if(e.e.length>0){
|
||||||
|
e.e.remove()
|
||||||
|
}else{
|
||||||
|
var html = '<div class="PTZ_controls">'
|
||||||
|
html += '<div class="pad">'
|
||||||
|
html += '<div class="control top" monitor="control" control="up"></div>'
|
||||||
|
html += '<div class="control left" monitor="control" control="left"></div>'
|
||||||
|
html += '<div class="control right" monitor="control" control="right"></div>'
|
||||||
|
html += '<div class="control bottom" monitor="control" control="down"></div>'
|
||||||
|
html += '<div class="control middle" monitor="control" control="center"></div>'
|
||||||
|
html += '</div>'
|
||||||
|
html += '<div class="btn-group btn-group-sm btn-group-justified">'
|
||||||
|
html += '<a title="'+lang['Zoom In']+'" class="zoom_in btn btn-default" monitor="control" control="zoom_in"><i class="fa fa-search-plus"></i></a>'
|
||||||
|
html += '<a title="'+lang['Zoom Out']+'" class="zoom_out btn btn-default" monitor="control" control="zoom_out"><i class="fa fa-search-minus"></i></a>'
|
||||||
|
html += '</div>'
|
||||||
|
html += '<div class="btn-group btn-group-sm btn-group-justified">'
|
||||||
|
html += '<a title="'+lang['Enable Nightvision']+'" class="nv_enable btn btn-default" monitor="control" control="enable_nv"><i class="fa fa-moon-o"></i></a>'
|
||||||
|
html += '<a title="'+lang['Disable Nightvision']+'" class="nv_disable btn btn-default" monitor="control" control="disable_nv"><i class="fa fa-sun-o"></i></a>'
|
||||||
|
html += '</div>'
|
||||||
|
html += '</div>'
|
||||||
|
e.p.append(html)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'watch':
|
||||||
|
if($("#monitor_live_"+e.mid+user.auth_token).length===0||$.ccio.mon[e.ke+e.mid+user.auth_token].watch!==1){
|
||||||
|
$.ccio.cx({f:'monitor',ff:'watch_on',id:e.mid},user)
|
||||||
|
}else{
|
||||||
|
$("#main_canvas").animate({scrollTop:$("#monitor_live_"+e.mid+user.auth_token).offset().top-($('#main_header').height()+10)},500);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'watch_off':
|
||||||
|
$.ccio.cx({f:'monitor',ff:'watch_off',id:e.mid},user)
|
||||||
|
break;
|
||||||
|
case'delete':
|
||||||
|
e.m=$('#confirm_window').modal('show');e.f=e.e.attr('file');
|
||||||
|
$.confirm.title.text(lang['Delete Monitor']+' : '+e.mon.name)
|
||||||
|
e.html=lang.DeleteMonitorText
|
||||||
|
e.html+='<table class="info-table table table-striped"><tr>';
|
||||||
|
$.each($.ccio.init('cleanMon',e.mon),function(n,v,g){
|
||||||
|
if(n==='host'&&v.indexOf('@')>-1){g=v.split('@')[1]}else{g=v};
|
||||||
|
try{JSON.parse(g);return}catch(err){}
|
||||||
|
e.html+='<tr><td><b>'+n+'</b></td><td>'+g+'</td></tr>';
|
||||||
|
})
|
||||||
|
e.html+='</tr></table>';
|
||||||
|
$.confirm.body.html(e.html)
|
||||||
|
$.confirm.click([
|
||||||
|
{
|
||||||
|
title:'Delete Monitor',
|
||||||
|
class:'btn-danger',
|
||||||
|
callback:function(){
|
||||||
|
$.get($.ccio.init('location',user)+user.auth_token+'/configureMonitor/'+user.ke+'/'+e.mon.mid+'/delete',function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title:'Delete Monitor and Files',
|
||||||
|
class:'btn-danger',
|
||||||
|
callback:function(){
|
||||||
|
$.get($.ccio.init('location',user)+user.auth_token+'/configureMonitor/'+user.ke+'/'+e.mon.mid+'/delete?deleteFiles=true',function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
|
break;
|
||||||
|
case'edit':
|
||||||
|
e.p=$('#add_monitor'),e.mt=e.p.find('.modal-title')
|
||||||
|
e.p.find('.am_notice').hide()
|
||||||
|
e.p.find('[detailcontainer="detector_cascades"]').prop('checked',false).parents('.mdl-js-switch').removeClass('is-checked')
|
||||||
|
if(!$.ccio.mon[e.ke+e.mid+user.auth_token]){
|
||||||
|
e.p.find('.am_notice_new').show()
|
||||||
|
//new monitor
|
||||||
|
e.p.find('[monitor="delete"]').hide()
|
||||||
|
e.mt.find('span').text('Add'),e.mt.find('i').attr('class','fa fa-plus');
|
||||||
|
//default values
|
||||||
|
e.values=$.aM.generateDefaultMonitorSettings();
|
||||||
|
}else{
|
||||||
|
e.p.find('.am_notice_edit').show()
|
||||||
|
//edit monitor
|
||||||
|
e.p.find('[monitor="delete"]').show()
|
||||||
|
e.mt.find('span').text(lang.Edit);
|
||||||
|
e.mt.find('i').attr('class','fa fa-wrench');
|
||||||
|
e.values=$.ccio.mon[e.ke+e.mid+user.auth_token];
|
||||||
|
}
|
||||||
|
$.aM.selected=e.values;
|
||||||
|
// e.openTabs=$.ccio.op().tabsOpen
|
||||||
|
// if(e.openTabs[e.mid]){
|
||||||
|
// e.values=e.openTabs[e.mid]
|
||||||
|
// }
|
||||||
|
$.aM.import(e)
|
||||||
|
$('#add_monitor').modal('show')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on('dblclick','[type="password"],.password_field',function(){
|
||||||
|
var _this = $(this)
|
||||||
|
var type = 'password'
|
||||||
|
_this.addClass('password_field')
|
||||||
|
if(_this.attr('type') === 'password'){
|
||||||
|
type = 'text'
|
||||||
|
}
|
||||||
|
_this.attr('type',type)
|
||||||
|
})
|
||||||
|
|
||||||
|
$('.modal').on('hidden.bs.modal',function(){
|
||||||
|
$(this).find('video').remove();
|
||||||
|
$(this).find('iframe').attr('src','about:blank');
|
||||||
|
});
|
||||||
|
$('.modal').on('shown.bs.modal',function(){
|
||||||
|
e={e:$(this).find('.flex-container-modal-body')}
|
||||||
|
if(e.e.length>0){
|
||||||
|
e.e.resize()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('body')
|
||||||
|
.on('click','.scrollTo',function(ee){
|
||||||
|
ee.preventDefault()
|
||||||
|
var e = {e:$(this)};
|
||||||
|
e.parent=e.e.attr('scrollToParent')
|
||||||
|
if(!e.parent){
|
||||||
|
e.parent='body,html'
|
||||||
|
}
|
||||||
|
$(e.parent).animate({
|
||||||
|
scrollTop: $(e.e.attr('href')).position().top
|
||||||
|
}, 400);
|
||||||
|
})
|
||||||
|
.on('resize','.flex-container-modal-body',function(e){
|
||||||
|
e=$(this)
|
||||||
|
e.find('.flex-modal-block').css('height',e.height())
|
||||||
|
})
|
||||||
|
.on('resize','#monitors_live .monitor_item',function(e){
|
||||||
|
e.e=$(this).find('.stream-block');
|
||||||
|
e.c=e.e.find('canvas');
|
||||||
|
e.c.attr('height',e.e.height());
|
||||||
|
e.c.attr('width',e.e.width());
|
||||||
|
})
|
||||||
|
.on('keyup','.search-parent .search-controller',function(){
|
||||||
|
_this = this;
|
||||||
|
$.each($(".search-parent .search-body .search-row"), function() {
|
||||||
|
if($(this).text().toLowerCase().indexOf($(_this).val().toLowerCase()) === -1)
|
||||||
|
$(this).hide();
|
||||||
|
else
|
||||||
|
$(this).show();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.on('dblclick','.stream-hud',function(){
|
||||||
|
$(this).parents('[mid]').find('[monitor="fullscreen"]').click();
|
||||||
|
})
|
||||||
|
//.on('mousemove',".magnifyStream",$.ccio.magnifyStream)
|
||||||
|
//.on('touchmove',".magnifyStream",$.ccio.magnifyStream);
|
||||||
|
})
|
|
@ -0,0 +1,61 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//monitor grid
|
||||||
|
$.grid={e:$('#monitors_live')}
|
||||||
|
$.grid.data = function(){
|
||||||
|
return $.grid.e.data('gridstack')
|
||||||
|
}
|
||||||
|
$.grid.getMonitorsPerRow = function(){
|
||||||
|
var x
|
||||||
|
switch($.ccio.op().montage){
|
||||||
|
case'1':
|
||||||
|
x = '12'
|
||||||
|
break;
|
||||||
|
case'2':
|
||||||
|
x = '6'
|
||||||
|
break;
|
||||||
|
case'3':
|
||||||
|
x = '4'
|
||||||
|
break;
|
||||||
|
case'4':
|
||||||
|
x = '3'
|
||||||
|
break;
|
||||||
|
case'5':
|
||||||
|
x = '5'
|
||||||
|
break;
|
||||||
|
case'6':
|
||||||
|
x = '2'
|
||||||
|
break;
|
||||||
|
default://3
|
||||||
|
x = '4'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
$.grid.saveElementPositions = function() {
|
||||||
|
var monitors = {}
|
||||||
|
$.grid.e.find(" .monitor_item").each(function(n,v){
|
||||||
|
var el = $(v)
|
||||||
|
var item = {}
|
||||||
|
item.ke = el.attr('ke')
|
||||||
|
item.mid = el.attr('mid')
|
||||||
|
item.x = el.attr('data-gs-x')
|
||||||
|
item.y = el.attr('data-gs-y')
|
||||||
|
item.height = el.attr('data-gs-height')
|
||||||
|
item.width = el.attr('data-gs-width')
|
||||||
|
monitors[item.ke+item.mid] = item
|
||||||
|
})
|
||||||
|
$user.details.monitorOrder=monitors;
|
||||||
|
$.ccio.cx({f:'monitorOrder',monitorOrder:monitors})
|
||||||
|
}
|
||||||
|
$.grid.e
|
||||||
|
.gridstack({
|
||||||
|
cellHeight: 80,
|
||||||
|
verticalMargin: 0,
|
||||||
|
})
|
||||||
|
.on('dragstop', function(event,ui){
|
||||||
|
setTimeout(function(){
|
||||||
|
$.grid.saveElementPositions()
|
||||||
|
},700)
|
||||||
|
})
|
||||||
|
.on('gsresizestop', $.grid.saveElementPositions);
|
||||||
|
})
|
|
@ -0,0 +1,612 @@
|
||||||
|
$.ccio.init=function(x,d,user,k){
|
||||||
|
if(!k){k={}};k.tmp='';
|
||||||
|
if(d&&d.user){
|
||||||
|
user=d.user
|
||||||
|
}
|
||||||
|
if(!user){
|
||||||
|
user=$user
|
||||||
|
}
|
||||||
|
switch(x){
|
||||||
|
case'cleanMon':
|
||||||
|
var acceptedFields = [
|
||||||
|
'mid',
|
||||||
|
'ke',
|
||||||
|
'name',
|
||||||
|
'shto',
|
||||||
|
'shfr',
|
||||||
|
'details',
|
||||||
|
'type',
|
||||||
|
'ext',
|
||||||
|
'protocol',
|
||||||
|
'host',
|
||||||
|
'path',
|
||||||
|
'port',
|
||||||
|
'fps',
|
||||||
|
'mode',
|
||||||
|
'width',
|
||||||
|
'height'
|
||||||
|
]
|
||||||
|
var row = {};
|
||||||
|
$.each(d,function(m,b){
|
||||||
|
if(acceptedFields.indexOf(m)>-1){
|
||||||
|
row[m]=b;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return row
|
||||||
|
break;
|
||||||
|
case'cleanMons':
|
||||||
|
if(d==='object'){
|
||||||
|
var arr={}
|
||||||
|
}else{
|
||||||
|
var arr=[]
|
||||||
|
}
|
||||||
|
$.each($.ccio.mon,function(n,v){
|
||||||
|
var row = $.ccio.init('cleanMon',v)
|
||||||
|
if(d==='object'){
|
||||||
|
arr[n]=row
|
||||||
|
}else{
|
||||||
|
arr.push(row)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return arr;
|
||||||
|
break;
|
||||||
|
case'location':
|
||||||
|
var url
|
||||||
|
if(d&&d.info&&d.info.URL){
|
||||||
|
url=d.info.URL
|
||||||
|
if(url.charAt(url.length-1)!=='/'){
|
||||||
|
url=url+'/'
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
url = $.ccio.libURL
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
break;
|
||||||
|
case'videoUrlBuild':
|
||||||
|
var url
|
||||||
|
if(d.href){
|
||||||
|
url = d.href
|
||||||
|
}else if(!d.href && d.hrefNoAuth){
|
||||||
|
url = $.ccio.init('location',user)+user.auth_token+d.hrefNoAuth
|
||||||
|
}
|
||||||
|
if(user!==$user&&url.charAt(0)==='/'){
|
||||||
|
url = $.ccio.init('location',user)+d.href.substring(1)
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
break;
|
||||||
|
case'videoHrefToDelete':
|
||||||
|
var urlSplit = d.split('?')
|
||||||
|
var url = urlSplit[0]+'/delete'
|
||||||
|
if(urlSplit[1])url += '?' + urlSplit[1]
|
||||||
|
return url
|
||||||
|
break;
|
||||||
|
case'videoHrefToUnread':
|
||||||
|
var urlSplit = d.split('?')
|
||||||
|
var url = urlSplit[0]+'/status/1'
|
||||||
|
if(urlSplit[1])url += '?' + urlSplit[1]
|
||||||
|
return url
|
||||||
|
break;
|
||||||
|
case'videoHrefToRead':
|
||||||
|
var urlSplit = d.split('?')
|
||||||
|
var url = urlSplit[0]+'/status/2'
|
||||||
|
if(urlSplit[1])url += '?' + urlSplit[1]
|
||||||
|
return url
|
||||||
|
break;
|
||||||
|
// case'streamWindow':
|
||||||
|
// return $('.monitor_item[mid="'+d.id+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"]')
|
||||||
|
// break;
|
||||||
|
case'streamMotionDetectRestart':
|
||||||
|
$.ccio.init('streamMotionDetectOff',d,user)
|
||||||
|
$.ccio.init('streamMotionDetectOn',d,user)
|
||||||
|
break;
|
||||||
|
case'streamMotionDetectOff':
|
||||||
|
d.mon.motionDetectionRunning = false
|
||||||
|
$('.monitor_item[mid="'+d.mid+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"]').find('.stream-detected-object,.zoomGlass').remove()
|
||||||
|
clearInterval(d.mon.motionDetector)
|
||||||
|
break;
|
||||||
|
case'streamMotionDetectOn':
|
||||||
|
switch(JSON.parse(d.mon.details).stream_type){
|
||||||
|
case'hls':case'flv':case'mp4':
|
||||||
|
//pass
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return $.ccio.init('note',{title:'Client-side Detector',text:'Could not be started. Only <b>FLV</b> and <b>HLS</b> can use this feature.',type:'error'});
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
d.mon.motionDetectorNextDraw = true
|
||||||
|
d.mon.motionDetectionRunning = true
|
||||||
|
$.ccio.snapshot(d,function(url){
|
||||||
|
$('#temp').html('<img>')
|
||||||
|
var img=$('#temp img')[0]
|
||||||
|
img.onload=function(){
|
||||||
|
var frameNumber = 0,
|
||||||
|
mainWindow = $('.monitor_item[mid="'+d.mid+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"]'),
|
||||||
|
blenderCanvas = mainWindow.find(".blenderCanvas"),
|
||||||
|
motionVision = mainWindow.find(".motionVision"),
|
||||||
|
streamElement = mainWindow.find('.stream-element'),
|
||||||
|
streamElementTag = streamElement[0],
|
||||||
|
lastURL = null,
|
||||||
|
currentImage = null,
|
||||||
|
f = [],
|
||||||
|
drawMatrices = {
|
||||||
|
e:mainWindow,
|
||||||
|
monitorDetails:JSON.parse(d.mon.details),
|
||||||
|
stream:streamElement,
|
||||||
|
streamObjects:mainWindow.find('.stream-objects'),
|
||||||
|
details:{
|
||||||
|
name:'clientSideDetection',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
widthRatio = streamElement.width() / img.width
|
||||||
|
heightRatio = streamElement.height() / img.height
|
||||||
|
drawMatrices.monitorDetails.detector_scale_x = img.width;
|
||||||
|
drawMatrices.monitorDetails.detector_scale_y = img.height;
|
||||||
|
function checkForMotion() {
|
||||||
|
blenderCanvas.width = img.width;
|
||||||
|
blenderCanvas.height = img.height;
|
||||||
|
blenderCanvasContext.drawImage(streamElementTag, 0, 0);
|
||||||
|
f[frameNumber] = blenderCanvasContext.getImageData(0, 0, blenderCanvas.width, blenderCanvas.height);
|
||||||
|
frameNumber = 0 == frameNumber ? 1 : 0;
|
||||||
|
currentImage = blenderCanvasContext.getImageData(0, 0, blenderCanvas.width, blenderCanvas.height);
|
||||||
|
foundPixels = [];
|
||||||
|
for (var currentImageLength = currentImage.data.length * 0.25, b = 0; b < currentImageLength;){
|
||||||
|
var pos = b * 4
|
||||||
|
currentImage.data[pos] = .5 * (255 - currentImage.data[pos]) + .5 * f[frameNumber].data[pos];
|
||||||
|
currentImage.data[pos + 1] = .5 * (255 - currentImage.data[pos + 1]) + .5 * f[frameNumber].data[pos + 1];
|
||||||
|
currentImage.data[pos + 2] = .5 * (255 - currentImage.data[pos + 2]) + .5 * f[frameNumber].data[pos + 2];
|
||||||
|
currentImage.data[pos + 3] = 255;
|
||||||
|
var score = (currentImage.data[pos] + currentImage.data[pos + 1] + currentImage.data[pos + 2]) / 3;
|
||||||
|
if(score>170){
|
||||||
|
var x = (pos / 4) % img.width;
|
||||||
|
var y = Math.floor((pos / 4) / img.width);
|
||||||
|
foundPixels.push([x,y])
|
||||||
|
}
|
||||||
|
b += 4;
|
||||||
|
}
|
||||||
|
var groupedPoints = Object.assign({},Cluster);
|
||||||
|
groupedPoints.iterations(25);
|
||||||
|
groupedPoints.data(foundPixels);
|
||||||
|
var groupedPoints = groupedPoints.clusters()
|
||||||
|
drawMatrices.details.matrices=[]
|
||||||
|
var mostHeight = 0;
|
||||||
|
var mostWidth = 0;
|
||||||
|
var mostWithMotion = null;
|
||||||
|
groupedPoints.forEach(function(v,n){
|
||||||
|
var matrix = {
|
||||||
|
topLeft:[img.width,img.height],
|
||||||
|
topRight:[0,img.height],
|
||||||
|
bottomRight:[0,0],
|
||||||
|
bottomLeft:[img.width,0],
|
||||||
|
}
|
||||||
|
v.points.forEach(function(b){
|
||||||
|
var x = b[0]
|
||||||
|
var y = b[1]
|
||||||
|
if(x<matrix.topLeft[0])matrix.topLeft[0]=x;
|
||||||
|
if(y<matrix.topLeft[1])matrix.topLeft[1]=y;
|
||||||
|
//Top Right point
|
||||||
|
if(x>matrix.topRight[0])matrix.topRight[0]=x;
|
||||||
|
if(y<matrix.topRight[1])matrix.topRight[1]=y;
|
||||||
|
//Bottom Right point
|
||||||
|
if(x>matrix.bottomRight[0])matrix.bottomRight[0]=x;
|
||||||
|
if(y>matrix.bottomRight[1])matrix.bottomRight[1]=y;
|
||||||
|
//Bottom Left point
|
||||||
|
if(x<matrix.bottomLeft[0])matrix.bottomLeft[0]=x;
|
||||||
|
if(y>matrix.bottomLeft[1])matrix.bottomLeft[1]=y;
|
||||||
|
})
|
||||||
|
matrix.x = matrix.topLeft[0];
|
||||||
|
matrix.y = matrix.topLeft[1];
|
||||||
|
matrix.width = matrix.topRight[0] - matrix.topLeft[0]
|
||||||
|
matrix.height = matrix.bottomLeft[1] - matrix.topLeft[1]
|
||||||
|
|
||||||
|
if(matrix.width>mostWidth&&matrix.height>mostHeight){
|
||||||
|
mostWidth = matrix.width;
|
||||||
|
mostHeight = matrix.height;
|
||||||
|
mostWithMotion = matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawMatrices.details.matrices.push(matrix)
|
||||||
|
})
|
||||||
|
$.ccio.magnifyStream({
|
||||||
|
p:mainWindow,
|
||||||
|
useCanvas:true,
|
||||||
|
zoomAmount:1,
|
||||||
|
auto:true,
|
||||||
|
animate:true,
|
||||||
|
pageX:((mostWithMotion.width / 2) + mostWithMotion.x) * widthRatio,
|
||||||
|
pageY:((mostWithMotion.height / 2) + mostWithMotion.y) * heightRatio
|
||||||
|
})
|
||||||
|
$.ccio.init('drawMatrices',drawMatrices)
|
||||||
|
if(d.mon.motionDetectorNextDraw===true){
|
||||||
|
clearTimeout(d.mon.motionDetectorNextDrawTimeout)
|
||||||
|
d.mon.motionDetectorNextDrawTimeout=setTimeout(function(){
|
||||||
|
d.mon.motionDetectorNextDraw = true;
|
||||||
|
},1000)
|
||||||
|
d.mon.motionDetectorNextDraw = false;
|
||||||
|
// console.log({
|
||||||
|
// p:mainWindow,
|
||||||
|
// pageX:((matrix.width / 2) + matrix.x) * widthRatio,
|
||||||
|
// pageY:((matrix.height / 2) + matrix.y) * heightRatio
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
return drawMatrices.details.matrices;
|
||||||
|
}
|
||||||
|
if(blenderCanvas.length === 0){
|
||||||
|
mainWindow.append('<div class="zoomGlass"><canvas class="blenderCanvas"></canvas></div>')
|
||||||
|
blenderCanvas = mainWindow.find(".blenderCanvas")
|
||||||
|
}
|
||||||
|
blenderCanvas = blenderCanvas[0];
|
||||||
|
var blenderCanvasContext = blenderCanvas.getContext("2d");
|
||||||
|
clearInterval(d.mon.motionDetector)
|
||||||
|
d.mon.motionDetector = setInterval(checkForMotion,2000)
|
||||||
|
}
|
||||||
|
img.src=url
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case'streamURL':
|
||||||
|
var streamURL
|
||||||
|
switch(JSON.parse(d.details).stream_type){
|
||||||
|
case'jpeg':
|
||||||
|
streamURL=$.ccio.init('location',user)+user.auth_token+'/jpeg/'+d.ke+'/'+d.mid+'/s.jpg'
|
||||||
|
break;
|
||||||
|
case'mjpeg':
|
||||||
|
streamURL=$.ccio.init('location',user)+user.auth_token+'/mjpeg/'+d.ke+'/'+d.mid
|
||||||
|
break;
|
||||||
|
case'hls':
|
||||||
|
streamURL=$.ccio.init('location',user)+user.auth_token+'/hls/'+d.ke+'/'+d.mid+'/s.m3u8'
|
||||||
|
break;
|
||||||
|
case'flv':
|
||||||
|
streamURL=$.ccio.init('location',user)+user.auth_token+'/flv/'+d.ke+'/'+d.mid+'/s.flv'
|
||||||
|
break;
|
||||||
|
case'h265':
|
||||||
|
streamURL=$.ccio.init('location',user)+user.auth_token+'/h265/'+d.ke+'/'+d.mid+'/s.hevc'
|
||||||
|
break;
|
||||||
|
case'mp4':
|
||||||
|
streamURL=$.ccio.init('location',user)+user.auth_token+'/mp4/'+d.ke+'/'+d.mid+'/s.mp4'
|
||||||
|
break;
|
||||||
|
case'b64':
|
||||||
|
streamURL='Websocket'
|
||||||
|
break;
|
||||||
|
case'pam':
|
||||||
|
streamURL='Websocket'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return streamURL
|
||||||
|
break;
|
||||||
|
case'humanReadMode':
|
||||||
|
switch(d){
|
||||||
|
case'idle':
|
||||||
|
k.mode=lang['Idle']
|
||||||
|
break;
|
||||||
|
case'stop':
|
||||||
|
k.mode=lang['Disabled']
|
||||||
|
break;
|
||||||
|
case'record':
|
||||||
|
k.mode=lang['Record']
|
||||||
|
break;
|
||||||
|
case'start':
|
||||||
|
k.mode=lang['Watch Only']
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return k.mode
|
||||||
|
break;
|
||||||
|
case'monitorInfo':
|
||||||
|
d.e=$('.glM'+d.mon.mid+user.auth_token);
|
||||||
|
if(JSON.parse(d.mon.details).vcodec!=='copy'&&d.mon.mode=='record'){
|
||||||
|
d.e.find('.monitor_not_record_copy').show()
|
||||||
|
}else{
|
||||||
|
d.e.find('.monitor_not_record_copy').hide()
|
||||||
|
}
|
||||||
|
d.e.find('.monitor_name').text(d.mon.name)
|
||||||
|
d.e.find('.monitor_mid').text(d.mon.mid)
|
||||||
|
d.e.find('.monitor_ext').text(d.mon.ext);
|
||||||
|
d.mode=$.ccio.init('humanReadMode',d.mon.mode,user)
|
||||||
|
d.e.find('.monitor_mode').text(d.mode)
|
||||||
|
d.e.find('.monitor_status').text(d.status)
|
||||||
|
d.e.attr('mode',d.mode)
|
||||||
|
d.e.find('.lamp').attr('title',d.mode)
|
||||||
|
break;
|
||||||
|
case'fullscreen':
|
||||||
|
if (d.requestFullscreen) {
|
||||||
|
d.requestFullscreen();
|
||||||
|
} else if (d.mozRequestFullScreen) {
|
||||||
|
d.mozRequestFullScreen();
|
||||||
|
} else if (d.webkitRequestFullscreen) {
|
||||||
|
d.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'drawPoints':
|
||||||
|
d.height=d.stream.height()
|
||||||
|
d.width=d.stream.width()
|
||||||
|
if(d.monitorDetails.detector_scale_x===''){d.monitorDetails.detector_scale_x=320}
|
||||||
|
if(d.monitorDetails.detector_scale_y===''){d.monitorDetails.detector_scale_y=240}
|
||||||
|
|
||||||
|
d.widthRatio=d.width/d.monitorDetails.detector_scale_x
|
||||||
|
d.heightRatio=d.height/d.monitorDetails.detector_scale_y
|
||||||
|
|
||||||
|
d.streamObjects.find('.stream-detected-point[name="'+d.details.name+'"]').remove()
|
||||||
|
d.tmp=''
|
||||||
|
$.each(d.details.points,function(n,v){
|
||||||
|
d.tmp+='<div class="stream-detected-point" name="'+d.details.name+'" style="height:'+1+'px;width:'+1+'px;top:'+(d.heightRatio*v.x)+'px;left:'+(d.widthRatio*v.y)+'px;">'
|
||||||
|
if(v.tag){d.tmp+='<span class="tag">'+v.tag+'</span>'}
|
||||||
|
d.tmp+='</div>'
|
||||||
|
})
|
||||||
|
d.streamObjects.append(d.tmp)
|
||||||
|
break;
|
||||||
|
case'drawMatrices':
|
||||||
|
d.height=d.stream.height()
|
||||||
|
d.width=d.stream.width()
|
||||||
|
if(d.monitorDetails.detector_scale_x===''){d.monitorDetails.detector_scale_x=320}
|
||||||
|
if(d.monitorDetails.detector_scale_y===''){d.monitorDetails.detector_scale_y=240}
|
||||||
|
|
||||||
|
d.widthRatio=d.width/d.monitorDetails.detector_scale_x
|
||||||
|
d.heightRatio=d.height/d.monitorDetails.detector_scale_y
|
||||||
|
|
||||||
|
d.streamObjects.find('.stream-detected-object[name="'+d.details.name+'"]').remove()
|
||||||
|
d.tmp=''
|
||||||
|
$.each(d.details.matrices,function(n,v){
|
||||||
|
d.tmp+='<div class="stream-detected-object" name="'+d.details.name+'" style="height:'+(d.heightRatio*v.height)+'px;width:'+(d.widthRatio*v.width)+'px;top:'+(d.heightRatio*v.y)+'px;left:'+(d.widthRatio*v.x)+'px;">'
|
||||||
|
if(v.tag){d.tmp+='<span class="tag">'+v.tag+'</span>'}
|
||||||
|
d.tmp+='</div>'
|
||||||
|
})
|
||||||
|
d.streamObjects.append(d.tmp)
|
||||||
|
break;
|
||||||
|
case'clearTimers':
|
||||||
|
if(!d.mid){d.mid=d.id}
|
||||||
|
if($.ccio.mon[d.ke+d.mid+user.auth_token]){
|
||||||
|
clearTimeout($.ccio.mon[d.ke+d.mid+user.auth_token]._signal);
|
||||||
|
clearInterval($.ccio.mon[d.ke+d.mid+user.auth_token].hlsGarbageCollectorTimer)
|
||||||
|
clearTimeout($.ccio.mon[d.ke+d.mid+user.auth_token].jpegInterval);
|
||||||
|
clearInterval($.ccio.mon[d.ke+d.mid+user.auth_token].signal);
|
||||||
|
clearInterval($.ccio.mon[d.ke+d.mid+user.auth_token].m3uCheck);
|
||||||
|
if($.ccio.mon[d.ke+d.mid+user.auth_token].Base64 && $.ccio.mon[d.ke+d.mid+user.auth_token].Base64.connected){
|
||||||
|
$.ccio.mon[d.ke+d.mid+user.auth_token].Base64.disconnect()
|
||||||
|
}
|
||||||
|
if($.ccio.mon[d.ke+d.mid+user.auth_token].Poseidon){
|
||||||
|
$.ccio.mon[d.ke+d.mid+user.auth_token].Poseidon.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'note':
|
||||||
|
k.o=$.ccio.op().switches
|
||||||
|
if(k.o&&k.o.notifyHide!==1){
|
||||||
|
new PNotify(d)
|
||||||
|
if(user.details.audio_note && user.details.audio_note !== ''){
|
||||||
|
var audio = new Audio('libs/audio/'+user.details.audio_note);
|
||||||
|
audio.play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'monGroup':
|
||||||
|
$.ccio.mon_groups={};
|
||||||
|
$.each($.ccio.mon,function(n,v,x){
|
||||||
|
if(typeof v.details==='string'){
|
||||||
|
k.d=JSON.parse(v.details)
|
||||||
|
}else{
|
||||||
|
k.d=v.details
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
k.groups=JSON.parse(k.d.groups)
|
||||||
|
$.each(k.groups,function(m,b){
|
||||||
|
if(!$.ccio.mon_groups[b])$.ccio.mon_groups[b]={}
|
||||||
|
$.ccio.mon_groups[b][v.mid]=v;
|
||||||
|
})
|
||||||
|
}catch(er){
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return $.ccio.mon_groups;
|
||||||
|
break;
|
||||||
|
case'closeVideo':
|
||||||
|
var el = $('#monitor_live_'+d.mid+user.auth_token)
|
||||||
|
var video = el.find('video')
|
||||||
|
if(video.length === 1){
|
||||||
|
if(!video[0].paused){
|
||||||
|
video[0].onerror = function(){}
|
||||||
|
video[0].pause()
|
||||||
|
}
|
||||||
|
video.prop('src','');
|
||||||
|
video.find('source').remove();
|
||||||
|
video.remove();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'jpegModeStop':
|
||||||
|
clearTimeout($.ccio.mon[d.ke+d.mid+user.auth_token].jpegInterval);
|
||||||
|
delete($.ccio.mon[d.ke+d.mid+user.auth_token].jpegInterval);
|
||||||
|
$('#monitor_live_'+d.mid+user.auth_token+' .stream-element').unbind('load')
|
||||||
|
break;
|
||||||
|
case'jpegMode':
|
||||||
|
if(d.watch===1){
|
||||||
|
k=JSON.parse(d.details);
|
||||||
|
k.jpegInterval=parseFloat(k.jpegInterval);
|
||||||
|
if(!k.jpegInterval||k.jpegInterval===''||isNaN(k.jpegInterval)){k.jpegInterval=1}
|
||||||
|
$.ccio.tm('stream-element',$.ccio.mon[d.ke+d.mid+user.auth_token]);
|
||||||
|
k.e=$('#monitor_live_'+d.mid+user.auth_token+' .stream-element');
|
||||||
|
$.ccio.init('jpegModeStop',d,user);
|
||||||
|
k.run=function(){
|
||||||
|
k.e.attr('src',$.ccio.init('location',user)+user.auth_token+'/jpeg/'+d.ke+'/'+d.mid+'/s.jpg?time='+(new Date()).getTime())
|
||||||
|
}
|
||||||
|
k.e.load(function(){
|
||||||
|
$.ccio.mon[d.ke+d.mid+user.auth_token].jpegInterval=setTimeout(k.run,1000/k.jpegInterval);
|
||||||
|
}).error(function(){
|
||||||
|
$.ccio.mon[d.ke+d.mid+user.auth_token].jpegInterval=setTimeout(k.run,1000/k.jpegInterval);
|
||||||
|
})
|
||||||
|
k.run()
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case'jpegModeAll':
|
||||||
|
$.each($.ccio.mon,function(n,v){
|
||||||
|
$.ccio.init('jpegMode',v,user)
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case'getLocation':
|
||||||
|
var l = document.createElement("a");
|
||||||
|
l.href = d;
|
||||||
|
return l;
|
||||||
|
break;
|
||||||
|
case 'ls'://livestamp all
|
||||||
|
g={e:jQuery('.livestamp')};
|
||||||
|
g.e.each(function(){g.v=jQuery(this),g.t=g.v.attr('title');if(!g.t){return};g.v.toggleClass('livestamp livestamped').attr('title',$.ccio.init('t',g.t,user)).livestamp(g.t);})
|
||||||
|
return g.e
|
||||||
|
break;
|
||||||
|
case't'://format time
|
||||||
|
if(!d){d=new Date();}
|
||||||
|
return $.ccio.timeObject(d).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
break;
|
||||||
|
case'th'://format time hy
|
||||||
|
if(!d){d=new Date();}
|
||||||
|
return $.ccio.timeObject(d).format('YYYY-MM-DDTHH:mm:ss')
|
||||||
|
break;
|
||||||
|
case'tf'://time to filename
|
||||||
|
if(!d){d=new Date();}
|
||||||
|
return $.ccio.timeObject(d).format('YYYY-MM-DDTHH-mm-ss')
|
||||||
|
break;
|
||||||
|
case'fn'://row to filename
|
||||||
|
return $.ccio.init('tf',d.time,user)+'.'+d.ext
|
||||||
|
break;
|
||||||
|
case'filters':
|
||||||
|
k.tmp='<option value="" selected>'+lang['Add New']+'</option>';
|
||||||
|
$.each(user.details.filters,function(n,v){
|
||||||
|
k.tmp+='<option value="'+v.id+'">'+v.name+'</option>'
|
||||||
|
});
|
||||||
|
$('#saved_filters').html(k.tmp)
|
||||||
|
break;
|
||||||
|
case'id':
|
||||||
|
$('.usermail').html(d.mail)
|
||||||
|
try{k.d=JSON.parse(d.details);}catch(er){k.d=d.details;}
|
||||||
|
try{user.mon_groups=JSON.parse(k.d.mon_groups);}catch(er){}
|
||||||
|
if(!user.mon_groups)user.mon_groups={};
|
||||||
|
$.sM.reDrawMonGroups()
|
||||||
|
$.each(user,function(n,v){$.sM.e.find('[name="'+n+'"]').val(v).change()})
|
||||||
|
$.each(k.d,function(n,v){$.sM.e.find('[detail="'+n+'"]').val(v).change()})
|
||||||
|
$.gR.drawList();
|
||||||
|
$.ccio.pm('link-set',k.d.links,null,user)
|
||||||
|
break;
|
||||||
|
case'jsontoblock'://draw json as block
|
||||||
|
if(d instanceof Object){
|
||||||
|
$.each(d,function(n,v){
|
||||||
|
k.tmp+='<div>';
|
||||||
|
k.tmp+='<b>'+n+'</b> : '+$.ccio.init('jsontoblock',v,user);
|
||||||
|
k.tmp+='</div>';
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
k.tmp+='<span>';
|
||||||
|
k.tmp+=d;
|
||||||
|
k.tmp+='</span>';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'url':
|
||||||
|
var porty
|
||||||
|
if(d.port && d.port !== ''){
|
||||||
|
porty = ':' + d.port
|
||||||
|
}else{
|
||||||
|
porty = ''
|
||||||
|
}
|
||||||
|
d.url = d.protocol + '://' + d.host + porty
|
||||||
|
return d.url
|
||||||
|
break;
|
||||||
|
case'data-video':
|
||||||
|
if(!d){
|
||||||
|
$('[data-mid]').each(function(n,v){
|
||||||
|
v=$(v);v.attr('mid',v.attr('data-mid'))
|
||||||
|
});
|
||||||
|
$('[data-ke]').each(function(n,v){
|
||||||
|
v=$(v);v.attr('ke',v.attr('data-ke'))
|
||||||
|
});
|
||||||
|
$('[data-file]').each(function(n,v){
|
||||||
|
v=$(v);v.attr('file',v.attr('data-file'))
|
||||||
|
});
|
||||||
|
$('[data-status]').each(function(n,v){
|
||||||
|
v=$(v);v.attr('status',v.attr('data-status'))
|
||||||
|
});
|
||||||
|
$('[data-auth]').each(function(n,v){
|
||||||
|
v=$(v);v.attr('auth',v.attr('data-auth'))
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
$('[data-ke="'+d.ke+'"][data-mid="'+d.mid+'"][data-file="'+d.filename+'"][auth="'+user.auth_token+'"]').attr('mid',d.mid).attr('ke',d.ke).attr('status',d.status).attr('file',d.filename).attr('auth',user.auth_token);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'signal':
|
||||||
|
d.mon=$.ccio.mon[d.ke+d.id+user.auth_token];d.e=$('#monitor_live_'+d.id+user.auth_token+' .signal').addClass('btn-success').removeClass('btn-danger');d.signal=parseFloat(JSON.parse(d.mon.details).signal_check);
|
||||||
|
if(!d.signal||d.signal==NaN){d.signal=10;};d.signal=d.signal*1000*60;
|
||||||
|
clearTimeout($.ccio.mon[d.ke+d.id+user.auth_token]._signal);$.ccio.mon[d.ke+d.id+user.auth_token]._signal=setTimeout(function(){d.e.addClass('btn-danger').removeClass('btn-success');},d.signal)
|
||||||
|
break;
|
||||||
|
case'signal-check':
|
||||||
|
try{
|
||||||
|
d.mon=$.ccio.mon[d.ke+d.id+user.auth_token];d.p=$('#monitor_live_'+d.id+user.auth_token);
|
||||||
|
try{d.d=JSON.parse(d.mon.details)}catch(er){d.d=d.mon.details;}
|
||||||
|
d.check={c:0};
|
||||||
|
d.fn=function(){
|
||||||
|
if(!d.speed){d.speed=1000}
|
||||||
|
switch(d.d.stream_type){
|
||||||
|
case'b64':case'h265':
|
||||||
|
d.p.resize()
|
||||||
|
break;
|
||||||
|
case'hls':case'flv':case'mp4':
|
||||||
|
if(d.p.find('video')[0].paused){
|
||||||
|
if(d.d.signal_check_log==1){
|
||||||
|
d.log={type:'Stream Check',msg:lang.clientStreamFailedattemptingReconnect}
|
||||||
|
$.ccio.tm(4,d,'#logs,.monitor_item[mid="'+d.id+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"] .logs')
|
||||||
|
}
|
||||||
|
$.ccio.cx({f:'monitor',ff:'watch_on',id:d.id},user);
|
||||||
|
}else{
|
||||||
|
if(d.d.signal_check_log==1){
|
||||||
|
d.log={type:'Stream Check',msg:'Success'}
|
||||||
|
$.ccio.tm(4,d,'#logs,.monitor_item[mid="'+d.id+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"] .logs')
|
||||||
|
}
|
||||||
|
$.ccio.init('signal',d,user);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if($.ccio.op().jpeg_on===true){return}
|
||||||
|
$.ccio.snapshot(d,function(url){
|
||||||
|
d.check.f=url;
|
||||||
|
setTimeout(function(){
|
||||||
|
$.ccio.snapshot(d,function(url){
|
||||||
|
if(d.check.f===url){
|
||||||
|
if(d.check.c<3){
|
||||||
|
++d.check.c;
|
||||||
|
setTimeout(function(){
|
||||||
|
d.fn();
|
||||||
|
},d.speed)
|
||||||
|
}else{
|
||||||
|
if(d.d.signal_check_log==1){
|
||||||
|
d.log={type:'Stream Check',msg:'Client side ctream check failed, attempting reconnect.'}
|
||||||
|
$.ccio.tm(4,d,'#logs,.monitor_item[mid="'+d.id+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"] .logs')
|
||||||
|
}
|
||||||
|
delete(d.check)
|
||||||
|
$.ccio.cx({f:'monitor',ff:'watch_on',id:d.id},user);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(d.d.signal_check_log==1){
|
||||||
|
d.log={type:'Stream Check',msg:'Success'}
|
||||||
|
$.ccio.tm(4,d,'#logs,.monitor_item[mid="'+d.id+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"] .logs')
|
||||||
|
}
|
||||||
|
delete(d.check)
|
||||||
|
$.ccio.init('signal',d,user);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},d.speed)
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.fn();
|
||||||
|
}catch(er){
|
||||||
|
er=er.stack;
|
||||||
|
d.in=function(x){return er.indexOf(x)>-1}
|
||||||
|
switch(true){
|
||||||
|
case d.in("The HTMLImageElement provided is in the 'broken' state."):
|
||||||
|
delete(d.check)
|
||||||
|
$.ccio.cx({f:'monitor',ff:'watch_on',id:d.id},user);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$.ccio.log('signal-check',er)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
clearInterval($.ccio.mon[d.ke+d.id+user.auth_token].signal);delete($.ccio.mon[d.ke+d.id+user.auth_token].signal);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return k.tmp;
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//log viewer
|
||||||
|
$.log = {
|
||||||
|
e : $('#logs_modal'),
|
||||||
|
lm : $('#log_monitors'),
|
||||||
|
dateRange : $('#logs_daterange'),
|
||||||
|
loaded : {}
|
||||||
|
}
|
||||||
|
$.log.dateRange.daterangepicker({
|
||||||
|
startDate:$.ccio.timeObject().subtract(moment.duration("5:00:00")),
|
||||||
|
endDate:$.ccio.timeObject().add(moment.duration("24:00:00")),
|
||||||
|
timePicker: true,
|
||||||
|
timePicker24Hour: true,
|
||||||
|
timePickerSeconds: true,
|
||||||
|
timePickerIncrement: 30,
|
||||||
|
locale: {
|
||||||
|
format: 'MM/DD/YYYY h:mm A'
|
||||||
|
}
|
||||||
|
},function(start, end, label){
|
||||||
|
//change daterange
|
||||||
|
$.log.lm.change()
|
||||||
|
});
|
||||||
|
$.log.table = $.log.e.find('table')
|
||||||
|
$.log.e.on('shown.bs.modal', function () {
|
||||||
|
$.log.lm.find('option:not(.hard)').remove()
|
||||||
|
$.each($.ccio.mon,function(n,v){
|
||||||
|
v.id = v.mid
|
||||||
|
$.ccio.tm('option',v,'#log_monitors')
|
||||||
|
})
|
||||||
|
$.log.lm.change()
|
||||||
|
})
|
||||||
|
$.log.lm.change(function(){
|
||||||
|
e = {}
|
||||||
|
e.v = $(this).val();
|
||||||
|
e.urlSelector = e.v+'';
|
||||||
|
if(e.v === 'all'){
|
||||||
|
e.urlSelector = ''
|
||||||
|
}
|
||||||
|
e.dateRange = $.log.dateRange.data('daterangepicker');
|
||||||
|
$.log.loaded.startDate = e.dateRange.startDate
|
||||||
|
$.log.loaded.endDate = e.dateRange.endDate
|
||||||
|
var url = $.ccio.init('location',$user)+$user.auth_token+'/logs/'+$user.ke+'/'+e.urlSelector+'?start='+$.ccio.init('th',$.log.loaded.startDate)+'&end='+$.ccio.init('th',$.log.loaded.endDate)
|
||||||
|
$.get(url,function(d){
|
||||||
|
$.log.loaded.url = url
|
||||||
|
$.log.loaded.query = e.v
|
||||||
|
$.log.loaded.rows = d
|
||||||
|
e.tmp='';
|
||||||
|
if(d.length === 0){
|
||||||
|
e.tmp = '<tr class="text-center"><td>'+lang.NoLogsFoundForDateRange+'</td></tr>'
|
||||||
|
}else{
|
||||||
|
$.each(d,function(n,v){
|
||||||
|
e.tmp+='<tr class="search-row"><td title="'+v.time+'" class="livestamp"></td><td>'+v.time+'</td><td>'+v.mid+'</td><td>'+$.ccio.init('jsontoblock',v.info)+'</td></tr>'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$.log.table.find('tbody').html(e.tmp)
|
||||||
|
// $.log.table.bootstrapTable()
|
||||||
|
$.ccio.init('ls')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
$.log.e.find('[download]').click(function(){
|
||||||
|
$.ccio.downloadJSON($.log.loaded,'Shinobi_Logs_'+(new Date())+'.json',{
|
||||||
|
title : 'No Logs Found',
|
||||||
|
text : 'No file will be downloaded.',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,773 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
|
||||||
|
//Monitor Editor
|
||||||
|
$.aM={e:$('#add_monitor'),monitorsForCopy:$('#copy_settings_monitors')};
|
||||||
|
$.aM.f=$.aM.e.find('form')
|
||||||
|
$.aM.channels=$('#monSectionStreamChannels')
|
||||||
|
$.aM.maps=$('#monSectionInputMaps')
|
||||||
|
$.aM.e.find('.follow-list ul').affix();
|
||||||
|
$.each($.ccio.definitions["Monitor Settings"].blocks,function(n,v){
|
||||||
|
$.each(v.info,function(m,b){
|
||||||
|
if(!b.name){
|
||||||
|
console.log(b)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(b.name.indexOf('detail=')>-1){
|
||||||
|
b.name=b.name.replace('detail=','')
|
||||||
|
v.element=$.aM.e.find('[detail="'+b.name+'"]')
|
||||||
|
}else{
|
||||||
|
v.element=$.aM.e.find('[name="'+b.name+'"]')
|
||||||
|
}
|
||||||
|
v.parent=v.element.parents('.form-group').find('label div:first-child span')
|
||||||
|
v.parent.find('small').remove()
|
||||||
|
v.parent.append('<small class="hover">'+b.description+'</small>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
$.aM.generateDefaultMonitorSettings=function(){
|
||||||
|
return {
|
||||||
|
"mode": "start",
|
||||||
|
"mid": $.ccio.gid(),
|
||||||
|
"name": "Some Stream",
|
||||||
|
"type": "h264",
|
||||||
|
"protocol": "rtsp",
|
||||||
|
"host": "",
|
||||||
|
"port": "",
|
||||||
|
"path": "",
|
||||||
|
"ext": "mp4",
|
||||||
|
"fps": "1",
|
||||||
|
"width": "640",
|
||||||
|
"height": "480",
|
||||||
|
"details": JSON.stringify({
|
||||||
|
"fatal_max": "0",
|
||||||
|
"notes": "",
|
||||||
|
"dir": "",
|
||||||
|
"auto_host_enable": "1",
|
||||||
|
"auto_host": "",
|
||||||
|
"rtsp_transport": "tcp",
|
||||||
|
"muser": "",
|
||||||
|
"mpass": "",
|
||||||
|
"port_force": "0",
|
||||||
|
"aduration": "1000000",
|
||||||
|
"probesize": "1000000",
|
||||||
|
"stream_loop": "0",
|
||||||
|
"sfps": "",
|
||||||
|
"accelerator": "0",
|
||||||
|
"hwaccel": "auto",
|
||||||
|
"hwaccel_vcodec": "",
|
||||||
|
"hwaccel_device": "",
|
||||||
|
"stream_type": "mp4",
|
||||||
|
"stream_flv_type": "ws",
|
||||||
|
"stream_mjpeg_clients": "",
|
||||||
|
"stream_vcodec": "copy",
|
||||||
|
"stream_acodec": "no",
|
||||||
|
"hls_time": "2",
|
||||||
|
"preset_stream": "ultrafast",
|
||||||
|
"hls_list_size": "3",
|
||||||
|
"signal_check": "10",
|
||||||
|
"signal_check_log": "0",
|
||||||
|
"stream_quality": "15",
|
||||||
|
"stream_fps": "2",
|
||||||
|
"stream_scale_x": "",
|
||||||
|
"stream_scale_y": "",
|
||||||
|
"rotate_stream": "no",
|
||||||
|
"svf": "",
|
||||||
|
"rtmp_vcodec": "h264",
|
||||||
|
"rtmp_acodec": "aac",
|
||||||
|
"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": "tr",
|
||||||
|
"snap": "0",
|
||||||
|
"snap_fps": "",
|
||||||
|
"snap_scale_x": "",
|
||||||
|
"snap_scale_y": "",
|
||||||
|
"snap_vf": "",
|
||||||
|
"rawh264": "0",
|
||||||
|
"rawh264_vcodec": "copy",
|
||||||
|
"rawh264_acodec": "",
|
||||||
|
"rawh264_fps": "",
|
||||||
|
"rawh264_scale_x": "",
|
||||||
|
"rawh264_scale_y": "",
|
||||||
|
"rawh264_crf": "",
|
||||||
|
"rawh264_vf": "",
|
||||||
|
"vcodec": "copy",
|
||||||
|
"crf": "1",
|
||||||
|
"preset_record": "",
|
||||||
|
"acodec": "no",
|
||||||
|
"dqf": "0",
|
||||||
|
"cutoff": "15",
|
||||||
|
"rotate_record": "no",
|
||||||
|
"vf": "",
|
||||||
|
"timestamp": "0",
|
||||||
|
"timestamp_font": "",
|
||||||
|
"timestamp_font_size": "10",
|
||||||
|
"timestamp_color": "white",
|
||||||
|
"timestamp_box_color": "0x00000000@1",
|
||||||
|
"timestamp_x": "(w-tw)/2",
|
||||||
|
"timestamp_y": "0",
|
||||||
|
"watermark": "0",
|
||||||
|
"watermark_location": "",
|
||||||
|
"watermark_position": "tr",
|
||||||
|
"cust_input": "",
|
||||||
|
"cust_snap": "",
|
||||||
|
"cust_rawh264": "",
|
||||||
|
"cust_detect": "",
|
||||||
|
"cust_stream": "",
|
||||||
|
"cust_stream_server": "",
|
||||||
|
"cust_record": "",
|
||||||
|
"custom_output": "",
|
||||||
|
"detector": "0",
|
||||||
|
"detector_pam": "1",
|
||||||
|
"detector_webhook": "0",
|
||||||
|
"detector_webhook_url": "",
|
||||||
|
"detector_command_enable": "0",
|
||||||
|
"detector_command": "",
|
||||||
|
"detector_command_timeout": "",
|
||||||
|
"detector_lock_timeout": "",
|
||||||
|
"detector_save": "0",
|
||||||
|
"detector_frame_save": "0",
|
||||||
|
"detector_mail": "0",
|
||||||
|
"detector_mail_timeout": "",
|
||||||
|
"detector_record_method": "sip",
|
||||||
|
"detector_trigger": "1",
|
||||||
|
"detector_trigger_record_fps": "",
|
||||||
|
"detector_timeout": "10",
|
||||||
|
"watchdog_reset": "0",
|
||||||
|
"detector_delete_motionless_videos": "0",
|
||||||
|
"detector_send_frames": "1",
|
||||||
|
"detector_region_of_interest": "0",
|
||||||
|
"detector_fps": "",
|
||||||
|
"detector_scale_x": "640",
|
||||||
|
"detector_scale_y": "480",
|
||||||
|
"detector_use_motion": "1",
|
||||||
|
"detector_use_detect_object": "0",
|
||||||
|
"detector_frame": "0",
|
||||||
|
"detector_sensitivity": "",
|
||||||
|
"detector_max_sensitivity": "",
|
||||||
|
"detector_threshold": "1",
|
||||||
|
"detector_color_threshold": "",
|
||||||
|
"cords": "[]",
|
||||||
|
"detector_buffer_vcodec": "auto",
|
||||||
|
"detector_buffer_fps": "",
|
||||||
|
"detector_buffer_hls_time": "",
|
||||||
|
"detector_buffer_hls_list_size": "",
|
||||||
|
"detector_buffer_start_number": "",
|
||||||
|
"detector_buffer_live_start_index": "",
|
||||||
|
"detector_lisence_plate": "0",
|
||||||
|
"detector_lisence_plate_country": "us",
|
||||||
|
"detector_notrigger": "0",
|
||||||
|
"detector_notrigger_mail": "0",
|
||||||
|
"detector_notrigger_timeout": "",
|
||||||
|
"control": "0",
|
||||||
|
"control_base_url": "",
|
||||||
|
"control_stop": "0",
|
||||||
|
"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": "",
|
||||||
|
"tv_channel": "0",
|
||||||
|
"groups": "[]",
|
||||||
|
"loglevel": "warning",
|
||||||
|
"sqllog": "0",
|
||||||
|
"detector_cascades": ""
|
||||||
|
}),
|
||||||
|
"shto": "[]",
|
||||||
|
"shfr": "[]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.aM.drawList=function(){
|
||||||
|
e={list:$.aM.e.find('.follow-list ul'),html:''}
|
||||||
|
$.aM.e.find('[section]:visible').each(function(n,v){
|
||||||
|
e.e=$(v)
|
||||||
|
e.id = e.e.attr('id');
|
||||||
|
e.title = e.e.find('h4').first().html();
|
||||||
|
var div = document.createElement('div');
|
||||||
|
div.innerHTML = e.title;
|
||||||
|
var elements = div.getElementsByTagName('a');
|
||||||
|
while (elements[0])
|
||||||
|
elements[0].parentNode.removeChild(elements[0])
|
||||||
|
var elements = div.getElementsByTagName('small');
|
||||||
|
while (elements[0])
|
||||||
|
elements[0].parentNode.removeChild(elements[0])
|
||||||
|
var repl = div.innerHTML;
|
||||||
|
e.html += '<li><a class="scrollTo" href="#'+e.id+'" scrollToParent="#add_monitor .modal-body">'+repl+'</a></li>'
|
||||||
|
})
|
||||||
|
e.list.html(e.html)
|
||||||
|
}
|
||||||
|
$.aM.import=function(e){
|
||||||
|
$.get($.ccio.init('location',$user)+$user.auth_token+'/hls/'+e.values.ke+'/'+e.values.mid+'/detectorStream.m3u8',function(data){
|
||||||
|
$('#monEditBufferPreview').html(data)
|
||||||
|
})
|
||||||
|
$.aM.e.find('.edit_id').text(e.values.mid);
|
||||||
|
$.aM.e.attr('mid',e.values.mid).attr('ke',e.values.ke).attr('auth',e.auth)
|
||||||
|
$.each(e.values,function(n,v){
|
||||||
|
$.aM.e.find('[name="'+n+'"]').val(v).change()
|
||||||
|
})
|
||||||
|
e.ss=JSON.parse(e.values.details);
|
||||||
|
//get maps
|
||||||
|
$.aM.maps.empty()
|
||||||
|
if(e.ss.input_maps&&e.ss.input_maps!==''){
|
||||||
|
var input_maps
|
||||||
|
try{
|
||||||
|
input_maps = JSON.parse(e.ss.input_maps)
|
||||||
|
}catch(er){
|
||||||
|
input_maps = e.ss.input_maps;
|
||||||
|
}
|
||||||
|
var mapContainers = $('[input-mapping]')
|
||||||
|
if(input_maps.length>0){
|
||||||
|
mapContainers.show()
|
||||||
|
$.each(input_maps,function(n,v){
|
||||||
|
var tempID = $.ccio.tm('input-map')
|
||||||
|
var parent = $('#monSectionMap'+tempID)
|
||||||
|
$.each(v,function(m,b){
|
||||||
|
parent.find('[map-detail="'+m+'"]').val(b).change()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
mapContainers.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//get channels
|
||||||
|
$.aM.channels.empty()
|
||||||
|
if(e.ss.stream_channels&&e.ss.stream_channels!==''){
|
||||||
|
var stream_channels
|
||||||
|
try{
|
||||||
|
stream_channels = JSON.parse(e.ss.stream_channels)
|
||||||
|
}catch(er){
|
||||||
|
stream_channels = e.ss.stream_channels;
|
||||||
|
}
|
||||||
|
$.each(stream_channels,function(n,v){
|
||||||
|
var tempID = $.ccio.tm('stream-channel')
|
||||||
|
var parent = $('#monSectionChannel'+tempID)
|
||||||
|
$.each(v,function(m,b){
|
||||||
|
parent.find('[channel-detail="'+m+'"]').val(b)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//get map choices for outputs
|
||||||
|
$('[input-mapping] .choices').empty()
|
||||||
|
if(e.ss.input_map_choices&&e.ss.input_map_choices!==''){
|
||||||
|
var input_map_choices
|
||||||
|
try{
|
||||||
|
input_map_choices = JSON.parse(e.ss.input_map_choices)
|
||||||
|
}catch(er){
|
||||||
|
input_map_choices = e.ss.input_map_choices;
|
||||||
|
}
|
||||||
|
$.each(input_map_choices,function(n,v){
|
||||||
|
$.each(v,function(m,b){
|
||||||
|
var parent = $('[input-mapping="'+n+'"] .choices')
|
||||||
|
$.ccio.tm('input-map-selector',b,parent)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$.aM.e.find('[detail]').each(function(n,v){
|
||||||
|
v=$(v).attr('detail');if(!e.ss[v]){e.ss[v]=''}
|
||||||
|
})
|
||||||
|
$.each(e.ss,function(n,v){
|
||||||
|
var theVal = v;
|
||||||
|
if(v instanceof Object){
|
||||||
|
theVal = JSON.stringify(v);
|
||||||
|
}
|
||||||
|
$.aM.e.find('[detail="'+n+'"]').val(theVal).change();
|
||||||
|
});
|
||||||
|
$.each(e.ss,function(n,v){
|
||||||
|
try{
|
||||||
|
var variable=JSON.parse(v)
|
||||||
|
}catch(err){
|
||||||
|
var variable=v
|
||||||
|
}
|
||||||
|
if(variable instanceof Object){
|
||||||
|
$('[detailContainer="'+n+'"][detailObject]').prop('checked',false)
|
||||||
|
$('[detailContainer="'+n+'"][detailObject]').parents('.mdl-js-switch').removeClass('is-checked')
|
||||||
|
if(variable instanceof Array){
|
||||||
|
$.each(variable,function(m,b,parentOfObject){
|
||||||
|
$('[detailContainer="'+n+'"][detailObject="'+b+'"]').prop('checked',true)
|
||||||
|
parentOfObject=$('[detailContainer="'+n+'"][detailObject="'+b+'"]').parents('.mdl-js-switch')
|
||||||
|
parentOfObject.addClass('is-checked')
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
$.each(variable,function(m,b){
|
||||||
|
if(typeof b ==='string'){
|
||||||
|
$('[detailContainer="'+n+'"][detailObject="'+m+'"]').val(b).change()
|
||||||
|
}else{
|
||||||
|
$('[detailContainer="'+n+'"][detailObject="'+m+'"]').prop('checked',true)
|
||||||
|
parentOfObject=$('[detailContainer="'+n+'"][detailObject="'+m+'"]').parents('.mdl-js-switch')
|
||||||
|
parentOfObject.addClass('is-checked')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
try{
|
||||||
|
$.each(['groups','group_detector'],function(m,b){
|
||||||
|
var tmp=''
|
||||||
|
$.each($user.mon_groups,function(n,v){
|
||||||
|
tmp+='<li class="mdl-list__item">';
|
||||||
|
tmp+='<span class="mdl-list__item-primary-content">';
|
||||||
|
tmp+=v.name;
|
||||||
|
tmp+='</span>';
|
||||||
|
tmp+='<span class="mdl-list__item-secondary-action">';
|
||||||
|
tmp+='<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">';
|
||||||
|
tmp+='<input type="checkbox" '+b+' value="'+v.id+'" class="mdl-switch__input"';
|
||||||
|
if(!e.ss[b]){
|
||||||
|
e.ss[b]=[]
|
||||||
|
}
|
||||||
|
if(e.ss[b].indexOf(v.id)>-1){tmp+=' checked';}
|
||||||
|
tmp+=' />';
|
||||||
|
tmp+='</label>';
|
||||||
|
tmp+='</span>';
|
||||||
|
tmp+='</li>';
|
||||||
|
})
|
||||||
|
$('#monitor_'+b).html(tmp)
|
||||||
|
})
|
||||||
|
componentHandler.upgradeAllRegistered()
|
||||||
|
}catch(er){
|
||||||
|
console.log(er)
|
||||||
|
//no group, this 'try' will be removed in future.
|
||||||
|
};
|
||||||
|
$('#copy_settings').val('0').change()
|
||||||
|
var tmp = '';
|
||||||
|
$.each($.ccio.mon,function(n,v){
|
||||||
|
if(v.ke === $user.ke){
|
||||||
|
tmp += $.ccio.tm('option',{auth_token:$user.auth_token,id:v.mid,name:v.name},null,$user);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.aM.monitorsForCopy.find('optgroup').html(tmp)
|
||||||
|
setTimeout(function(){$.aM.drawList()},1000)
|
||||||
|
}
|
||||||
|
//parse "Automatic" field in "Input" Section
|
||||||
|
$.aM.e.on('change','.auto_host_fill input,.auto_host_fill select',function(e){
|
||||||
|
var theSwitch = $.aM.e.find('[detail="auto_host_enable"]').val()
|
||||||
|
if(!theSwitch||theSwitch===''){
|
||||||
|
theSwitch='1'
|
||||||
|
}
|
||||||
|
if(theSwitch==='1'){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if($.aM.e.find('[name="host"]').val() !== ''){
|
||||||
|
$.aM.e.find('[detail="auto_host"]').val($.aM.buildMonitorURL())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.aM.e.on('change','[detail="auto_host"]',function(e){
|
||||||
|
var isRTSP = false
|
||||||
|
var inputType = $.aM.e.find('[name="type"]').val()
|
||||||
|
var url = $(this).val()
|
||||||
|
var theSwitch = $.aM.e.find('[detail="auto_host_enable"]')
|
||||||
|
var disabled = theSwitch.val()
|
||||||
|
if(!disabled||disabled===''){
|
||||||
|
//if no value, then probably old version of monitor config. Set to Manual to avoid confusion.
|
||||||
|
disabled='0'
|
||||||
|
theSwitch.val('0').change()
|
||||||
|
}
|
||||||
|
if(disabled==='0'){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(inputType === 'local'){
|
||||||
|
$.aM.e.find('[name="path"]').val(url).change()
|
||||||
|
}else{
|
||||||
|
var urlSplitByDots = url.split('.')
|
||||||
|
var has = function(query,searchIn){if(!searchIn){searchIn=url;};return url.indexOf(query)>-1}
|
||||||
|
var protocol = url.split('://')[0]
|
||||||
|
console.log(url.split('://'))
|
||||||
|
//switch RTSP, RTMP and RTMPS to parse URL
|
||||||
|
if(has('rtsp://')){
|
||||||
|
isRTSP = true;
|
||||||
|
url = url.replace('rtsp://','http://')
|
||||||
|
}
|
||||||
|
if(has('rtmp://')){
|
||||||
|
isRTMP = true;
|
||||||
|
url = url.replace('rtmp://','http://')
|
||||||
|
}
|
||||||
|
if(has('rtmps://')){
|
||||||
|
isRTMPS = true;
|
||||||
|
url = url.replace('rtmps://','http://')
|
||||||
|
}
|
||||||
|
//parse URL
|
||||||
|
var parsedURL = document.createElement('a');
|
||||||
|
parsedURL.href = url;
|
||||||
|
var pathname = parsedURL.pathname
|
||||||
|
if(url.indexOf('?') > -1){
|
||||||
|
pathname += '?'+url.split('?')[1]
|
||||||
|
}
|
||||||
|
$.aM.e.find('[name="protocol"]').val(protocol).change()
|
||||||
|
if(isRTSP){
|
||||||
|
$.aM.e.find('[detail="rtsp_transport"]').val('tcp').change()
|
||||||
|
$.aM.e.find('[detail="aduration"]').val(1000000).change()
|
||||||
|
$.aM.e.find('[detail="probesize"]').val(1000000).change()
|
||||||
|
}
|
||||||
|
$.aM.e.find('[detail="muser"]').val(parsedURL.username).change()
|
||||||
|
$.aM.e.find('[detail="mpass"]').val(parsedURL.password).change()
|
||||||
|
$.aM.e.find('[name="host"]').val(parsedURL.hostname).change()
|
||||||
|
$.aM.e.find('[name="port"]').val(parsedURL.port).change()
|
||||||
|
$.aM.e.find('[name="path"]').val(pathname).change()
|
||||||
|
delete(parsedURL)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.aM.e.find('.refresh_cascades').click(function(e){
|
||||||
|
$.ccio.cx({f:'ocv_in',data:{f:'refreshPlugins',ke:$user.ke}})
|
||||||
|
})
|
||||||
|
$.aM.f.submit(function(ee){
|
||||||
|
ee.preventDefault();
|
||||||
|
e={e:$(this)};
|
||||||
|
e.s=e.e.serializeObject();
|
||||||
|
e.er=[];
|
||||||
|
$.each(e.s,function(n,v){e.s[n]=v.trim()});
|
||||||
|
e.s.mid=e.s.mid.replace(/[^\w\s]/gi,'').replace(/ /g,'')
|
||||||
|
if(e.s.mid.length<3){e.er.push('Monitor ID too short')}
|
||||||
|
if(e.s.port==''){
|
||||||
|
if(e.s.protocol === 'https'){
|
||||||
|
e.s.port = 443
|
||||||
|
}else{
|
||||||
|
e.s.port = 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(e.s.name==''){e.er.push('Monitor Name cannot be blank')}
|
||||||
|
// if(e.s.protocol=='rtsp'){e.s.ext='mp4',e.s.type='rtsp'}
|
||||||
|
if(e.er.length>0){
|
||||||
|
$.sM.e.find('.msg').html(e.er.join('<br>'));
|
||||||
|
$.ccio.init('note',{title:'Configuration Invalid',text:e.er.join('<br>'),type:'error'});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.post($.ccio.init('location',$user)+$user.auth_token+'/configureMonitor/'+$user.ke+'/'+e.s.mid,{data:JSON.stringify(e.s)},function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
})
|
||||||
|
//
|
||||||
|
if($('#copy_settings').val() === '1'){
|
||||||
|
e.s.details = JSON.parse(e.s.details);
|
||||||
|
var copyMonitors = $.aM.monitorsForCopy.val();
|
||||||
|
var chosenSections = [];
|
||||||
|
var chosenMonitors = {};
|
||||||
|
|
||||||
|
if(!copyMonitors||copyMonitors.length===0){
|
||||||
|
$.ccio.init('note',{title:lang['No Monitors Selected'],text:lang.monSavedButNotCopied})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$.aM.e.find('[copy]').each(function(n,v){
|
||||||
|
var el = $(v)
|
||||||
|
if(el.val() === '1'){
|
||||||
|
chosenSections.push(el.attr('copy'))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
var alterSettings = function(settingsToAlter,monitor){
|
||||||
|
monitor.details = JSON.parse(monitor.details);
|
||||||
|
$.aM.e.find(settingsToAlter).find('input,select,textarea').each(function(n,v){
|
||||||
|
var el = $(v);
|
||||||
|
var name = el.attr('name')
|
||||||
|
var detail = el.attr('detail')
|
||||||
|
var value
|
||||||
|
switch(true){
|
||||||
|
case !!name:
|
||||||
|
var value = e.s[name]
|
||||||
|
monitor[name] = value;
|
||||||
|
break;
|
||||||
|
case !!detail:
|
||||||
|
detail = detail.replace('"','')
|
||||||
|
var value = e.s.details[detail]
|
||||||
|
monitor.details[detail] = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
monitor.details = JSON.stringify(monitor.details);
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
$.each(copyMonitors,function(n,id){
|
||||||
|
var monitor
|
||||||
|
if(id === '$New'){
|
||||||
|
monitor = $.aM.generateDefaultMonitorSettings();
|
||||||
|
//connection
|
||||||
|
monitor.name = e.s.name+' - '+monitor.mid
|
||||||
|
monitor.type = e.s.type
|
||||||
|
monitor.protocol = e.s.protocol
|
||||||
|
monitor.host = e.s.host
|
||||||
|
monitor.port = e.s.port
|
||||||
|
monitor.path = e.s.path
|
||||||
|
monitor.details.fatal_max = e.s.details.fatal_max
|
||||||
|
monitor.details.port_force = e.s.details.port_force
|
||||||
|
monitor.details.muser = e.s.details.muser
|
||||||
|
monitor.details.password = e.s.details.password
|
||||||
|
monitor.details.rtsp_transport = e.s.details.rtsp_transport
|
||||||
|
monitor.details.auto_host = e.s.details.auto_host
|
||||||
|
monitor.details.auto_host_enable = e.s.details.auto_host_enable
|
||||||
|
//input
|
||||||
|
monitor.details.aduration = e.s.details.aduration
|
||||||
|
monitor.details.probesize = e.s.details.probesize
|
||||||
|
monitor.details.stream_loop = e.s.details.stream_loop
|
||||||
|
monitor.details.sfps = e.s.details.sfps
|
||||||
|
monitor.details.accelerator = e.s.details.accelerator
|
||||||
|
monitor.details.hwaccel = e.s.details.hwaccel
|
||||||
|
monitor.details.hwaccel_vcodec = e.s.details.hwaccel_vcodec
|
||||||
|
monitor.details.hwaccel_device = e.s.details.hwaccel_device
|
||||||
|
}else{
|
||||||
|
monitor = Object.assign({},$.ccio.init('cleanMon',$.ccio.mon[$user.ke+id+$user.auth_token]));
|
||||||
|
}
|
||||||
|
$.each(chosenSections,function(n,section){
|
||||||
|
monitor = alterSettings(section,monitor)
|
||||||
|
})
|
||||||
|
console.log(monitor)
|
||||||
|
$.post($.ccio.init('location',$user)+$user.auth_token+'/configureMonitor/'+$user.ke+'/'+monitor.mid,{data:JSON.stringify(monitor)},function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
})
|
||||||
|
chosenMonitors[monitor.mid] = monitor;
|
||||||
|
})
|
||||||
|
console.log(chosenMonitors)
|
||||||
|
}
|
||||||
|
|
||||||
|
$.aM.e.modal('hide')
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
//////////////////
|
||||||
|
//Input Map (Feed)
|
||||||
|
$.aM.mapPlacementInit = function(){
|
||||||
|
$('.input-map').each(function(n,v){
|
||||||
|
var _this = $(this)
|
||||||
|
_this.find('.place').text(n+1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$.aM.mapSave = function(){
|
||||||
|
var e={};
|
||||||
|
var mapContainers = $('[input-mapping]');
|
||||||
|
var stringForSave={}
|
||||||
|
mapContainers.each(function(q,t){
|
||||||
|
var mapRowElement = $(t).find('.map-row');
|
||||||
|
var mapRow = []
|
||||||
|
mapRowElement.each(function(n,v){
|
||||||
|
var map={}
|
||||||
|
$.each($(v).find('[map-input]'),function(m,b){
|
||||||
|
map[$(b).attr('map-input')]=$(b).val()
|
||||||
|
});
|
||||||
|
mapRow.push(map)
|
||||||
|
});
|
||||||
|
stringForSave[$(t).attr('input-mapping')] = mapRow;
|
||||||
|
});
|
||||||
|
$.aM.e.find('[detail="input_map_choices"]').val(JSON.stringify(stringForSave)).change();
|
||||||
|
}
|
||||||
|
$.aM.maps.on('click','.delete',function(){
|
||||||
|
$(this).parents('.input-map').remove()
|
||||||
|
var inputs = $('[map-detail]')
|
||||||
|
var mapContainers = $('[input-mapping]');
|
||||||
|
if(inputs.length===0){
|
||||||
|
$.aM.e.find('[detail="input_maps"]').val('[]').change()
|
||||||
|
mapContainers.hide();
|
||||||
|
}else{
|
||||||
|
inputs.first().change()
|
||||||
|
mapContainers.show();
|
||||||
|
}
|
||||||
|
$.aM.mapPlacementInit()
|
||||||
|
})
|
||||||
|
$.aM.e.on('change','[map-detail]',function(){
|
||||||
|
var e={};
|
||||||
|
e.e=$.aM.maps.find('.input-map')
|
||||||
|
e.s=[]
|
||||||
|
e.e.each(function(n,v){
|
||||||
|
var map={}
|
||||||
|
$.each($(v).find('[map-detail]'),function(m,b){
|
||||||
|
map[$(b).attr('map-detail')]=$(b).val()
|
||||||
|
});
|
||||||
|
e.s.push(map)
|
||||||
|
});
|
||||||
|
$.aM.e.find('[detail="input_maps"]').val(JSON.stringify(e.s)).change()
|
||||||
|
})
|
||||||
|
$.aM.e.on('click','[input-mapping] .add_map_row',function(){
|
||||||
|
$.ccio.tm('input-map-selector',{},$(this).parents('[input-mapping]').find('.choices'))
|
||||||
|
$.aM.mapSave()
|
||||||
|
})
|
||||||
|
$.aM.e.on('click','[input-mapping] .delete_map_row',function(){
|
||||||
|
$(this).parents('.map-row').remove()
|
||||||
|
$.aM.mapSave()
|
||||||
|
})
|
||||||
|
$.aM.e.on('change','[map-input]',function(){
|
||||||
|
$.aM.mapSave()
|
||||||
|
})
|
||||||
|
//////////////////
|
||||||
|
//Stream Channels
|
||||||
|
$.aM.channelSave = function(){
|
||||||
|
var e={};
|
||||||
|
e.e=$.aM.channels.find('.stream-channel')
|
||||||
|
e.s=[]
|
||||||
|
e.e.each(function(n,v){
|
||||||
|
var channel={}
|
||||||
|
$.each($(v).find('[channel-detail]'),function(m,b){
|
||||||
|
channel[$(b).attr('channel-detail')]=$(b).val()
|
||||||
|
});
|
||||||
|
e.s.push(channel)
|
||||||
|
});
|
||||||
|
$.aM.e.find('[detail="stream_channels"]').val(JSON.stringify(e.s)).change()
|
||||||
|
}
|
||||||
|
$.aM.channelPlacementInit = function(){
|
||||||
|
$('.stream-channel').each(function(n,v){
|
||||||
|
var _this = $(this)
|
||||||
|
_this.attr('stream-channel',n)
|
||||||
|
_this.find('.place').text(n)
|
||||||
|
_this.find('[input-mapping]').attr('input-mapping','stream_channel-'+n)
|
||||||
|
$.aM.mapSave()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$.aM.buildMonitorURL = function(){
|
||||||
|
var e={};
|
||||||
|
e.user=$.aM.e.find('[detail="muser"]').val();
|
||||||
|
e.pass=$.aM.e.find('[detail="mpass"]').val();
|
||||||
|
e.host=$.aM.e.find('[name="host"]').val();
|
||||||
|
e.protocol=$.aM.e.find('[name="protocol"]').val();
|
||||||
|
e.port=$.aM.e.find('[name="port"]').val();
|
||||||
|
e.path=$.aM.e.find('[name="path"]').val();
|
||||||
|
if($.aM.e.find('[name="type"]').val()==='local'){
|
||||||
|
e.url=e.path;
|
||||||
|
}else{
|
||||||
|
if(e.host.indexOf('@')===-1&&e.user!==''){
|
||||||
|
e.host=e.user+':'+e.pass+'@'+e.host;
|
||||||
|
}
|
||||||
|
e.url=$.ccio.init('url',e)+e.path;
|
||||||
|
}
|
||||||
|
return e.url
|
||||||
|
}
|
||||||
|
$.aM.channels.on('click','.delete',function(){
|
||||||
|
$(this).parents('.stream-channel').remove()
|
||||||
|
$.aM.channelSave()
|
||||||
|
$.aM.channelPlacementInit()
|
||||||
|
})
|
||||||
|
$.aM.e.on('change','[channel-detail]',function(){
|
||||||
|
$.aM.channelSave()
|
||||||
|
})
|
||||||
|
//////////////////
|
||||||
|
$.aM.e.on('change','[groups]',function(){
|
||||||
|
var e={};
|
||||||
|
e.e=$.aM.e.find('[groups]:checked');
|
||||||
|
e.s=[];
|
||||||
|
e.e.each(function(n,v){
|
||||||
|
e.s.push($(v).val())
|
||||||
|
});
|
||||||
|
$.aM.e.find('[detail="groups"]').val(JSON.stringify(e.s)).change()
|
||||||
|
})
|
||||||
|
$.aM.e.on('change','.detector_cascade_selection',function(){
|
||||||
|
var e={};
|
||||||
|
e.e=$.aM.e.find('.detector_cascade_selection:checked');
|
||||||
|
e.s={};
|
||||||
|
e.e.each(function(n,v){
|
||||||
|
e.s[$(v).val()]={}
|
||||||
|
});
|
||||||
|
$.aM.e.find('[detail="detector_cascades"]').val(JSON.stringify(e.s)).change()
|
||||||
|
})
|
||||||
|
//$.aM.e.on('change','.detector_cascade_selection',function(){
|
||||||
|
// var e={};
|
||||||
|
// e.details=$.aM.e.find('[name="details"]')
|
||||||
|
// try{
|
||||||
|
// e.detailsVal=JSON.parse(e.details.val())
|
||||||
|
// }catch(err){
|
||||||
|
// e.detailsVal={}
|
||||||
|
// }
|
||||||
|
// e.detailsVal.detector_cascades=[];
|
||||||
|
// e.e=$.aM.e.find('.detector_cascade_selection:checked');
|
||||||
|
// e.e.each(function(n,v){
|
||||||
|
// e.detailsVal.detector_cascades.push($(v).val())
|
||||||
|
// });
|
||||||
|
// e.details.val(JSON.stringify(e.detailsVal))
|
||||||
|
//})
|
||||||
|
$.aM.e.find('.probe_config').click(function(){
|
||||||
|
$.pB.e.find('[name="url"]').val($.aM.buildMonitorURL());
|
||||||
|
$.pB.f.submit();
|
||||||
|
$.pB.e.modal('show');
|
||||||
|
})
|
||||||
|
$.aM.e.find('.import_config').click(function(e){
|
||||||
|
var e={};e.e=$(this);e.mid=e.e.parents('[mid]').attr('mid');
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text(lang['Import Monitor Configuration'])
|
||||||
|
e.html=lang.ImportMonitorConfigurationText+'<div style="margin-top:15px"><div class="form-group"><textarea placeholder="'+lang['Paste JSON here.']+'" class="form-control"></textarea></div><label class="upload_file btn btn-primary btn-block"> Upload File <input class="upload" type=file name="files[]"></label></div>';
|
||||||
|
$.confirm.body.html(e.html)
|
||||||
|
$.confirm.e.find('.upload').change(function(e){
|
||||||
|
var files = e.target.files; // FileList object
|
||||||
|
f = files[0];
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(ee) {
|
||||||
|
$.confirm.e.find('textarea').val(ee.target.result);
|
||||||
|
}
|
||||||
|
reader.readAsText(f);
|
||||||
|
});
|
||||||
|
$.confirm.click({title:'Import',class:'btn-primary'},function(){
|
||||||
|
try{
|
||||||
|
e.values=JSON.parse($.confirm.e.find('textarea').val());
|
||||||
|
$.aM.import(e)
|
||||||
|
$.aM.e.modal('show')
|
||||||
|
}catch(err){
|
||||||
|
$.ccio.log(err)
|
||||||
|
$.ccio.init('note',{title:lang['Invalid JSON'],text:lang.InvalidJSONText,type:'error'})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$.aM.e.find('.save_config').click(function(e){
|
||||||
|
var e={};e.e=$(this);e.mid=e.e.parents('[mid]').attr('mid');e.s=$.aM.f.serializeObject();
|
||||||
|
if(!e.mid||e.mid===''){
|
||||||
|
e.mid='NewMonitor'
|
||||||
|
}
|
||||||
|
e.dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(e.s));
|
||||||
|
$('#temp').html('<a></a>')
|
||||||
|
.find('a')
|
||||||
|
.attr('href',e.dataStr)
|
||||||
|
.attr('download','Shinobi_'+e.mid+'_config.json')
|
||||||
|
[0].click()
|
||||||
|
});
|
||||||
|
$.aM.e.find('.add_map').click(function(e){
|
||||||
|
$('[input-mapping]').show()
|
||||||
|
$.ccio.tm('input-map')
|
||||||
|
});
|
||||||
|
$.aM.e.find('.add_channel').click(function(e){
|
||||||
|
$.ccio.tm('stream-channel')
|
||||||
|
});
|
||||||
|
$.aM.f.find('[detail="stream_type"]').change(function(e){
|
||||||
|
e.e=$(this);
|
||||||
|
if(e.e.val()==='jpeg'){$.aM.f.find('[detail="snap"]').val('1').change()}
|
||||||
|
})
|
||||||
|
$.aM.f.find('[name="type"]').change(function(e){
|
||||||
|
e.e=$(this);
|
||||||
|
if(e.e.val()==='h264'){$.aM.f.find('[name="protocol"]').val('rtsp').change()}
|
||||||
|
})
|
||||||
|
$.aM.md=$.aM.f.find('[detail]');
|
||||||
|
$.aM.md.change($.ccio.form.details)
|
||||||
|
$.aM.f.on('change','[selector]',function(){
|
||||||
|
e={e:$(this)}
|
||||||
|
e.v=e.e.val();
|
||||||
|
e.a=e.e.attr('selector')
|
||||||
|
e.triggerChange=e.e.attr('triggerchange')
|
||||||
|
e.triggerChangeIgnore=e.e.attr('triggerChangeIgnore')
|
||||||
|
$.aM.f.find('.'+e.a+'_input').hide()
|
||||||
|
$.aM.f.find('.'+e.a+'_'+e.v).show();
|
||||||
|
$.aM.f.find('.'+e.a+'_text').text($(this).find('option:selected').text())
|
||||||
|
if(e.triggerChange && e.triggerChange !== '' && !e.triggerChangeIgnore || (e.triggerChangeIgnore && e.triggerChangeIgnore.split(',').indexOf(e.v) === -1)){
|
||||||
|
console.log(e.triggerChange)
|
||||||
|
$(e.triggerChange).trigger('change')
|
||||||
|
}
|
||||||
|
$.aM.drawList()
|
||||||
|
});
|
||||||
|
$.aM.f.find('[name="type"]').change(function(e){
|
||||||
|
e.e=$(this);
|
||||||
|
e.v=e.e.val();
|
||||||
|
e.h=$.aM.f.find('[name="path"]');
|
||||||
|
e.p=e.e.parents('.form-group');
|
||||||
|
switch(e.v){
|
||||||
|
case'local':case'socket':
|
||||||
|
e.h.attr('placeholder','/dev/video0')
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
e.h.attr('placeholder','/videostream.cgi?1')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
|
@ -0,0 +1,192 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//multi monitor manager
|
||||||
|
$.multimon={e:$('#multi_mon')};
|
||||||
|
$.multimon.table=$.multimon.e.find('.tableData tbody');
|
||||||
|
$.multimon.f=$.multimon.e.find('form');
|
||||||
|
$.multimon.f.on('change','#multimon_select_all',function(e){
|
||||||
|
e.e=$(this);
|
||||||
|
e.p=e.e.prop('checked')
|
||||||
|
e.a=$.multimon.f.find('input[type=checkbox][name]')
|
||||||
|
if(e.p===true){
|
||||||
|
e.a.prop('checked',true)
|
||||||
|
}else{
|
||||||
|
e.a.prop('checked',false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.multimon.e.find('.import_config').click(function(){
|
||||||
|
var e={};e.e=$(this);e.mid=e.e.parents('[mid]').attr('mid');
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text(lang['Import Monitor Configuration'])
|
||||||
|
e.html=lang.ImportMultiMonitorConfigurationText+'<div style="margin-top:15px"><div class="form-group"><textarea placeholder="'+lang['Paste JSON here.']+'" class="form-control"></textarea></div><label class="upload_file btn btn-primary btn-block"> Upload File <input class="upload" type=file name="files[]"></label></div>';
|
||||||
|
$.confirm.body.html(e.html)
|
||||||
|
$.confirm.e.find('.upload').change(function(e){
|
||||||
|
var files = e.target.files; // FileList object
|
||||||
|
f = files[0];
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(ee) {
|
||||||
|
$.confirm.e.find('textarea').val(ee.target.result);
|
||||||
|
}
|
||||||
|
reader.readAsText(f);
|
||||||
|
});
|
||||||
|
$.confirm.click({title:'Import',class:'btn-primary'},function(){
|
||||||
|
// setTimeout(function(){
|
||||||
|
// $.confirm.e.modal('show');
|
||||||
|
// },1000)
|
||||||
|
// $.confirm.title.text(lang['Are you sure?'])
|
||||||
|
// $.confirm.body.html(lang.ImportMultiMonitorConfigurationText)
|
||||||
|
// $.confirm.click({title:'Save Set',class:'btn-danger'},function(){
|
||||||
|
try{
|
||||||
|
var postMonitor = function(v){
|
||||||
|
$.post($.ccio.init('location',$user)+$user.auth_token+'/configureMonitor/'+$user.ke+'/'+v.mid,{data:JSON.stringify(v,null,3)},function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var parseZmMonitor = function(Monitor){
|
||||||
|
console.log(Monitor)
|
||||||
|
var newMon = $.aM.generateDefaultMonitorSettings()
|
||||||
|
newMon.details = JSON.parse(newMon.details)
|
||||||
|
newMon.details.stream_type = 'jpeg'
|
||||||
|
switch(Monitor.Type.toLowerCase()){
|
||||||
|
case'ffmpeg':case'libvlc':
|
||||||
|
newMon.details.auto_host_enable = '1'
|
||||||
|
newMon.details.auto_host = Monitor.Path
|
||||||
|
if(newMon.auto_host.indexOf('rtsp://') > -1 || newMon.auto_host.indexOf('rtmp://') > -1 || newMon.auto_host.indexOf('rtmps://') > -1){
|
||||||
|
newMon.type = 'h264'
|
||||||
|
}else{
|
||||||
|
$.ccio.init('note',{title:lang['Please Check Your Settings'],text:lang.migrateText1,type:'error'})
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'local':
|
||||||
|
newMon.details.auto_host = Monitor.Device
|
||||||
|
break;
|
||||||
|
case'remote':
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
newMon.details = JSON.stringify(newMon.details)
|
||||||
|
console.log(newMon)
|
||||||
|
return newMon
|
||||||
|
}
|
||||||
|
parsedData=JSON.parse($.confirm.e.find('textarea').val());
|
||||||
|
//zoneminder one monitor
|
||||||
|
if(parsedData.monitor){
|
||||||
|
$.aM.import({
|
||||||
|
values : parseZmMonitor(parsedData.monitor.Monitor)
|
||||||
|
})
|
||||||
|
$.aM.e.modal('show')
|
||||||
|
}else
|
||||||
|
//zoneminder multiple monitors
|
||||||
|
if(parsedData.monitors){
|
||||||
|
$.each(parsedData.monitors,function(n,v){
|
||||||
|
$.aM.import({
|
||||||
|
values : parseZmMonitor(parsedData.Monitor)
|
||||||
|
})
|
||||||
|
parseZmMonitor(v.Monitor)
|
||||||
|
})
|
||||||
|
}else
|
||||||
|
//shinobi one monitor
|
||||||
|
if(parsedData.mid){
|
||||||
|
postMonitor(parsedData)
|
||||||
|
}else
|
||||||
|
//shinobi multiple monitors
|
||||||
|
if(parsedData[0] && parsedData[0].mid){
|
||||||
|
$.each(parsedData,function(n,v){
|
||||||
|
postMonitor(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
$.ccio.log(err)
|
||||||
|
$.ccio.init('note',{title:lang['Invalid JSON'],text:lang.InvalidJSONText,type:'error'})
|
||||||
|
}
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
})
|
||||||
|
$.multimon.getSelectedMonitors = function(unclean){
|
||||||
|
var arr=[];
|
||||||
|
if(unclean === true){
|
||||||
|
var monitors = $.ccio.mon
|
||||||
|
}else{
|
||||||
|
var monitors = $.ccio.init('cleanMons','object')
|
||||||
|
}
|
||||||
|
$.each($.multimon.f.serializeObject(),function(n,v){
|
||||||
|
arr.push(monitors[n])
|
||||||
|
})
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
$.multimon.e.find('.delete').click(function(){
|
||||||
|
var arr=$.multimon.getSelectedMonitors(true);
|
||||||
|
if(arr.length===0){
|
||||||
|
$.ccio.init('note',{title:'No Monitors Selected',text:'Select atleast one monitor to delete.',type:'error'});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text(lang['Delete']+' '+lang['Monitors'])
|
||||||
|
e.html='<p>'+lang.DeleteMonitorsText+'</p>';
|
||||||
|
$.confirm.body.html(e.html)
|
||||||
|
$.confirm.click([
|
||||||
|
{
|
||||||
|
title:'Delete Monitors',
|
||||||
|
class:'btn-danger',
|
||||||
|
callback:function(){
|
||||||
|
$.each(arr,function(n,v){
|
||||||
|
$.get($.ccio.init('location',$user)+v.user.auth_token+'/configureMonitor/'+v.ke+'/'+v.mid+'/delete',function(data){
|
||||||
|
console.log(data)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title:'Delete Monitors and Files',
|
||||||
|
class:'btn-danger',
|
||||||
|
callback:function(){
|
||||||
|
$.each(arr,function(n,v){
|
||||||
|
$.get($.ccio.init('location',$user)+v.user.auth_token+'/configureMonitor/'+v.ke+'/'+v.mid+'/delete?deleteFiles=true',function(data){
|
||||||
|
console.log(data)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
})
|
||||||
|
//$.multimon.e.find('.edit_all').click(function(){
|
||||||
|
// var arr=$.multimon.getSelectedMonitors();
|
||||||
|
// var arrObject={}
|
||||||
|
// if(arr.length===0){
|
||||||
|
// $.ccio.init('note',{title:'No Monitors Selected',text:'Select atleast one monitor to delete.',type:'error'});
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// $.multimonedit.selectedList = arr;
|
||||||
|
// $.multimonedit.e.modal('show')
|
||||||
|
//})
|
||||||
|
$.multimon.e.find('.save_config').click(function(){
|
||||||
|
var e={};e.e=$(this);
|
||||||
|
var arr=$.multimon.getSelectedMonitors();
|
||||||
|
if(arr.length===0){
|
||||||
|
$.ccio.init('note',{title:'No Monitors Selected',text:'Select atleast one monitor to delete.',type:'error'});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
e.dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(arr));
|
||||||
|
$('#temp').html('<a></a>')
|
||||||
|
.find('a')
|
||||||
|
.attr('href',e.dataStr)
|
||||||
|
.attr('download','Shinobi_Monitors_'+(new Date())+'.json')
|
||||||
|
[0].click()
|
||||||
|
})
|
||||||
|
$.multimon.e.on('shown.bs.modal',function() {
|
||||||
|
var tmp=''
|
||||||
|
$.each($.ccio.mon,function(n,v){
|
||||||
|
var streamURL = $.ccio.init('streamURL',v)
|
||||||
|
if(streamURL!=='Websocket'&&v.mode!==('idle'&&'stop')){
|
||||||
|
streamURL='<a target="_blank" href="'+streamURL+'">'+streamURL+'</a>'
|
||||||
|
}
|
||||||
|
var img = $('#left_menu [mid="'+v.mid+'"][auth="'+v.user.auth_token+'"] [monitor="watch"]').attr('src')
|
||||||
|
tmp+='<tr mid="'+v.mid+'" ke="'+v.ke+'" auth="'+v.user.auth_token+'">'
|
||||||
|
tmp+='<td><div class="checkbox"><input id="multimonCheck_'+v.ke+v.mid+v.user.auth_token+'" type="checkbox" name="'+v.ke+v.mid+v.user.auth_token+'" value="1"><label for="multimonCheck_'+v.ke+v.mid+v.user.auth_token+'"></label></div></td>'
|
||||||
|
tmp+='<td><a monitor="watch"><img class="small-square-img" src="'+img+'"></a></td><td>'+v.name+'<br><small>'+v.mid+'</small></td><td class="monitor_status">'+v.status+'</td><td>'+streamURL+'</td>'
|
||||||
|
//buttons
|
||||||
|
tmp+='<td class="text-right"><a title="'+lang.Pop+'" monitor="pop" class="btn btn-primary"><i class="fa fa-external-link"></i></a> <a title="'+lang.Calendar+'" monitor="calendar" class="btn btn-default"><i class="fa fa-calendar"></i></a> <a title="'+lang['Power Viewer']+'" class="btn btn-default" monitor="powerview"><i class="fa fa-map-marker"></i></a> <a title="'+lang['Time-lapse']+'" class="btn btn-default" monitor="timelapse"><i class="fa fa-angle-double-right"></i></a> <a title="'+lang['Videos List']+'" monitor="videos_table" class="btn btn-default"><i class="fa fa-film"></i></a> <a title="'+lang['Monitor Settings']+'" class="btn btn-default" monitor="edit"><i class="fa fa-wrench"></i></a></td>'
|
||||||
|
tmp+='</tr>'
|
||||||
|
})
|
||||||
|
$.multimon.table.html(tmp)
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,60 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//onvif probe
|
||||||
|
$.oB={
|
||||||
|
e:$('#onvif_probe'),
|
||||||
|
v:$('#onvif_video'),
|
||||||
|
};
|
||||||
|
$.oB.f=$.oB.e.find('form');$.oB.o=$.oB.e.find('.output_data');
|
||||||
|
$.oB.f.submit(function(ee){
|
||||||
|
ee.preventDefault();
|
||||||
|
e={};
|
||||||
|
$.oB.foundMonitors={}
|
||||||
|
e.e=$(this),e.s=e.e.serializeObject();
|
||||||
|
$.oB.o.empty();
|
||||||
|
$.oB.e.find('._loading').show()
|
||||||
|
$.oB.e.find('[type="submit"]').prop('disabled',true)
|
||||||
|
$.ccio.cx({f:'onvif',ip:e.s.ip,port:e.s.port,user:e.s.user,pass:e.s.pass})
|
||||||
|
clearTimeout($.oB.checkTimeout)
|
||||||
|
$.oB.checkTimeout=setTimeout(function(){
|
||||||
|
if($.oB.o.find('tr').length===0){
|
||||||
|
$.oB.e.find('._loading').hide()
|
||||||
|
$.oB.e.find('[type="submit"]').prop('disabled',false)
|
||||||
|
$.oB.o.append('<td class="text-center _notfound">Sorry, nothing was found.</td>')
|
||||||
|
}
|
||||||
|
},5000)
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$.oB.e.on('click','.copy',function(){
|
||||||
|
$('.hidden-xs [monitor="edit"]').click();
|
||||||
|
e={};
|
||||||
|
e.e = $(this).parents('[onvif_row]');
|
||||||
|
var id = e.e.attr('onvif_row');
|
||||||
|
var onvifRecord = $.oB.foundMonitors[id];
|
||||||
|
var streamURL = onvifRecord.uri;
|
||||||
|
if($.oB.e.find('[name="user"]').val()!==''){
|
||||||
|
streamURL = streamURL.split('://')
|
||||||
|
streamURL = streamURL[0]+'://'+$.oB.e.find('[name="user"]').val()+':'+$.oB.e.find('[name="pass"]').val()+'@'+streamURL[1];
|
||||||
|
}
|
||||||
|
$.aM.e.find('[detail="auto_host"]').val(streamURL).change()
|
||||||
|
$.aM.e.find('[name="mode"]').val('start')
|
||||||
|
$.oB.e.modal('hide')
|
||||||
|
})
|
||||||
|
$.oB.e.find('[name="ip"]').change(function(e){
|
||||||
|
$.ccio.op('onvif_probe_ip',$(this).val());
|
||||||
|
})
|
||||||
|
if($.ccio.op().onvif_probe_ip){
|
||||||
|
$.oB.e.find('[name="ip"]').val($.ccio.op().onvif_probe_ip)
|
||||||
|
}
|
||||||
|
$.oB.e.find('[name="port"]').change(function(e){
|
||||||
|
$.ccio.op('onvif_probe_port',$(this).val());
|
||||||
|
})
|
||||||
|
if($.ccio.op().onvif_probe_port){
|
||||||
|
$.oB.e.find('[name="port"]').val($.ccio.op().onvif_probe_port)
|
||||||
|
}
|
||||||
|
$.oB.e.find('[name="user"]').change(function(e){
|
||||||
|
$.ccio.op('onvif_probe_user',$(this).val());
|
||||||
|
})
|
||||||
|
if($.ccio.op().onvif_probe_user){
|
||||||
|
$.oB.e.find('[name="user"]').val($.ccio.op().onvif_probe_user)
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,298 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//POWER videos window
|
||||||
|
$.pwrvid={e:$('#pvideo_viewer')};
|
||||||
|
$.pwrvid.f=$.pwrvid.e.find('form'),
|
||||||
|
$.pwrvid.d=$('#vis_pwrvideo'),
|
||||||
|
$.pwrvid.mL=$('#motion_list'),
|
||||||
|
$.pwrvid.m=$('#vis_monitors'),
|
||||||
|
$.pwrvid.lv=$('#live_view'),
|
||||||
|
$.pwrvid.dr=$('#pvideo_daterange'),
|
||||||
|
$.pwrvid.vp=$('#video_preview'),
|
||||||
|
$.pwrvid.seekBar=$('#pwrvid_seekBar'),
|
||||||
|
$.pwrvid.seekBarProgress=$.pwrvid.seekBar.find('.progress-bar'),
|
||||||
|
$.pwrvid.playRate = 1;
|
||||||
|
$.pwrvid.dr.daterangepicker({
|
||||||
|
startDate:$.ccio.timeObject().subtract(moment.duration("24:00:00")),
|
||||||
|
endDate:$.ccio.timeObject().add(moment.duration("24:00:00")),
|
||||||
|
timePicker: true,
|
||||||
|
timePicker24Hour: true,
|
||||||
|
timePickerSeconds: true,
|
||||||
|
timePickerIncrement: 30,
|
||||||
|
locale: {
|
||||||
|
format: 'MM/DD/YYYY h:mm A'
|
||||||
|
}
|
||||||
|
},function(start, end, label){
|
||||||
|
$.pwrvid.drawTimeline()
|
||||||
|
$.pwrvid.dr.focus()
|
||||||
|
});
|
||||||
|
$('#pvideo_show_events').change(function(){
|
||||||
|
$.pwrvid.drawTimeline()
|
||||||
|
})
|
||||||
|
$.pwrvid.e.on('click','[preview]',function(e){
|
||||||
|
e.e=$(this);
|
||||||
|
e.video=$.pwrvid.vp.find('video')[0];
|
||||||
|
if(e.video){
|
||||||
|
e.duration=e.video.duration;
|
||||||
|
e.now=e.video.currentTime;
|
||||||
|
}
|
||||||
|
if($.pwrvid.video){
|
||||||
|
clearInterval($.pwrvid.video.interval);
|
||||||
|
}
|
||||||
|
switch(e.e.attr('preview')){
|
||||||
|
case'fullscreen':
|
||||||
|
$.ccio.init('fullscreen',e.video)
|
||||||
|
break;
|
||||||
|
case'mute':
|
||||||
|
e.video.muted = !e.video.muted
|
||||||
|
e.e.find('i').toggleClass('fa-volume-off fa-volume-up')
|
||||||
|
e.e.toggleClass('btn-danger')
|
||||||
|
break;
|
||||||
|
case'play':
|
||||||
|
e.video.playbackRate = 1;
|
||||||
|
$.pwrvid.vpOnPlayPause(1)
|
||||||
|
break;
|
||||||
|
case'stepFrontFront':
|
||||||
|
e.add=e.e.attr('add')
|
||||||
|
e.stepFrontFront=parseInt(e.e.attr('stepFrontFront'))
|
||||||
|
if(!e.stepFrontFront||isNaN(e.stepFrontFront)){e.stepFrontFront = 5}
|
||||||
|
if(e.add==="0"){
|
||||||
|
$.pwrvid.playRate = e.stepFrontFront
|
||||||
|
}else{
|
||||||
|
$.pwrvid.playRate += e.stepFrontFront
|
||||||
|
}
|
||||||
|
e.video.playbackRate = $.pwrvid.playRate;
|
||||||
|
e.video.play()
|
||||||
|
break;
|
||||||
|
case'stepFront':
|
||||||
|
e.video.currentTime += 1;
|
||||||
|
e.video.pause()
|
||||||
|
break;
|
||||||
|
case'stepBackBack':
|
||||||
|
$.pwrvid.video.interval = setInterval(function(){
|
||||||
|
e.video.playbackRate = 1.0;
|
||||||
|
if(e.video.currentTime == 0){
|
||||||
|
clearInterval($.pwrvid.video.interval);
|
||||||
|
e.video.pause();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
e.video.currentTime += -.2;
|
||||||
|
}
|
||||||
|
},30);
|
||||||
|
break;
|
||||||
|
case'stepBack':
|
||||||
|
e.video.currentTime += -1;
|
||||||
|
e.video.pause()
|
||||||
|
break;
|
||||||
|
case'video':
|
||||||
|
// e.preventDefault();
|
||||||
|
e.p=e.e.parents('[mid]');
|
||||||
|
e.filename=e.p.attr('file');
|
||||||
|
$.pwrvid.vp.find('h3').text(e.filename)
|
||||||
|
e.href=e.e.attr('href');
|
||||||
|
e.status=e.p.attr('status');
|
||||||
|
e.mon=$.ccio.mon[e.p.attr('ke')+e.p.attr('mid')+$user.auth_token];
|
||||||
|
$.pwrvid.vp.find('.holder').html('<video class="video_video" video="'+e.href+'"><source src="'+e.href+'" type="video/'+e.mon.ext+'"></video>');
|
||||||
|
$.pwrvid.vp
|
||||||
|
.attr('mid',e.mon.mid)
|
||||||
|
.attr('mid',e.mon.user.auth_token)
|
||||||
|
.attr('ke',e.mon.ke)
|
||||||
|
.attr('status',e.status)
|
||||||
|
.attr('file',e.filename)
|
||||||
|
.find('[download],[video="download"]')
|
||||||
|
.attr('download',e.filename)
|
||||||
|
.attr('href',e.href)
|
||||||
|
$.pwrvid.vp.find('video').off('loadeddata').on('loadeddata',function(){
|
||||||
|
$.pwrvid.vp.find('.stream-objects .stream-detected-object').remove()
|
||||||
|
})
|
||||||
|
if(e.status==1){
|
||||||
|
$.get($.ccio.init('videoHrefToRead',e.href),function(d){
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var labels=[]
|
||||||
|
var Dataset1=[]
|
||||||
|
var events=$.pwrvid.currentDataObject[e.filename].motion
|
||||||
|
var eventsLabeledByTime={}
|
||||||
|
$.each(events,function(n,v){
|
||||||
|
if(!v.details.confidence){v.details.confidence=0}
|
||||||
|
var time=$.ccio.timeObject(v.time).format('MM/DD/YYYY HH:mm:ss')
|
||||||
|
labels.push(time)
|
||||||
|
Dataset1.push(v.details.confidence)
|
||||||
|
eventsLabeledByTime[time]=v;
|
||||||
|
})
|
||||||
|
if(events.length>0){
|
||||||
|
$.pwrvid.mL.html("<canvas></canvas>")
|
||||||
|
var timeFormat = 'MM/DD/YYYY HH:mm:ss';
|
||||||
|
var color = Chart.helpers.color;
|
||||||
|
Chart.defaults.global.defaultFontColor = '#fff';
|
||||||
|
var config = {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: labels,
|
||||||
|
datasets: [{
|
||||||
|
type: 'line',
|
||||||
|
label: 'Motion Confidence',
|
||||||
|
backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),
|
||||||
|
borderColor: window.chartColors.red,
|
||||||
|
data: Dataset1,
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
fontColor: "white",
|
||||||
|
text:"Events in this video"
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
type: "time",
|
||||||
|
display: true,
|
||||||
|
time: {
|
||||||
|
format: timeFormat,
|
||||||
|
// round: 'day'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var ctx = $.pwrvid.mL.find('canvas')[0].getContext("2d");
|
||||||
|
$.pwrvid.miniChart = new Chart(ctx, config);
|
||||||
|
$.pwrvid.mL.find('canvas').click(function(f) {
|
||||||
|
var target = $.pwrvid.miniChart.getElementsAtEvent(f)[0];
|
||||||
|
if(!target){return false}
|
||||||
|
var video = $.pwrvid.currentDataObject[e.filename];
|
||||||
|
var event = video.motion[target._index];
|
||||||
|
var video1 = $('#video_preview video')[0];
|
||||||
|
video1.currentTime=$.ccio.timeObject(event.time).diff($.ccio.timeObject(video.row.time),'seconds')
|
||||||
|
video1.play()
|
||||||
|
});
|
||||||
|
var colorNames = Object.keys(window.chartColors);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
$.pwrvid.mL.html('<div class="super-center text-center" style="width:auto">'+lang['No Events found for this video']+'</div>')
|
||||||
|
}
|
||||||
|
$.pwrvid.video={filename:e.filename,href:e.href,mid:e.mon.mid,ke:e.mon.ke}
|
||||||
|
$.pwrvid.vpOnPlayPause=function(x,e){
|
||||||
|
var e={}
|
||||||
|
e.video=$.pwrvid.vp.find('video')[0]
|
||||||
|
e.i=$.pwrvid.vp.find('[preview="play"]').find('i')
|
||||||
|
if(e.video.paused===true){
|
||||||
|
e.i.removeClass('fa-pause').addClass('fa-play')
|
||||||
|
if(x==1)e.video.play();
|
||||||
|
}else{
|
||||||
|
e.i.removeClass('fa-play').addClass('fa-pause')
|
||||||
|
if(x==1)e.video.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var videoElement=$.pwrvid.vp.find('video')[0]
|
||||||
|
$.pwrvid.vp.find('video')
|
||||||
|
.off('loadeddata').on('loadeddata', function() {
|
||||||
|
this.playbackRate = $.pwrvid.playRate;
|
||||||
|
this.play()
|
||||||
|
})
|
||||||
|
.off("pause").on("pause",$.pwrvid.vpOnPlayPause)
|
||||||
|
.off("play").on("play",$.pwrvid.vpOnPlayPause)
|
||||||
|
.off("timeupdate").on("timeupdate",function(){
|
||||||
|
var video = $.pwrvid.currentDataObject[e.filename];
|
||||||
|
var videoTime=$.ccio.timeObject(video.row.time).add(parseInt(videoElement.currentTime),'seconds').format('MM/DD/YYYY HH:mm:ss');
|
||||||
|
var event = eventsLabeledByTime[videoTime];
|
||||||
|
if(event){
|
||||||
|
if(event.details.plates){
|
||||||
|
console.log('licensePlateVideo',event)
|
||||||
|
}
|
||||||
|
if(event.details.matrices){
|
||||||
|
event.monitorDetails=JSON.parse(e.mon.details)
|
||||||
|
event.stream=$(videoElement)
|
||||||
|
event.streamObjects=$.pwrvid.vp.find('.stream-objects')
|
||||||
|
$.ccio.init('drawMatrices',event)
|
||||||
|
}
|
||||||
|
if(event.details.confidence){
|
||||||
|
$.pwrvid.vp.find('.motion-meter .progress-bar').css('width',event.details.confidence+'px').find('span').text(event.details.confidence)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var value= (( videoElement.currentTime / videoElement.duration ) * 100)+"%"
|
||||||
|
$.pwrvid.seekBarProgress.css("width",value);
|
||||||
|
})
|
||||||
|
$.pwrvid.seekBar.off("click").on("click", function(seek){
|
||||||
|
var offset = $(this).offset();
|
||||||
|
var left = (seek.pageX - offset.left);
|
||||||
|
var totalWidth = $.pwrvid.seekBar.width();
|
||||||
|
var percentage = ( left / totalWidth );
|
||||||
|
var vidTime = videoElement.duration * percentage;
|
||||||
|
videoElement.currentTime = vidTime;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.pwrvid.drawTimeline=function(getData){
|
||||||
|
var e={};
|
||||||
|
$.pwrvid.e.find('.nodata').hide()
|
||||||
|
if(getData===undefined){getData=true}
|
||||||
|
var mid=$.pwrvid.m.val();
|
||||||
|
$.pwrvid.e.find('.loading').show()
|
||||||
|
e.live_header=$.pwrvid.lv.find('h3 span');
|
||||||
|
e.live=$.pwrvid.lv.find('iframe');
|
||||||
|
e.dateRange=$.pwrvid.dr.data('daterangepicker');
|
||||||
|
e.videoLimit = $('#pvideo_video_limit').val();
|
||||||
|
e.eventLimit = $('#pvideo_event_limit').val();
|
||||||
|
if(e.eventLimit===''||isNaN(e.eventLimit)){e.eventLimit=500}
|
||||||
|
if(e.videoLimit===''||isNaN(e.videoLimit)){e.videoLimit=0}
|
||||||
|
|
||||||
|
var getTheData = function(){
|
||||||
|
e.live_header.text($.ccio.mon[$user.ke+mid+$user.auth_token].name)
|
||||||
|
e.live.attr('src',$.ccio.init('location',$user)+$user.auth_token+'/embed/'+$user.ke+'/'+mid+'/fullscreen|jquery|relative|gui')
|
||||||
|
|
||||||
|
var pulseLoading = function(){
|
||||||
|
var loading = $.pwrvid.e.find('.loading')
|
||||||
|
var currentColor = loading.css('color')
|
||||||
|
loading.animate('color','red')
|
||||||
|
setTimeout(function(){
|
||||||
|
loading.css('color',currentColor)
|
||||||
|
},500)
|
||||||
|
}
|
||||||
|
if(getData===true){
|
||||||
|
$.ccio.cx({
|
||||||
|
f:'monitor',
|
||||||
|
ff:'get',
|
||||||
|
fff:'videos&events',
|
||||||
|
videoLimit:e.videoLimit,
|
||||||
|
eventLimit:e.eventLimit,
|
||||||
|
startDate:$.ccio.init('th',e.dateRange.startDate),
|
||||||
|
endDate:$.ccio.init('th',e.dateRange.endDate),
|
||||||
|
ke:e.ke,
|
||||||
|
mid:mid
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
$.pwrvid.e.find('.loading').hide()
|
||||||
|
e.next($.pwrvid.currentVideos,$.pwrvid.currentEvents)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(parseInt(e.eventLimit) >= 1000){
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text(lang['Warning']+'!')
|
||||||
|
e.html=lang.powerVideoEventLimit
|
||||||
|
$.confirm.body.html(e.html)
|
||||||
|
$.confirm.click({title:lang.Request,class:'btn-primary'},function(){
|
||||||
|
getTheData()
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
getTheData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$('#vis_monitors,#pvideo_event_limit,#pvideo_video_limit').change(function(){
|
||||||
|
$.pwrvid.f.submit()
|
||||||
|
})
|
||||||
|
$.pwrvid.f.submit(function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
$.pwrvid.drawTimeline()
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
$.pwrvid.e.on('hidden.bs.modal',function(e){
|
||||||
|
$(this).find('iframe').attr('src','about:blank')
|
||||||
|
$.pwrvid.vp.find('.holder').empty()
|
||||||
|
delete($.pwrvid.currentDataObject)
|
||||||
|
delete($.pwrvid.currentData)
|
||||||
|
$.pwrvid.mL.empty()
|
||||||
|
$.pwrvid.d.empty()
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,48 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//probe
|
||||||
|
$.pB={e:$('#probe')};$.pB.f=$.pB.e.find('form');$.pB.o=$.pB.e.find('.output_data');
|
||||||
|
$.pB.f.submit(function(e){
|
||||||
|
|
||||||
|
$.pB.e.find('._loading').show()
|
||||||
|
$.pB.o.empty();
|
||||||
|
$.pB.e.find('.stop').show();
|
||||||
|
$.pB.e.find('[type="submit"]').hide();
|
||||||
|
|
||||||
|
e.preventDefault();e.e=$(this),e.s=e.e.serializeObject();
|
||||||
|
e.s.url=e.s.url.trim();
|
||||||
|
var flags = '';
|
||||||
|
switch(e.s.mode){
|
||||||
|
case'json':
|
||||||
|
flags = '-v quiet -print_format json -show_format -show_streams';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// if(e.s.url.indexOf('{{JSON}}')>-1){
|
||||||
|
// e.s.url='-v quiet -print_format json -show_format -show_streams '+e.s.url
|
||||||
|
// }
|
||||||
|
$.get($.ccio.init('location',$user)+$user.auth_token+'/probe/'+$user.ke+'?url='+e.s.url+'&flags='+flags,function(data){
|
||||||
|
if(data.ok===true){
|
||||||
|
var html
|
||||||
|
try{
|
||||||
|
html = $.ccio.init('jsontoblock',JSON.parse(data.result))
|
||||||
|
}catch(err){
|
||||||
|
html = data.result
|
||||||
|
}
|
||||||
|
$.pB.o.append(html)
|
||||||
|
}else{
|
||||||
|
$.ccio.init('note',{title:'Failed to Probe',text:data.error,type:'error'});
|
||||||
|
}
|
||||||
|
$.pB.e.find('._loading').hide()
|
||||||
|
$.pB.o.append('<div><b>END</b></div>');
|
||||||
|
$.pB.e.find('.stop').hide();
|
||||||
|
$.pB.e.find('[type="submit"]').show();
|
||||||
|
})
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$.pB.e.on('hidden.bs.modal',function(){
|
||||||
|
$.pB.o.empty()
|
||||||
|
})
|
||||||
|
$.pB.e.find('.stop').click(function(e){
|
||||||
|
e.e=$(this);
|
||||||
|
// $.ccio.cx({f:'ffprobe',ff:'stop'})
|
||||||
|
});
|
||||||
|
})
|
|
@ -0,0 +1,200 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//Region Editor
|
||||||
|
$.zO={e:$('#region_editor')};
|
||||||
|
$.zO.f=$.zO.e.find('form');
|
||||||
|
$.zO.o=function(){return $.zO.e.find('canvas')};
|
||||||
|
$.zO.c=$.zO.e.find('.canvas_holder');
|
||||||
|
$.zO.name=$.zO.e.find('[name="name"]');
|
||||||
|
$.zO.rl=$('#regions_list');
|
||||||
|
$.zO.rp=$('#regions_points');
|
||||||
|
$.zO.ca=$('#regions_canvas');
|
||||||
|
$.zO.saveCoords=function(){
|
||||||
|
$.aM.e.find('[detail="cords"]').val(JSON.stringify($.zO.regionViewerDetails.cords)).change()
|
||||||
|
}
|
||||||
|
$.zO.initRegionList=function(){
|
||||||
|
$('#regions_list,#region_points').empty();
|
||||||
|
$.each($.zO.regionViewerDetails.cords,function(n,v){
|
||||||
|
if(v&&v.name){
|
||||||
|
$.zO.rl.append('<option value="'+n+'">'+v.name+'</option>')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$.zO.rl.change();
|
||||||
|
}
|
||||||
|
$.zO.rl.change(function(e){
|
||||||
|
$.zO.initCanvas();
|
||||||
|
})
|
||||||
|
$.zO.initLiveStream=function(e){
|
||||||
|
var e={}
|
||||||
|
e.re=$('#region_editor_live');
|
||||||
|
e.re.find('iframe,img').attr('src','about:blank').hide()
|
||||||
|
if($('#region_still_image').is(':checked')){
|
||||||
|
e.re=e.re.find('img')
|
||||||
|
e.choice='jpeg'
|
||||||
|
}else{
|
||||||
|
e.re=e.re.find('iframe')
|
||||||
|
e.choice='embed'
|
||||||
|
}
|
||||||
|
e.src=$.ccio.init('location',$user)+$user.auth_token+'/'+e.choice+'/'+$user.ke+'/'+$.aM.selected.mid
|
||||||
|
if(e.choice=='embed'){
|
||||||
|
e.src+='/fullscreen|jquery|relative'
|
||||||
|
}else{
|
||||||
|
e.src+='/s.jpg'
|
||||||
|
}
|
||||||
|
if(e.re.attr('src')!==e.src){
|
||||||
|
e.re.attr('src',e.src).show()
|
||||||
|
}
|
||||||
|
e.re.attr('width',$.zO.regionViewerDetails.detector_scale_x)
|
||||||
|
e.re.attr('height',$.zO.regionViewerDetails.detector_scale_y)
|
||||||
|
}
|
||||||
|
$('#region_still_image').change(function(e){
|
||||||
|
e.o=$.ccio.op().switches
|
||||||
|
if(!e.o){e.o={}}
|
||||||
|
if($(this).is(':checked')){
|
||||||
|
e.o.regionStillImage=1
|
||||||
|
}else{
|
||||||
|
e.o.regionStillImage="0"
|
||||||
|
}
|
||||||
|
$.ccio.op('switches',e.o)
|
||||||
|
$.zO.initLiveStream()
|
||||||
|
}).ready(function(e){
|
||||||
|
e.switches=$.ccio.op().switches
|
||||||
|
if(e.switches&&e.switches.regionStillImage===1){
|
||||||
|
$('#region_still_image').prop('checked',true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.zO.initCanvas=function(){
|
||||||
|
var e={};
|
||||||
|
e.ar=[];
|
||||||
|
e.val=$.zO.rl.val();
|
||||||
|
if(!e.val){
|
||||||
|
$.zO.f.find('[name="name"]').val('')
|
||||||
|
$.zO.f.find('[name="sensitivity"]').val('')
|
||||||
|
$.zO.f.find('[name="max_sensitivity"]').val('')
|
||||||
|
$.zO.f.find('[name="threshold"]').val('')
|
||||||
|
$.zO.f.find('[name="color_threshold"]').val('')
|
||||||
|
$.zO.rp.empty()
|
||||||
|
}else{
|
||||||
|
e.cord=$.zO.regionViewerDetails.cords[e.val];
|
||||||
|
if(!e.cord.points){e.cord.points=[[0,0],[0,100],[100,0]]}
|
||||||
|
$.each(e.cord.points,function(n,v){
|
||||||
|
e.ar=e.ar.concat(v)
|
||||||
|
});
|
||||||
|
if(isNaN(e.cord.sensitivity)){
|
||||||
|
e.cord.sensitivity=$.zO.regionViewerDetails.detector_sensitivity;
|
||||||
|
}
|
||||||
|
$.zO.f.find('[name="name"]').val(e.val)
|
||||||
|
$.zO.e.find('.cord_name').text(e.val)
|
||||||
|
$.zO.f.find('[name="sensitivity"]').val(e.cord.sensitivity)
|
||||||
|
$.zO.f.find('[name="max_sensitivity"]').val(e.cord.max_sensitivity)
|
||||||
|
$.zO.f.find('[name="threshold"]').val(e.cord.threshold)
|
||||||
|
$.zO.f.find('[name="color_threshold"]').val(e.cord.color_threshold)
|
||||||
|
$.zO.e.find('.canvas_holder canvas').remove();
|
||||||
|
|
||||||
|
$.zO.initLiveStream()
|
||||||
|
e.e=$.zO.ca.val(e.ar.join(','))
|
||||||
|
e.e.canvasAreaDraw({
|
||||||
|
imageUrl:placeholder.getData(placeholder.plcimg({
|
||||||
|
bgcolor:'transparent',
|
||||||
|
text:' ',
|
||||||
|
size:$.zO.regionViewerDetails.detector_scale_x+'x'+$.zO.regionViewerDetails.detector_scale_y
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
e.e.change();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.zO.e.on('change','[name]:not([name="name"])',function(){
|
||||||
|
var el = $(this)
|
||||||
|
var val = el.val()
|
||||||
|
var key = el.attr('name')
|
||||||
|
$.zO.regionViewerDetails.cords[$.zO.rl.val()][key] = val
|
||||||
|
$.zO.saveCoords()
|
||||||
|
})
|
||||||
|
$.zO.e.on('change','[name="name"]',function(e){
|
||||||
|
e.old=$.zO.rl.val();
|
||||||
|
e.new=$.zO.name.val();
|
||||||
|
$.zO.regionViewerDetails.cords[e.new]=$.zO.regionViewerDetails.cords[e.old];
|
||||||
|
delete($.zO.regionViewerDetails.cords[e.old]);
|
||||||
|
$.zO.rl.find('option[value="'+e.old+'"]').attr('value',e.new).text(e.new)
|
||||||
|
$.zO.saveCoords()
|
||||||
|
})
|
||||||
|
$.zO.e.on('change','[point]',function(e){
|
||||||
|
e.points=[];
|
||||||
|
$('[points]').each(function(n,v){
|
||||||
|
v=$(v);
|
||||||
|
n=v.find('[point="x"]').val();
|
||||||
|
if(n){
|
||||||
|
e.points.push([n,v.find('[point="y"]').val()])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.zO.regionViewerDetails.cords[$.zO.name.val()].points=e.points;
|
||||||
|
$.zO.initCanvas();
|
||||||
|
})
|
||||||
|
$.zO.e.find('.erase').click(function(e){
|
||||||
|
e.arr=[]
|
||||||
|
$.each($.zO.regionViewerDetails.cords,function(n,v){
|
||||||
|
if(v&&v!==$.zO.regionViewerDetails.cords[$.zO.rl.val()]){
|
||||||
|
e.arr.push(v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.zO.regionViewerDetails.cords=e.arr.concat([]);
|
||||||
|
if(Object.keys($.zO.regionViewerDetails.cords).length>0){
|
||||||
|
$.zO.initRegionList();
|
||||||
|
}else{
|
||||||
|
$.zO.f.find('input').prop('disabled',true)
|
||||||
|
$('#regions_points tbody').empty()
|
||||||
|
$('#regions_list [value="'+$.zO.rl.val()+'"]').remove()
|
||||||
|
$.aM.e.find('[detail="cords"]').val('[]')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//$.zO.e.find('.new').click(function(e){
|
||||||
|
// $.zO.regionViewerDetails.cords[$.zO.rl.val()]
|
||||||
|
// $.zO.initRegionList();
|
||||||
|
//})
|
||||||
|
$.zO.e.on('changed','#regions_canvas',function(e){
|
||||||
|
e.val=$(this).val().replace(/(,[^,]*),/g, '$1;').split(';');
|
||||||
|
e.ar=[];
|
||||||
|
$.each(e.val,function(n,v){
|
||||||
|
v=v.split(',')
|
||||||
|
if(v[1]){
|
||||||
|
e.ar.push([v[0],v[1]])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.zO.regionViewerDetails.cords[$.zO.rl.val()].points=e.ar;
|
||||||
|
e.selected=$.zO.regionViewerDetails.cords[$.zO.rl.val()];
|
||||||
|
e.e=$('#regions_points tbody').empty();
|
||||||
|
$.each($.zO.regionViewerDetails.cords[$.zO.rl.val()].points,function(n,v){
|
||||||
|
if(isNaN(v[0])){v[0]=20}
|
||||||
|
if(isNaN(v[1])){v[1]=20}
|
||||||
|
e.e.append('<tr points="'+n+'"><td><input class="form-control" placeholder="X" point="x" value="'+v[0]+'"></td><td><input class="form-control" placeholder="Y" point="y" value="'+v[1]+'"></td><td class="text-right"><a class="delete btn btn-danger"><i class="fa fa-trash-o"></i></a></td></tr>')
|
||||||
|
});
|
||||||
|
$.zO.saveCoords()
|
||||||
|
})
|
||||||
|
$.zO.f.submit(function(e){
|
||||||
|
e.preventDefault();e.e=$(this),e.s=e.e.serializeObject();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$('#regions_points')
|
||||||
|
.on('click','.delete',function(e){
|
||||||
|
e.p=$(this).parents('tr'),e.row=e.p.attr('points');
|
||||||
|
delete($.zO.regionViewerDetails.cords[$.zO.rl.val()].points[e.row])
|
||||||
|
$.zO.saveCoords()
|
||||||
|
e.p.remove();
|
||||||
|
$.zO.rl.change();
|
||||||
|
})
|
||||||
|
$.zO.e.on('click','.add',function(e){
|
||||||
|
$.zO.f.find('input').prop('disabled',false)
|
||||||
|
e.gid=$.ccio.gid(5);
|
||||||
|
e.save={};
|
||||||
|
$.each($.zO.regionViewerDetails.cords,function(n,v){
|
||||||
|
if(v&&v!==null&&v!=='null'){
|
||||||
|
e.save[n]=v;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.zO.regionViewerDetails.cords=e.save;
|
||||||
|
$.zO.regionViewerDetails.cords[e.gid]={name:e.gid,sensitivity:0.0005,max_sensitivity:'',threshold:1,color_threshold:9,points:[[0,0],[0,100],[100,0]]};
|
||||||
|
$.zO.rl.append('<option value="'+e.gid+'">'+e.gid+'</option>');
|
||||||
|
$.zO.rl.val(e.gid)
|
||||||
|
$.zO.rl.change();
|
||||||
|
});
|
||||||
|
})
|
|
@ -0,0 +1,933 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//websocket functions
|
||||||
|
$.users = {}
|
||||||
|
$.ccio.cx=function(x,user){
|
||||||
|
if(!user){user=$user}
|
||||||
|
if(!x.ke){x.ke=user.ke;};
|
||||||
|
if(!x.uid){x.uid=user.uid;};
|
||||||
|
return user.ws.emit('f',x)
|
||||||
|
}
|
||||||
|
$.ccio.globalWebsocket=function(d,user){
|
||||||
|
if(d.f!=='monitor_frame'&&d.f!=='os'&&d.f!=='video_delete'&&d.f!=='detector_trigger'&&d.f!=='detector_record_timeout_start'&&d.f!=='log'){$.ccio.log(d);}
|
||||||
|
if(!user){
|
||||||
|
user=$user
|
||||||
|
}
|
||||||
|
if(d.viewers){
|
||||||
|
$('[ke="'+d.ke+'"][mid="'+d.id+'"][auth="'+user.auth_token+'"] .viewers').html(d.viewers);
|
||||||
|
}
|
||||||
|
switch(d.f){
|
||||||
|
case'note':
|
||||||
|
$.ccio.init('note',d.note,user);
|
||||||
|
break;
|
||||||
|
case'monitor_status':
|
||||||
|
console.log(d)
|
||||||
|
$('[ke="'+d.ke+'"][mid="'+d.id+'"][auth="'+user.auth_token+'"] .monitor_status').html(d.status);
|
||||||
|
break;
|
||||||
|
case'detector_trigger':
|
||||||
|
d.e=$('.monitor_item[ke="'+d.ke+'"][mid="'+d.id+'"][auth="'+user.auth_token+'"]')
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token]&&d.e.length>0){
|
||||||
|
if(d.doObjectDetection === true){
|
||||||
|
d.e.addClass('doObjectDetection')
|
||||||
|
clearTimeout($.ccio.mon[d.ke+d.id+user.auth_token].detector_trigger_doObjectDetection_timeout)
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].detector_trigger_doObjectDetection_timeout = setTimeout(function(){
|
||||||
|
d.e.removeClass('doObjectDetection')
|
||||||
|
},3000)
|
||||||
|
}else{
|
||||||
|
d.e.removeClass('doObjectDetection')
|
||||||
|
}
|
||||||
|
if(d.details.plates&&d.details.plates.length>0){
|
||||||
|
console.log('licensePlateStream',d.id,d)
|
||||||
|
}
|
||||||
|
if(d.details.matrices&&d.details.matrices.length>0){
|
||||||
|
d.monitorDetails=JSON.parse($.ccio.mon[d.ke+d.id+user.auth_token].details)
|
||||||
|
d.stream=d.e.find('.stream-element')
|
||||||
|
d.streamObjects=d.e.find('.stream-objects')
|
||||||
|
$.ccio.init('drawMatrices',d)
|
||||||
|
}
|
||||||
|
if(d.details.points&&Object.keys(d.details.points).length>0){
|
||||||
|
d.monitorDetails=JSON.parse($.ccio.mon[d.ke+d.id+user.auth_token].details)
|
||||||
|
d.stream=d.e.find('.stream-element')
|
||||||
|
d.streamObjects=d.e.find('.stream-objects')
|
||||||
|
$.ccio.init('drawPoints',d)
|
||||||
|
}
|
||||||
|
if(d.details.confidence){
|
||||||
|
d.tt=d.details.confidence;
|
||||||
|
if (d.tt > 100) { d.tt = 100 }
|
||||||
|
d.e.find('.indifference .progress-bar').css('width',d.tt + '%').find('span').html(d.details.confidence+'% change in <b>'+d.details.name+'</b>')
|
||||||
|
}
|
||||||
|
d.e.addClass('detector_triggered')
|
||||||
|
clearTimeout($.ccio.mon[d.ke+d.id+user.auth_token].detector_trigger_timeout);
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].detector_trigger_timeout=setTimeout(function(){
|
||||||
|
$('.monitor_item[ke="'+d.ke+'"][mid="'+d.id+'"][auth="'+user.auth_token+'"]').removeClass('detector_triggered').find('.stream-detected-object,.stream-detected-point').remove()
|
||||||
|
},5000);
|
||||||
|
//noise alert
|
||||||
|
if(user.details.audio_alert && user.details.audio_alert !== '' && $.ccio.soundAlarmed !== true){
|
||||||
|
$.ccio.soundAlarmed = true
|
||||||
|
var audio = new Audio('libs/audio/'+user.details.audio_alert);
|
||||||
|
audio.onended = function(){
|
||||||
|
setTimeout(function(){
|
||||||
|
$.ccio.soundAlarmed = false
|
||||||
|
},user.details.audio_delay * 1000)
|
||||||
|
}
|
||||||
|
if($.ccio.windowFocus = true){
|
||||||
|
audio.play()
|
||||||
|
}else{
|
||||||
|
clearInterval($.ccio.soundAlarmInterval)
|
||||||
|
if(!user.details.audio_delay || user.details.audio_delay === ''){
|
||||||
|
user.details.audio_delay = 1
|
||||||
|
}else{
|
||||||
|
user.details.audio_delay = parseFloat(user.details.audio_delay)
|
||||||
|
}
|
||||||
|
$.ccio.soundAlarmInterval = setInterval(function(){
|
||||||
|
audio.play()
|
||||||
|
},user.details.audio_delay * 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(user.details.event_mon_pop === '1' && (!$.ccio.mon[d.ke+d.id+user.auth_token].popOut || $.ccio.mon[d.ke+d.id+user.auth_token].popOut.closed === true)){
|
||||||
|
d.e.find('[monitor="pop"]').click()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'init_success':
|
||||||
|
$('#monitors_list .link-monitors-list[auth="'+user.auth_token+'"][ke="'+user.ke+'"]').empty();
|
||||||
|
if(user===$user){
|
||||||
|
d.chosen_set='watch_on'
|
||||||
|
}else{
|
||||||
|
d.chosen_set='watch_on_links'
|
||||||
|
}
|
||||||
|
d.o=$.ccio.op()[d.chosen_set];
|
||||||
|
if(!d.o){d.o={}};
|
||||||
|
$.getJSON($.ccio.init('location',user)+user.auth_token+'/monitor/'+user.ke,function(f,g){
|
||||||
|
g=function(n,v){
|
||||||
|
$.ccio.mon[v.ke+v.mid+user.auth_token]=v;
|
||||||
|
v.user=user;
|
||||||
|
$.ccio.tm(1,v,null,user)
|
||||||
|
if(d.o[v.ke]&&d.o[v.ke][v.mid]===1){
|
||||||
|
$.ccio.cx({f:'monitor',ff:'watch_on',id:v.mid},user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(f.mid){
|
||||||
|
g(null,f)
|
||||||
|
}else{
|
||||||
|
$.each(f,g);
|
||||||
|
}
|
||||||
|
if($.ccio.op().jpeg_on===true){
|
||||||
|
$.ccio.cx({f:'monitor',ff:'jpeg_on'},user)
|
||||||
|
}
|
||||||
|
$.gR.drawList();
|
||||||
|
})
|
||||||
|
$.ccio.pm(3,d.apis,null,user);
|
||||||
|
$('.os_platform').html(d.os.platform)
|
||||||
|
$('.os_cpuCount').html(d.os.cpuCount)
|
||||||
|
$('.os_totalmem').html((d.os.totalmem/1000000).toFixed(2))
|
||||||
|
if(d.os.cpuCount>1){
|
||||||
|
$('.os_cpuCount_trailer').html('s')
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'get_videos':
|
||||||
|
$.ccio.pm(0,d,null,user)
|
||||||
|
break;
|
||||||
|
case'log':
|
||||||
|
var attr = '[mid="'+d.mid+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"]'
|
||||||
|
$.ccio.tm(4,d,'#logs,'+attr+'.monitor_item .logs:visible,'+attr+'#add_monitor:visible .logs',user)
|
||||||
|
break;
|
||||||
|
case'camera_cpu_usage':
|
||||||
|
var el = $('.monitor_item[auth="'+user.auth_token+'"][ke="'+d.ke+'"][mid="'+d.id+'"] .camera_cpu_usage')
|
||||||
|
.attr('title',d.percent + '% ' + lang['CPU used by this stream'])
|
||||||
|
el.find('.progress-bar').css('width',d.percent)
|
||||||
|
el.find('.percent').html(d.percent + '%')
|
||||||
|
break;
|
||||||
|
case'os'://indicator
|
||||||
|
//cpu
|
||||||
|
d.cpu=parseFloat(d.cpu).toFixed(0)+'%';
|
||||||
|
$('.cpu_load .progress-bar').css('width',d.cpu);
|
||||||
|
$('.cpu_load .percent').html(d.cpu);
|
||||||
|
//ram
|
||||||
|
d.ram=(100-parseFloat(d.ram)).toFixed(0)+'%';
|
||||||
|
$('.ram_load .progress-bar').css('width',d.ram);
|
||||||
|
$('.ram_load .percent').html(d.ram);
|
||||||
|
break;
|
||||||
|
case'diskUsed':
|
||||||
|
if(!d.limit||d.limit===''){d.limit=10000}
|
||||||
|
d.percent=parseInt((d.size/d.limit)*100)+'%';
|
||||||
|
d.human=parseFloat(d.size)
|
||||||
|
if(d.human>1000){d.human=(d.human/1000).toFixed(2)+' GB'}else{d.human=d.human.toFixed(2)+' MB'}
|
||||||
|
$('.diskUsed .value').html(d.human)
|
||||||
|
$('.diskUsed .percent').html(d.percent)
|
||||||
|
$('.diskUsed .progress-bar').css('width',d.percent)
|
||||||
|
break;
|
||||||
|
case'video_fix_success':case'video_fix_start':
|
||||||
|
switch(d.f){
|
||||||
|
case'video_fix_success':
|
||||||
|
d.addClass='fa-wrench'
|
||||||
|
d.removeClass='fa-pulse fa-spinner'
|
||||||
|
break;
|
||||||
|
case'video_fix_start':
|
||||||
|
d.removeClass='fa-wrench'
|
||||||
|
d.addClass='fa-pulse fa-spinner'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$('[mid="'+d.mid+'"][ke="'+d.ke+'"][file="'+d.filename+'"][auth="'+user.auth_token+'"] [video="fix"] i,[data-mid="'+d.mid+'"][data-ke="'+d.ke+'"][data-file="'+d.filename+'"][data-auth="'+user.auth_token+'"] [video="fix"] i').addClass(d.addClass).removeClass(d.removeClass)
|
||||||
|
break;
|
||||||
|
case'video_edit':case'video_archive':
|
||||||
|
$.ccio.init('data-video',d)
|
||||||
|
d.e=$('[file="'+d.filename+'"][mid="'+d.mid+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"],[data-file="'+d.filename+'"][data-mid="'+d.mid+'"][data-ke="'+d.ke+'"][data-auth="'+user.auth_token+'"]');
|
||||||
|
d.e.attr('status',d.status),d.e.attr('data-status',d.status);
|
||||||
|
console.log(d)
|
||||||
|
|
||||||
|
break;
|
||||||
|
case'video_delete':
|
||||||
|
// if($('.modal[mid="'+d.mid+'"][auth="'+user.auth_token+'"]').length>0){$('#video_viewer[mid="'+d.mid+'"]').attr('file',null).attr('ke',null).attr('mid',null).attr('auth',null).modal('hide')}
|
||||||
|
$('[file="'+d.filename+'"][mid="'+d.mid+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"]:not(.modal)').remove();
|
||||||
|
$('[data-file="'+d.filename+'"][data-mid="'+d.mid+'"][data-ke="'+d.ke+'"][data-auth="'+user.auth_token+'"]:not(.modal)').remove();
|
||||||
|
if($.pwrvid.currentDataObject&&$.pwrvid.currentDataObject[d.filename]){
|
||||||
|
delete($.timelapse.currentVideos[$.pwrvid.currentDataObject[d.filename].position])
|
||||||
|
$.pwrvid.drawTimeline(false)
|
||||||
|
}
|
||||||
|
if($.timelapse.currentVideos&&$.timelapse.currentVideos[d.filename]){
|
||||||
|
delete($.timelapse.currentVideosArray.videos[$.timelapse.currentVideos[d.filename].position])
|
||||||
|
$.timelapse.drawTimeline(false)
|
||||||
|
}
|
||||||
|
if($.vidview.loadedVideos && $.vidview.loadedVideos[d.filename])delete($.vidview.loadedVideos[d.filename])
|
||||||
|
break;
|
||||||
|
case'video_build_success':
|
||||||
|
if(!d.mid){d.mid=d.id;};d.status=1;
|
||||||
|
d.e='.glM'+d.mid+user.auth_token+'.videos_list ul,.glM'+d.mid+user.auth_token+'.videos_monitor_list ul';$(d.e).find('.notice.novideos').remove();
|
||||||
|
$.ccio.tm(0,d,d.e,user)
|
||||||
|
break;
|
||||||
|
case'monitor_snapshot':
|
||||||
|
setTimeout(function(){
|
||||||
|
var snapElement = $('[mid="'+d.mid+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"] .snapshot')
|
||||||
|
switch(d.snapshot_format){
|
||||||
|
case'plc':
|
||||||
|
snapElement.attr('src',placeholder.getData(placeholder.plcimg(d.snapshot)))
|
||||||
|
break;
|
||||||
|
case'ab':
|
||||||
|
d.reader = new FileReader();
|
||||||
|
d.reader.addEventListener("loadend",function(){snapElement.attr('src',d.reader.result)});
|
||||||
|
d.reader.readAsDataURL(new Blob([d.snapshot],{type:"image/jpeg"}));
|
||||||
|
break;
|
||||||
|
case'b64':
|
||||||
|
snapElement.attr('src','data:image/jpeg;base64,'+d.snapshot)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},1000)
|
||||||
|
break;
|
||||||
|
case'monitor_delete':
|
||||||
|
$('[mid="'+d.mid+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"]:not(.modal)').remove();
|
||||||
|
$.ccio.init('clearTimers',d)
|
||||||
|
delete($.ccio.mon[d.ke+d.mid+user.auth_token]);
|
||||||
|
break;
|
||||||
|
case'monitor_watch_off':case'monitor_stopping':
|
||||||
|
if(user===$user){
|
||||||
|
d.chosen_set='watch_on'
|
||||||
|
}else{
|
||||||
|
d.chosen_set='watch_on_links'
|
||||||
|
}
|
||||||
|
d.o=$.ccio.op()[d.chosen_set];
|
||||||
|
if(!d.o[d.ke]){d.o[d.ke]={}};d.o[d.ke][d.id]=0;$.ccio.op(d.chosen_set,d.o);
|
||||||
|
$.ccio.destroyStream(d,user,(d.f === 'monitor_watch_off'))
|
||||||
|
break;
|
||||||
|
case'monitor_watch_on':
|
||||||
|
if(user===$user){
|
||||||
|
d.chosen_set='watch_on'
|
||||||
|
}else{
|
||||||
|
d.chosen_set='watch_on_links'
|
||||||
|
}
|
||||||
|
d.o=$.ccio.op()[d.chosen_set];
|
||||||
|
if(!d.o){d.o={}};if(!d.o[d.ke]){d.o[d.ke]={}};d.o[d.ke][d.id]=1;$.ccio.op(d.chosen_set,d.o);
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].watch=1;
|
||||||
|
delete($.ccio.mon[d.ke+d.id+user.auth_token].image)
|
||||||
|
delete($.ccio.mon[d.ke+d.id+user.auth_token].ctx)
|
||||||
|
d.e=$('#monitor_live_'+d.id+user.auth_token);
|
||||||
|
d.e.find('.stream-detected-object').remove()
|
||||||
|
$.ccio.init('clearTimers',d)
|
||||||
|
if(d.e.length === 1){
|
||||||
|
$.ccio.init('closeVideo',{mid:d.id,ke:d.ke},user);
|
||||||
|
}
|
||||||
|
if(d.e.length === 0){
|
||||||
|
$.ccio.tm(2,$.ccio.mon[d.ke+d.id+user.auth_token],'#monitors_live',user);
|
||||||
|
}
|
||||||
|
d.d=JSON.parse($.ccio.mon[d.ke+d.id+user.auth_token].details);
|
||||||
|
$.ccio.tm('stream-element',$.ccio.mon[d.ke+d.id+user.auth_token],null,user);
|
||||||
|
if($.ccio.op().jpeg_on===true){
|
||||||
|
$.ccio.init('jpegMode',$.ccio.mon[d.ke+d.id+user.auth_token]);
|
||||||
|
}else{
|
||||||
|
var path = tool.checkCorrectPathEnding(location.pathname)+'socket.io'
|
||||||
|
switch(d.d.stream_type){
|
||||||
|
case'jpeg':
|
||||||
|
$.ccio.init('jpegMode',$.ccio.mon[d.ke+d.id+user.auth_token]);
|
||||||
|
break;
|
||||||
|
case'b64':
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].Base64 && $.ccio.mon[d.ke+d.id+user.auth_token].Base64.connected){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].Base64.disconnect()
|
||||||
|
}
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].Base64 = io(location.origin,{ path: path, transports: ['websocket'], forceNew: false})
|
||||||
|
var ws = $.ccio.mon[d.ke+d.id+user.auth_token].Base64
|
||||||
|
var buffer
|
||||||
|
ws.on('diconnect',function(){
|
||||||
|
console.log('Base64 Stream Disconnected')
|
||||||
|
})
|
||||||
|
ws.on('connect',function(){
|
||||||
|
ws.emit('Base64',{
|
||||||
|
auth: user.auth_token,
|
||||||
|
uid: user.uid,
|
||||||
|
ke: d.ke,
|
||||||
|
id: d.id,
|
||||||
|
// channel: channel
|
||||||
|
})
|
||||||
|
if(!$.ccio.mon[d.ke+d.id+user.auth_token].ctx||$.ccio.mon[d.ke+d.id+user.auth_token].ctx.length===0){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].ctx = $('#monitor_live_'+d.id+user.auth_token+' canvas');
|
||||||
|
}
|
||||||
|
var ctx = $.ccio.mon[d.ke+d.id+user.auth_token].ctx[0]
|
||||||
|
var ctx2d = ctx.getContext("2d")
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].image = new Image()
|
||||||
|
var image = $.ccio.mon[d.ke+d.id+user.auth_token].image
|
||||||
|
image.onload = function() {
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].imageLoading = false
|
||||||
|
d.x = 0
|
||||||
|
d.y = 0
|
||||||
|
// d.ratio = Math.min(ctx.width/image.width,ctx.height/image.height)
|
||||||
|
// d.height = image.height * d.ratio
|
||||||
|
// d.width = image.width * d.ratio
|
||||||
|
// if(d.width < ctx.width){
|
||||||
|
// d.x = (ctx.width / 2) - (d.width / 2)
|
||||||
|
// }
|
||||||
|
// if(d.height < ctx.height){
|
||||||
|
// d.y = (ctx.height / 2) - (d.height / 2)
|
||||||
|
// }
|
||||||
|
// ctx.getContext("2d").drawImage(image,d.x,d.y,d.width,d.height)
|
||||||
|
ctx.getContext("2d").drawImage(image,d.x,d.y,ctx.width,ctx.height)
|
||||||
|
URL.revokeObjectURL($.ccio.mon[d.ke+d.id+user.auth_token].imageUrl)
|
||||||
|
}
|
||||||
|
ws.on('data',function(imageData){
|
||||||
|
try{
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].imageLoading === true)return console.log('drop');
|
||||||
|
// var base64Frame = 'data:image/jpeg;base64,'+$.ccio.base64ArrayBuffer(imageData)
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].imageLoading = true
|
||||||
|
// $.ccio.mon[d.ke+d.id+user.auth_token].image.src = base64Frame
|
||||||
|
var arrayBufferView = new Uint8Array(imageData);
|
||||||
|
var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } );
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].imageUrl = URL.createObjectURL( blob );
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].image.src = $.ccio.mon[d.ke+d.id+user.auth_token].imageUrl
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].last_frame = 'data:image/jpeg;base64,'+$.ccio.base64ArrayBuffer(imageData)
|
||||||
|
}catch(er){
|
||||||
|
console.log(er)
|
||||||
|
$.ccio.log('base64 frame')
|
||||||
|
}
|
||||||
|
$.ccio.init('signal',d);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case'mp4':
|
||||||
|
setTimeout(function(){
|
||||||
|
var stream = d.e.find('.stream-element');
|
||||||
|
var onPoseidonError = function(){
|
||||||
|
// setTimeout(function(){
|
||||||
|
// $.ccio.cx({f:'monitor',ff:'watch_on',id:d.id},user)
|
||||||
|
// },5000)
|
||||||
|
}
|
||||||
|
if(!$.ccio.mon[d.ke+d.id+user.auth_token].PoseidonErrorCount)$.ccio.mon[d.ke+d.id+user.auth_token].PoseidonErrorCount = 0
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].PoseidonErrorCount >= 5)return
|
||||||
|
if(d.d.stream_flv_type==='ws'){
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].Poseidon){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].Poseidon.stop()
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].Poseidon = new Poseidon({
|
||||||
|
video: stream[0],
|
||||||
|
auth_token:user.auth_token,
|
||||||
|
ke:d.ke,
|
||||||
|
uid:user.uid,
|
||||||
|
id:d.id,
|
||||||
|
url: location.origin,
|
||||||
|
path: path,
|
||||||
|
onError : onPoseidonError
|
||||||
|
})
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].Poseidon.start();
|
||||||
|
}catch(err){
|
||||||
|
// onPoseidonError()
|
||||||
|
console.log('onTryPoseidonError',err)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
stream.attr('src',$.ccio.init('location',user)+user.auth_token+'/mp4/'+d.ke+'/'+d.id+'/s.mp4')
|
||||||
|
stream[0].onerror = function(err){
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},2000)
|
||||||
|
break;
|
||||||
|
case'flv':
|
||||||
|
if (flvjs.isSupported()) {
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].flv){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].flv.destroy()
|
||||||
|
}
|
||||||
|
var options = {};
|
||||||
|
if(d.d.stream_flv_type==='ws'){
|
||||||
|
if(d.d.stream_flv_maxLatency&&d.d.stream_flv_maxLatency!==''){
|
||||||
|
d.d.stream_flv_maxLatency = parseInt(d.d.stream_flv_maxLatency)
|
||||||
|
}else{
|
||||||
|
d.d.stream_flv_maxLatency = 20000;
|
||||||
|
}
|
||||||
|
options = {
|
||||||
|
type: 'flv',
|
||||||
|
isLive: true,
|
||||||
|
auth_token:user.auth_token,
|
||||||
|
ke:d.ke,
|
||||||
|
uid:user.uid,
|
||||||
|
id:d.id,
|
||||||
|
maxLatency:d.d.stream_flv_maxLatency,
|
||||||
|
hasAudio:false,
|
||||||
|
url: location.origin,
|
||||||
|
path: path
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
options = {
|
||||||
|
type: 'flv',
|
||||||
|
isLive: true,
|
||||||
|
url: $.ccio.init('location',user)+user.auth_token+'/flv/'+d.ke+'/'+d.id+'/s.flv'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].flv = flvjs.createPlayer(options);
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].flv.attachMediaElement($('#monitor_live_'+d.id+user.auth_token+' .stream-element')[0]);
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].flv.on('error',function(err){
|
||||||
|
console.log(err)
|
||||||
|
});
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].flv.load();
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].flv.play();
|
||||||
|
}else{
|
||||||
|
$.ccio.init('note',{title:'Stream cannot be started',text:'FLV.js is not supported on this browser. Try another stream type.',type:'error'});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'hls':
|
||||||
|
d.fn=function(){
|
||||||
|
clearTimeout($.ccio.mon[d.ke+d.id+user.auth_token].m3uCheck)
|
||||||
|
d.url=$.ccio.init('location',user)+user.auth_token+'/hls/'+d.ke+'/'+d.id+'/s.m3u8';
|
||||||
|
$.get(d.url,function(m3u){
|
||||||
|
if(m3u=='File Not Found'){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].m3uCheck=setTimeout(function(){
|
||||||
|
d.fn()
|
||||||
|
},2000)
|
||||||
|
}else{
|
||||||
|
var video = $('#monitor_live_'+d.id+user.auth_token+' .stream-element')[0];
|
||||||
|
if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)||(navigator.userAgent.match(/(Safari)/)&&!navigator.userAgent.match('Chrome'))) {
|
||||||
|
video.src=d.url;
|
||||||
|
if (video.paused) {
|
||||||
|
video.play();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].hlsGarbageCollector=function(){
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].hls){$.ccio.mon[d.ke+d.id+user.auth_token].hls.destroy();URL.revokeObjectURL(video.src)}
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].hls = new Hls();
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].hls.loadSource(d.url);
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].hls.attachMedia(video);
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].hls.on(Hls.Events.MANIFEST_PARSED,function() {
|
||||||
|
if (video.paused) {
|
||||||
|
video.play();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].hlsGarbageCollector()
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].hlsGarbageCollectorTimer=setInterval($.ccio.mon[d.ke+d.id+user.auth_token].hlsGarbageCollector,1000*60*20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
d.fn()
|
||||||
|
break;
|
||||||
|
case'mjpeg':
|
||||||
|
$('#monitor_live_'+d.id+user.auth_token+' .stream-element').attr('src',$.ccio.init('location',user)+user.auth_token+'/mjpeg/'+d.ke+'/'+d.id+'/?full=true')
|
||||||
|
break;
|
||||||
|
case'h265':
|
||||||
|
var player = $.ccio.mon[d.ke+d.id+user.auth_token].h265Player
|
||||||
|
var video = $('#monitor_live_'+d.id+user.auth_token+' .stream-element')[0]
|
||||||
|
if (player) {
|
||||||
|
player.stop()
|
||||||
|
}
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].h265Player = new libde265.RawPlayer(video)
|
||||||
|
var player = $.ccio.mon[d.ke+d.id+user.auth_token].h265Player
|
||||||
|
player.set_status_callback(function(msg, fps) {
|
||||||
|
})
|
||||||
|
player.launch()
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].h265Socket && $.ccio.mon[d.ke+d.id+user.auth_token].h265Socket.connected){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].h265Socket.disconnect()
|
||||||
|
}
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].h265HttpStream && $.ccio.mon[d.ke+d.id+user.auth_token].abort){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].h265HttpStream.abort()
|
||||||
|
}
|
||||||
|
if(d.d.stream_flv_type==='ws'){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].h265Socket = io(location.origin,{ path: path, transports: ['websocket'], forceNew: false})
|
||||||
|
var ws = $.ccio.mon[d.ke+d.id+user.auth_token].h265Socket
|
||||||
|
ws.on('diconnect',function(){
|
||||||
|
console.log('h265Socket Stream Disconnected')
|
||||||
|
})
|
||||||
|
ws.on('connect',function(){
|
||||||
|
ws.emit('h265',{
|
||||||
|
auth: user.auth_token,
|
||||||
|
uid: user.uid,
|
||||||
|
ke: d.ke,
|
||||||
|
id: d.id,
|
||||||
|
// channel: channel
|
||||||
|
})
|
||||||
|
ws.on('data',function(imageData){
|
||||||
|
player._handle_onChunk(imageData)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
var url = $.ccio.init('location',user)+user.auth_token+'/h265/'+d.ke+'/'+d.id+'/s.hevc';
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].h265HttpStream = player.createHttpStream(url)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.signal=parseFloat(d.d.signal_check);
|
||||||
|
if(!d.signal||d.signal==NaN){d.signal=10;};d.signal=d.signal*1000*60;
|
||||||
|
if(d.signal>0){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].signal=setInterval(function(){$.ccio.init('signal-check',{id:d.id,ke:d.ke})},d.signal);
|
||||||
|
}
|
||||||
|
d.e=$('.monitor_item[mid="'+d.id+'"][ke="'+d.ke+'"][auth="'+user.auth_token+'"]').resize()
|
||||||
|
if(d.e.find('.videos_monitor_list li').length===0){
|
||||||
|
d.dr=$('#videos_viewer_daterange').data('daterangepicker');
|
||||||
|
$.getJSON($.ccio.init('location',user)+user.auth_token+'/videos/'+d.ke+'/'+d.id+'?limit=10',function(f){
|
||||||
|
$.ccio.pm(0,{videos:f.videos,ke:d.ke,mid:d.id},null,user)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setTimeout(function(){
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].motionDetectionRunning===true){
|
||||||
|
$.ccio.init('streamMotionDetectRestart',{mid:d.id,ke:d.ke,mon:$.ccio.mon[d.ke+d.id+user.auth_token]},user);
|
||||||
|
}
|
||||||
|
},3000)
|
||||||
|
break;
|
||||||
|
case'pam_frame':
|
||||||
|
if(!$.ccio.mon[d.ke+d.id+user.auth_token].ctx||$.ccio.mon[d.ke+d.id+user.auth_token].ctx.length===0){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].ctx = $('#monitor_live_'+d.id+user.auth_token+' canvas');
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].ctxContext = $.ccio.mon[d.ke+d.id+user.auth_token].ctx[0].getContext('2d');
|
||||||
|
}
|
||||||
|
var ctx = $.ccio.mon[d.ke+d.id+user.auth_token].ctxContext;
|
||||||
|
d.x = 0,d.y = 0;
|
||||||
|
d.ratio = Math.min($.ccio.mon[d.ke+d.id+user.auth_token].ctx.width()/d.imageData.width,$.ccio.mon[d.ke+d.id+user.auth_token].ctx.height()/d.imageData.height);
|
||||||
|
d.height = d.imageData.height*d.ratio;
|
||||||
|
d.width = d.imageData.width*d.ratio;
|
||||||
|
if( d.width < $.ccio.mon[d.ke+d.id+user.auth_token].ctx.width() )
|
||||||
|
d.x = ($.ccio.mon[d.ke+d.id+user.auth_token].ctx.width() / 2) - (d.width / 2);
|
||||||
|
if( d.height < $.ccio.mon[d.ke+d.id+user.auth_token].ctx.height() )
|
||||||
|
d.y = ($.ccio.mon[d.ke+d.id+user.auth_token].ctx.height() / 2) - (d.height / 2);
|
||||||
|
var imageData = ctx.createImageData(d.width,d.height)
|
||||||
|
imageData.data.set(new Uint8ClampedArray(d.imageData.data))
|
||||||
|
console.log(imageData)
|
||||||
|
ctx.putImageData(imageData, 0, 0);
|
||||||
|
break;
|
||||||
|
case'monitor_frame':
|
||||||
|
try{
|
||||||
|
if($.ccio.mon[d.ke+d.id+user.auth_token].imageLoading === true)return
|
||||||
|
if(!$.ccio.mon[d.ke+d.id+user.auth_token].ctx||$.ccio.mon[d.ke+d.id+user.auth_token].ctx.length===0){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].ctx = $('#monitor_live_'+d.id+user.auth_token+' canvas');
|
||||||
|
}
|
||||||
|
var ctx = $.ccio.mon[d.ke+d.id+user.auth_token].ctx[0]
|
||||||
|
if(!$.ccio.mon[d.ke+d.id+user.auth_token].image){
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].image = new Image()
|
||||||
|
var image = $.ccio.mon[d.ke+d.id+user.auth_token].image
|
||||||
|
image.onload = function() {
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].imageLoading = false
|
||||||
|
d.x = 0
|
||||||
|
d.y = 0
|
||||||
|
// d.ratio = Math.min(ctx.width/image.width,ctx.height/image.height)
|
||||||
|
// d.height = image.height * d.ratio
|
||||||
|
// d.width = image.width * d.ratio
|
||||||
|
// if(d.width < ctx.width){
|
||||||
|
// d.x = (ctx.width / 2) - (d.width / 2)
|
||||||
|
// }
|
||||||
|
// if(d.height < ctx.height){
|
||||||
|
// d.y = (ctx.height / 2) - (d.height / 2)
|
||||||
|
// }
|
||||||
|
// ctx.getContext("2d").drawImage(image,d.x,d.y,d.width,d.height)
|
||||||
|
ctx.getContext("2d").drawImage(image,d.x,d.y,ctx.width,ctx.height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var base64Frame = 'data:image/jpeg;base64,'+d.frame
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].imageLoading = true
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].image.src = base64Frame
|
||||||
|
$.ccio.mon[d.ke+d.id+user.auth_token].last_frame = base64Frame
|
||||||
|
}catch(er){
|
||||||
|
console.log(er)
|
||||||
|
$.ccio.log('base64 frame')
|
||||||
|
}
|
||||||
|
$.ccio.init('signal',d);
|
||||||
|
break;
|
||||||
|
case'monitor_edit':
|
||||||
|
$.ccio.init('clearTimers',d)
|
||||||
|
d.e=$('[mid="'+d.mon.mid+'"][ke="'+d.mon.ke+'"][auth="'+user.auth_token+'"]');
|
||||||
|
d.e=$('#monitor_live_'+d.mid+user.auth_token);
|
||||||
|
d.e.find('.stream-detected-object').remove()
|
||||||
|
if(d.mon.details.control=="1"){d.e.find('[monitor="control_toggle"]').show()}else{d.e.find('.pad').remove();d.e.find('[monitor="control_toggle"]').hide()}
|
||||||
|
if(user===$user){
|
||||||
|
d.chosen_set='watch_on'
|
||||||
|
}else{
|
||||||
|
d.chosen_set='watch_on_links'
|
||||||
|
}
|
||||||
|
d.o=$.ccio.op()[d.chosen_set];
|
||||||
|
if(!d.o){d.o={}}
|
||||||
|
if(d.mon.details.cords instanceof Object){d.mon.details.cords=JSON.stringify(d.mon.details.cords);}
|
||||||
|
d.mon.details=JSON.stringify(d.mon.details);
|
||||||
|
if(!$.ccio.mon[d.ke+d.mid+user.auth_token]){$.ccio.mon[d.ke+d.mid+user.auth_token]={}}
|
||||||
|
$.ccio.init('jpegModeStop',d);
|
||||||
|
$.ccio.mon[d.ke+d.mid+user.auth_token].previousStreamType=d.mon.details.stream_type
|
||||||
|
$.each(d.mon,function(n,v){
|
||||||
|
$.ccio.mon[d.ke+d.mid+user.auth_token][n]=v;
|
||||||
|
});
|
||||||
|
$.ccio.mon[d.ke+d.mid+user.auth_token].user=user
|
||||||
|
if(d.new===true){$.ccio.tm(1,d.mon,null,user)}
|
||||||
|
switch(d.mon.mode){
|
||||||
|
case'start':case'record':
|
||||||
|
if(d.o[d.ke]&&d.o[d.ke][d.mid]===1){
|
||||||
|
$.ccio.cx({f:'monitor',ff:'watch_on',id:d.mid},user)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$.ccio.init('monitorInfo',d)
|
||||||
|
$.gR.drawList();
|
||||||
|
if(!d.silenceNote){
|
||||||
|
$.ccio.init('note',{title:'Monitor Saved',text:'<b>'+d.mon.name+'</b> <small>'+d.mon.mid+'</small> has been saved.',type:'success'});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'monitor_starting':
|
||||||
|
// switch(d.mode){case'start':d.mode='Watch';break;case'record':d.mode='Record';break;}
|
||||||
|
// $.ccio.init('note',{title:'Monitor Starting',text:'Monitor <b>'+d.mid+'</b> is now running in mode <b>'+d.mode+'</b>',type:'success'});
|
||||||
|
d.e=$('#monitor_live_'+d.mid+user.auth_token)
|
||||||
|
if(d.e.length>0){$.ccio.cx({f:'monitor',ff:'watch_on',id:d.mid},user)}
|
||||||
|
break;
|
||||||
|
case'mode_jpeg_off':
|
||||||
|
$.ccio.op('jpeg_on',"0");
|
||||||
|
$.each($.ccio.mon,function(n,v,x){
|
||||||
|
$.ccio.init('jpegModeStop',v);
|
||||||
|
if(v.watch===1){
|
||||||
|
$.ccio.cx({f:'monitor',ff:'watch_on',id:v.mid},user)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('body').removeClass('jpegMode')
|
||||||
|
break;
|
||||||
|
case'mode_jpeg_on':
|
||||||
|
$.ccio.op('jpeg_on',true);
|
||||||
|
$.ccio.init('jpegModeAll');
|
||||||
|
$('body').addClass('jpegMode')
|
||||||
|
break;
|
||||||
|
case'drawPowerVideoMainTimeLine':
|
||||||
|
var videos = d.videos;
|
||||||
|
var events = d.events;
|
||||||
|
// $.pwrvid.currentlyLoading = false
|
||||||
|
$.pwrvid.currentVideos=videos
|
||||||
|
$.pwrvid.currentEvents=events
|
||||||
|
$.pwrvid.e.find('.loading').hide()
|
||||||
|
$.pwrvid.e.find('.nodata').hide()
|
||||||
|
//$.pwrvid.drawTimeLine
|
||||||
|
if($.pwrvid.t&&$.pwrvid.t.destroy){$.pwrvid.t.destroy()}
|
||||||
|
data={};
|
||||||
|
$.each(videos.videos,function(n,v){
|
||||||
|
if(!v||!v.mid){return}
|
||||||
|
v.mon=$.ccio.mon[v.ke+v.mid+$user.auth_token];
|
||||||
|
// v.filename=$.ccio.init('tf',v.time)+'.'+v.ext;
|
||||||
|
if(v.status>0){
|
||||||
|
// data.push({src:v,x:v.time,y:$.ccio.timeObject(v.time).diff($.ccio.timeObject(v.end),'minutes')/-1})
|
||||||
|
data[v.filename]={
|
||||||
|
filename:v.filename,
|
||||||
|
time:v.time,
|
||||||
|
timeFormatted:$.ccio.timeObject(v.time).format('MM/DD/YYYY HH:mm'),
|
||||||
|
endTime:v.end,
|
||||||
|
close:$.ccio.timeObject(v.time).diff($.ccio.timeObject(v.end),'minutes')/-1,
|
||||||
|
motion:[],
|
||||||
|
row:v,
|
||||||
|
position:n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var eventsToCheck = Object.assign({},events)
|
||||||
|
$.each(data,function(m,b){
|
||||||
|
startTimeFormatted = $.ccio.timeObject(b.time).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
startTime = $.ccio.timeObject(b.time).format();
|
||||||
|
endTime = $.ccio.timeObject(b.endTime).format();
|
||||||
|
var newSetOfEventsWithoutChecked = {};
|
||||||
|
var eventTime
|
||||||
|
$.each(eventsToCheck,function(n,v){
|
||||||
|
try{
|
||||||
|
if(v.details.videoTime.indexOf('T') > -1){
|
||||||
|
eventTime = v.details.videoTime.split('T');
|
||||||
|
}else{
|
||||||
|
eventTime = v.details.videoTime.split(' ');
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
if(v.time.indexOf('T') > -1){
|
||||||
|
eventTime = v.time.split('T');
|
||||||
|
}else{
|
||||||
|
eventTime = v.time.split(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eventTime[1] = eventTime[1].replace(/-/g,':'),eventTime = eventTime.join(' ');
|
||||||
|
if(eventTime === startTimeFormatted){
|
||||||
|
data[m].motion.push(v)
|
||||||
|
}else if ($.ccio.timeObject(v.time).isBetween(startTime,$.ccio.timeObject(b.endTime).format())) {
|
||||||
|
data[m].motion.push(v)
|
||||||
|
}else{
|
||||||
|
newSetOfEventsWithoutChecked[n] = v;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
eventsToCheck = newSetOfEventsWithoutChecked;
|
||||||
|
});
|
||||||
|
$.pwrvid.currentDataObject=data;
|
||||||
|
if($.pwrvid.chart){
|
||||||
|
$.pwrvid.d.empty()
|
||||||
|
delete($.pwrvid.chart)
|
||||||
|
}
|
||||||
|
$.pwrvid.currentData=Object.values(data);
|
||||||
|
if($.pwrvid.currentData.length>0){
|
||||||
|
var labels=[]
|
||||||
|
var Dataset1=[]
|
||||||
|
var Dataset2=[]
|
||||||
|
$.each(data,function(n,v){
|
||||||
|
labels.push(v.timeFormatted)
|
||||||
|
Dataset1.push(v.close)
|
||||||
|
Dataset2.push(v.motion.length)
|
||||||
|
})
|
||||||
|
$.pwrvid.d.html("<canvas></canvas>")
|
||||||
|
var timeFormat = 'MM/DD/YYYY HH:mm';
|
||||||
|
var color = Chart.helpers.color;
|
||||||
|
Chart.defaults.global.defaultFontColor = '#fff';
|
||||||
|
var config = {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: labels,
|
||||||
|
datasets: [{
|
||||||
|
type: 'line',
|
||||||
|
label: lang['Video and Time Span (Minutes)'],
|
||||||
|
backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),
|
||||||
|
borderColor: window.chartColors.blue,
|
||||||
|
data: Dataset1,
|
||||||
|
}, {
|
||||||
|
type: 'bar',
|
||||||
|
showTooltip: false,
|
||||||
|
label: lang['Counts of Motion'],
|
||||||
|
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
|
||||||
|
borderColor: window.chartColors.red,
|
||||||
|
data:Dataset2,
|
||||||
|
}, ]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
fontColor: "white",
|
||||||
|
text: lang['Video Length (minutes) and Motion Count per video']
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
callbacks: {
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
type: "time",
|
||||||
|
display: true,
|
||||||
|
time: {
|
||||||
|
format: timeFormat,
|
||||||
|
// round: 'day'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var ctx = $.pwrvid.d.find('canvas')[0].getContext("2d");
|
||||||
|
$.pwrvid.chart = new Chart(ctx, config);
|
||||||
|
$.pwrvid.d.find('canvas').click(function(e) {
|
||||||
|
var target = $.pwrvid.chart.getElementsAtEvent(e)[0];
|
||||||
|
if(!target){return false}
|
||||||
|
target = $.pwrvid.currentData[target._index];
|
||||||
|
$.pwrvid.e.find('.temp').html('<li class="glM'+target.row.mid+$user.auth_token+'" mid="'+target.row.mid+'" ke="'+target.row.ke+'" status="'+target.row.status+'" file="'+target.row.filename+'" auth="'+$user.auth_token+'"><a class="btn btn-sm btn-primary" preview="video" href="'+target.row.href+'"><i class="fa fa-play-circle"></i></a></li>').find('a').click()
|
||||||
|
});
|
||||||
|
var colorNames = Object.keys(window.chartColors);
|
||||||
|
}else{
|
||||||
|
$.pwrvid.e.find('.nodata').show()
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$user.ws=io(location.origin,{
|
||||||
|
path : tool.checkCorrectPathEnding(location.pathname)+'socket.io'
|
||||||
|
});
|
||||||
|
$user.ws.on('connect',function (d){
|
||||||
|
$(document).ready(function(e){
|
||||||
|
$.ccio.init('id',$user);
|
||||||
|
$.ccio.cx({f:'init',ke:$user.ke,auth:$user.auth_token,uid:$user.uid})
|
||||||
|
if($user.details&&$user.details.links){
|
||||||
|
$.each($user.details.links,function(n,v){
|
||||||
|
if(v.secure==='0'){
|
||||||
|
v.protocol='http'
|
||||||
|
}else{
|
||||||
|
v.protocol='https'
|
||||||
|
}
|
||||||
|
if(v.host.indexOf('://')>-1){
|
||||||
|
v.URL=v.protocol+'://'+v.host.split('://')[1]
|
||||||
|
}else{
|
||||||
|
v.URL=v.protocol+'://'+v.host
|
||||||
|
}
|
||||||
|
$.get(v.URL+'/'+v.api+'/userInfo/'+v.ke,function(e){
|
||||||
|
if(e.ok===true){
|
||||||
|
e.user.auth_token=v.api
|
||||||
|
$.users[v.api]=e.user
|
||||||
|
$.users[v.api].info=v
|
||||||
|
$.users[v.api].ws=io(v.host)
|
||||||
|
$.users[v.api].ws.on('ping', function(d){
|
||||||
|
$.users[v.api].ws.emit('pong',{beat:1});
|
||||||
|
});
|
||||||
|
$.users[v.api].ws.on('connect',function (d){
|
||||||
|
console.log(v.host,'connected')
|
||||||
|
$.ccio.cx({f:'init',ke:e.user.ke,auth:v.api,uid:e.user.uid},$.users[v.api])
|
||||||
|
})
|
||||||
|
$.users[v.api].ws.on('f',function (d){
|
||||||
|
$.ccio.globalWebsocket(d,$.users[v.api])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
PNotify.prototype.options.styling = "fontawesome";
|
||||||
|
$user.ws.on('ping', function(d){
|
||||||
|
$user.ws.emit('pong',{beat:1});
|
||||||
|
});
|
||||||
|
$user.ws.on('f',function (d){
|
||||||
|
$.ccio.globalWebsocket(d)
|
||||||
|
switch(d.f){
|
||||||
|
case'api_key_deleted':
|
||||||
|
if($user.uid === d.uid){
|
||||||
|
$.ccio.init('note',{title:lang['API Key Deleted'],text:lang.APIKeyDeletedText,type:'notice'});
|
||||||
|
$('[api_key="'+d.form.code+'"]').remove()
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'api_key_added':
|
||||||
|
if($user.uid === d.uid){
|
||||||
|
$.ccio.init('note',{title:lang['API Key Added'],text:lang.FiltersUpdatedText,type:'success'});
|
||||||
|
$.ccio.tm(3,d.form,'#api_list')
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'filters_change':
|
||||||
|
$.ccio.init('note',{title:lang['Filters Updated'],text:lang.FiltersUpdatedText,type:'success'});
|
||||||
|
$user.details.filters=d.filters;
|
||||||
|
$.ccio.init('filters');
|
||||||
|
break;
|
||||||
|
case'user_settings_change':
|
||||||
|
$.ccio.init('note',{title:lang['Settings Changed'],text:lang.SettingsChangedText,type:'success'});
|
||||||
|
$.ccio.init('id',d.form);
|
||||||
|
d.form.details=JSON.parse(d.form.details)
|
||||||
|
$('#custom_css').append(d.form.details.css)
|
||||||
|
if(d.form.details){
|
||||||
|
$user.details=d.form.details
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'users_online':
|
||||||
|
$.ccio.pm('user-row',d.users);
|
||||||
|
break;
|
||||||
|
case'user_status_change':
|
||||||
|
if(d.status===1){
|
||||||
|
$.ccio.tm('user-row',d.user,null)
|
||||||
|
}else{
|
||||||
|
$('.user-row[uid="'+d.uid+'"][ke="'+d.ke+'"]').remove()
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'ffprobe_stop':
|
||||||
|
$.pB.e.find('._loading').hide()
|
||||||
|
$.pB.o.append('<div><b>END</b></div>');
|
||||||
|
$.pB.e.find('.stop').hide();
|
||||||
|
$.pB.e.find('[type="submit"]').show();
|
||||||
|
break;
|
||||||
|
case'ffprobe_start':
|
||||||
|
$.pB.e.find('._loading').show()
|
||||||
|
$.pB.o.empty();
|
||||||
|
$.pB.e.find('.stop').show();
|
||||||
|
$.pB.e.find('[type="submit"]').hide();
|
||||||
|
break;
|
||||||
|
case'ffprobe_data':
|
||||||
|
$.pB.results=JSON.parse(d.data)
|
||||||
|
$.pB.o.append($.ccio.init('jsontoblock',$.pB.results))
|
||||||
|
break;
|
||||||
|
case'detector_cascade_list':
|
||||||
|
d.tmp=''
|
||||||
|
$.each(d.cascades,function(n,v){
|
||||||
|
d.tmp+='<li class="mdl-list__item">';
|
||||||
|
d.tmp+='<span class="mdl-list__item-primary-content">';
|
||||||
|
d.tmp+=v;
|
||||||
|
d.tmp+='</span>';
|
||||||
|
d.tmp+='<span class="mdl-list__item-secondary-action">';
|
||||||
|
d.tmp+='<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">';
|
||||||
|
d.tmp+='<input type="checkbox" value="'+v+'" detailContainer="detector_cascades" detailObject="'+v+'" class="detector_cascade_selection mdl-switch__input"/>';
|
||||||
|
d.tmp+='</label>';
|
||||||
|
d.tmp+='</span>';
|
||||||
|
d.tmp+='</li>';
|
||||||
|
})
|
||||||
|
$('#detector_cascade_list').html(d.tmp)
|
||||||
|
componentHandler.upgradeAllRegistered()
|
||||||
|
//add auto select for preferences
|
||||||
|
d.currentlyEditing=$.aM.e.attr('mid')
|
||||||
|
if(d.currentlyEditing&&d.currentlyEditing!==''){
|
||||||
|
d.currentlyEditing=JSON.parse(JSON.parse($.ccio.mon[d.currentlyEditing].details).detector_cascades)
|
||||||
|
$.each(d.currentlyEditing,function(m,b){
|
||||||
|
d.e=$('.detector_cascade_selection[value="'+m+'"]').prop('checked',true)
|
||||||
|
d.p=d.e.parents('.mdl-js-switch')
|
||||||
|
if(d.p.length>0){
|
||||||
|
d.p.addClass('is-checked')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case'detector_plugged':
|
||||||
|
if(!d.notice){d.notice=''}
|
||||||
|
$('.shinobi-detector').show()
|
||||||
|
$('.shinobi-detector-msg').html(d.notice)
|
||||||
|
$('.shinobi-detector_name').text(d.plug)
|
||||||
|
$('.shinobi-detector-'+d.plug).show()
|
||||||
|
$('.shinobi-detector-invert').hide()
|
||||||
|
$.aM.drawList()
|
||||||
|
break;
|
||||||
|
case'detector_unplugged':
|
||||||
|
$('.stream-objects .stream-detected-object').remove()
|
||||||
|
$('.shinobi-detector').hide()
|
||||||
|
$('.shinobi-detector-msg').empty()
|
||||||
|
$('.shinobi-detector_name').empty()
|
||||||
|
$('.shinobi-detector_plug').hide()
|
||||||
|
$('.shinobi-detector-invert').show()
|
||||||
|
$.aM.drawList()
|
||||||
|
break;
|
||||||
|
case'monitor_edit_failed':
|
||||||
|
d.pnote={title:'Monitor Not Saved',text:'<b>'+d.mon.name+'</b> <small>'+d.mon.mid+'</small> has not been saved.',type:'error'}
|
||||||
|
switch(d.ff){
|
||||||
|
case'max_reached':
|
||||||
|
d.pnote.text+=' '+lang.monitorEditFailedMaxReached
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$.ccio.init('note',d.pnote);
|
||||||
|
break;
|
||||||
|
// case'onvif_end':
|
||||||
|
// if(Object.keys($.oB.foundMonitorsCount).length===0){
|
||||||
|
// $.oB.e.find('._loading').hide()
|
||||||
|
// $.oB.e.find('[type="submit"]').prop('disabled',false)
|
||||||
|
// $.oB.o.append('<td class="text-center _notfound">Sorry, nothing was found.</td>')
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
case'onvif':
|
||||||
|
var tempID = $.ccio.gid();
|
||||||
|
$.oB.foundMonitors[tempID] = Object.assign({},d);
|
||||||
|
$.oB.e.find('._loading').hide()
|
||||||
|
$.oB.e.find('._notfound').remove()
|
||||||
|
$.oB.e.find('[type="submit"]').prop('disabled',false)
|
||||||
|
d.info=$.ccio.init('jsontoblock',d.info)
|
||||||
|
if(d.uri){
|
||||||
|
d.stream=d.uri
|
||||||
|
}else{
|
||||||
|
d.stream='URL not Found'
|
||||||
|
}
|
||||||
|
$('#onvif_probe .output_data').append('<tr onvif_row="'+tempID+'"><td><a class="btn btn-sm btn-primary copy"> <i class="fa fa-copy"></i> </a></td><td class="ip">'+d.ip+'</td><td class="port">'+d.port+'</td><td>'+$.ccio.init('jsontoblock',d.info)+'</td><td class="url">'+d.stream+'</td></tr>')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delete(d);
|
||||||
|
});
|
||||||
|
})
|
|
@ -0,0 +1,334 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//Timelapse Window
|
||||||
|
$.timelapse={e:$('#timelapse')}
|
||||||
|
$.timelapse.f=$.timelapse.e.find('form'),
|
||||||
|
$.timelapse.meter=$.timelapse.e.find('.motion-meter'),
|
||||||
|
$.timelapse.line=$('#timelapse_video_line'),
|
||||||
|
$.timelapse.display=$('#timelapse_video_display'),
|
||||||
|
$.timelapse.seekBar=$('#timelapse_seekBar'),
|
||||||
|
$.timelapse.seekBarProgress=$.timelapse.seekBar.find('.progress-bar'),
|
||||||
|
$.timelapse.dr=$('#timelapse_daterange'),
|
||||||
|
$.timelapse.mL=$.timelapse.e.find('.motion_list'),
|
||||||
|
$.timelapse.monitors=$.timelapse.e.find('.monitors_list');
|
||||||
|
$.timelapse.playDirection='videoAfter'
|
||||||
|
$.timelapse.playRate=15
|
||||||
|
$.timelapse.placeholder=placeholder.getData(placeholder.plcimg({bgcolor:'#b57d00',text:'...'}))
|
||||||
|
$.timelapse.dr.daterangepicker({
|
||||||
|
startDate:$.ccio.timeObject().subtract(moment.duration("24:00:00")),
|
||||||
|
endDate:$.ccio.timeObject().add(moment.duration("24:00:00")),
|
||||||
|
timePicker: true,
|
||||||
|
timePicker24Hour: true,
|
||||||
|
timePickerSeconds: true,
|
||||||
|
timePickerIncrement: 30,
|
||||||
|
locale: {
|
||||||
|
format: 'MM/DD/YYYY h:mm A'
|
||||||
|
}
|
||||||
|
},function(start, end, label){
|
||||||
|
$.timelapse.drawTimeline()
|
||||||
|
$.timelapse.dr.focus()
|
||||||
|
});
|
||||||
|
$.timelapse.f.find('input,select').change(function(){
|
||||||
|
$.timelapse.f.submit()
|
||||||
|
})
|
||||||
|
$.timelapse.f.submit(function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
$.timelapse.drawTimeline()
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
$.timelapse.drawTimeline=function(getData){
|
||||||
|
var e={};
|
||||||
|
if(getData===undefined){getData=true}
|
||||||
|
var mid = $.timelapse.monitors.val()
|
||||||
|
e.dateRange=$.timelapse.dr.data('daterangepicker');
|
||||||
|
e.dateRange={startDate:e.dateRange.startDate,endDate:e.dateRange.endDate}
|
||||||
|
e.videoURL=$.ccio.init('location',$user)+$user.auth_token+'/videos/'+$user.ke+'/'+mid;
|
||||||
|
e.videoURL+='?limit=100&start='+$.ccio.init('th',e.dateRange.startDate)+'&end='+$.ccio.init('th',e.dateRange.endDate);
|
||||||
|
e.next=function(videos){
|
||||||
|
$.timelapse.currentVideos={}
|
||||||
|
e.tmp=''
|
||||||
|
$.each(videos.videos,function(n,v){
|
||||||
|
if(!v||!v.time){return}
|
||||||
|
// v.filename=$.ccio.init('tf',v.time)+'.'+v.ext;
|
||||||
|
v.videoBefore=videos.videos[n-1];
|
||||||
|
v.videoAfter=videos.videos[n+1];
|
||||||
|
// if(v.href.charAt(0)==='/'){
|
||||||
|
// v.href=$.ccio.init('location',user)+(v.href.substring(1))
|
||||||
|
// v.videoURL=$.ccio.init('location',user)+(v.videoURL.substring(1))
|
||||||
|
// }
|
||||||
|
v.position=n;
|
||||||
|
$.timelapse.currentVideos[v.filename]=v;
|
||||||
|
e.tmp+='<li class="glM'+v.mid+$user.auth_token+' list-group-item timelapse_video flex-block" timelapse="video" file="'+v.filename+'" href="'+v.href+'" mid="'+v.mid+'" ke="'+v.ke+'" auth="'+$user.auth_token+'">'
|
||||||
|
e.tmp+='<div class="flex-block">'
|
||||||
|
e.tmp+='<div class="flex-unit-3"><div class="frame" style="background-image:url('+$.timelapse.placeholder+')"></div></div>'
|
||||||
|
e.tmp+='<div class="flex-unit-3"><div><span title="'+v.time+'" class="livestamp"></span></div><div>'+v.filename+'</div></div>'
|
||||||
|
e.tmp+='<div class="flex-unit-3 text-right"><a class="btn btn-default" download="'+v.mid+'-'+v.filename+'" href="'+v.href+'"> <i class="fa fa-download"></i> </a> <a class="btn btn-danger" video="delete" href="'+$.ccio.init('videoHrefToDelete',v.href)+'"> <i class="fa fa-trash-o"></i> </a></div>'
|
||||||
|
e.tmp+='</div>'
|
||||||
|
e.tmp+='<div class="flex-block">'
|
||||||
|
e.tmp+='<div class="flex-unit-3"><div class="progress"><div class="progress-bar progress-bar-primary" role="progressbar" style="width:0%"></div></div></div>'
|
||||||
|
e.tmp+='</div>'
|
||||||
|
e.tmp+='</li>'
|
||||||
|
})
|
||||||
|
$.timelapse.line.html(e.tmp)
|
||||||
|
$.ccio.init('ls')
|
||||||
|
if(getData===true){
|
||||||
|
e.timeout=50
|
||||||
|
}else{
|
||||||
|
e.timeout=2000
|
||||||
|
}
|
||||||
|
setTimeout(function(){
|
||||||
|
if($.timelapse.e.find('.timelapse_video.active').length===0){
|
||||||
|
$.timelapse.e.find('[timelapse="video"]').first().click()
|
||||||
|
}
|
||||||
|
},e.timeout)
|
||||||
|
}
|
||||||
|
if(getData===true){
|
||||||
|
$.getJSON(e.videoURL,function(videos){
|
||||||
|
videos.videos=videos.videos.reverse()
|
||||||
|
$.timelapse.currentVideosArray=videos
|
||||||
|
e.next(videos)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
e.next($.timelapse.currentVideosArray)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.timelapse.playButtonIcon = $.timelapse.e.find('[timelapse="play"]').find('i')
|
||||||
|
$.timelapse.timelapseSpeedUseBasicSwitch = $('#timelapseSpeedUseBasic')
|
||||||
|
$.timelapse.timelapseSpeedUseBasicSwitch.on('change',function(){
|
||||||
|
var el = $.timelapse.e.find('.timelapseSpeedUseBasicSwitch')
|
||||||
|
if($(this).is(':checked')){
|
||||||
|
el.hide()
|
||||||
|
}else{
|
||||||
|
el.show()
|
||||||
|
}
|
||||||
|
$.timelapse.play()
|
||||||
|
})
|
||||||
|
$.timelapse.getUseBasicStatus = function(){return $.timelapse.timelapseSpeedUseBasicSwitch.prop('checked')}
|
||||||
|
$.timelapse.onPlayPause = function(toggleGui,secondWind){
|
||||||
|
if($.timelapse.paused === true){
|
||||||
|
$.timelapse.paused = false
|
||||||
|
if(toggleGui === true)$.timelapse.play();
|
||||||
|
}else{
|
||||||
|
$.timelapse.paused = true
|
||||||
|
if(toggleGui === true)$.timelapse.pause(secondWind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.timelapse.pause = function(secondWind){
|
||||||
|
//secondWind is used because sometimes pause can be pressed just as a video ends and the pause command does not register on the next video.
|
||||||
|
var videoNow = $.timelapse.display.find('video.videoNow')[0]
|
||||||
|
var pause = function(){
|
||||||
|
if(videoNow.paused == false)videoNow.pause()
|
||||||
|
clearInterval($.timelapse.interval)
|
||||||
|
$.timelapse.playButtonIcon.removeClass('fa-pause').addClass('fa-play')
|
||||||
|
}
|
||||||
|
pause()
|
||||||
|
if(secondWind === true)setTimeout(pause,250);
|
||||||
|
}
|
||||||
|
$.timelapse.play = function(x){
|
||||||
|
var videoNow = $.timelapse.display.find('video.videoNow')[0]
|
||||||
|
$.timelapse.pause()
|
||||||
|
clearInterval($.timelapse.interval)
|
||||||
|
if($.timelapse.getUseBasicStatus()){
|
||||||
|
videoNow.playbackRate = $.timelapse.playRate
|
||||||
|
if(videoNow.paused)videoNow.play()
|
||||||
|
}else{
|
||||||
|
videoNow.playbackRate = 1.0
|
||||||
|
$.timelapse.interval = setInterval(function(){
|
||||||
|
if(videoNow.currentTime >= videoNow.duration - .2){
|
||||||
|
clearInterval($.timelapse.interval)
|
||||||
|
videoNow.currentTime = videoNow.duration
|
||||||
|
}else{
|
||||||
|
videoNow.currentTime += .5
|
||||||
|
}
|
||||||
|
},500 / $.timelapse.playRate)
|
||||||
|
}
|
||||||
|
$.timelapse.playButtonIcon.removeClass('fa-play').addClass('fa-pause')
|
||||||
|
}
|
||||||
|
$.timelapse.rewind = function(e){
|
||||||
|
var videoNow = $.timelapse.display.find('video.videoNow')[0]
|
||||||
|
$.timelapse.pause()
|
||||||
|
videoNow.playbackRate = 1.0
|
||||||
|
clearInterval($.timelapse.interval)
|
||||||
|
$.timelapse.interval = setInterval(function(){
|
||||||
|
if(videoNow.currentTime <= 0.2){
|
||||||
|
clearInterval($.timelapse.interval)
|
||||||
|
videoNow.currentTime = 0
|
||||||
|
$('[timelapse][href="'+e.videoCurrentBefore.attr('video')+'"]').click()
|
||||||
|
var videoNowNew = $.timelapse.display.find('video.videoNow')[0]
|
||||||
|
videoNowNew.pause()
|
||||||
|
videoNowNew.currentTime = videoNowNew.duration - 0.1
|
||||||
|
$.timelapse.e.find('[timelapse="stepBackBack"]').click()
|
||||||
|
}else{
|
||||||
|
videoNow.currentTime += -.5
|
||||||
|
}
|
||||||
|
},500 / $.timelapse.playRate)
|
||||||
|
$.timelapse.playButtonIcon.removeClass('fa-play').addClass('fa-pause')
|
||||||
|
}
|
||||||
|
$.timelapse.e.on('click','[timelapse]',function(){
|
||||||
|
var e={}
|
||||||
|
e.e=$(this)
|
||||||
|
e.videoCurrentNow=$.timelapse.display.find('.videoNow')
|
||||||
|
e.videoCurrentAfter=$.timelapse.display.find('.videoAfter')
|
||||||
|
e.videoCurrentBefore=$.timelapse.display.find('.videoBefore')
|
||||||
|
if($.timelapse.videoInterval){
|
||||||
|
clearInterval($.timelapse.videoInterval);
|
||||||
|
}
|
||||||
|
switch(e.e.attr('timelapse')){
|
||||||
|
case'download':
|
||||||
|
$.timelapse.line.find('.active [download]').click()
|
||||||
|
break;
|
||||||
|
case'mute':
|
||||||
|
e.videoCurrentNow[0].muted = !e.videoCurrentNow[0].muted
|
||||||
|
$.timelapse.videoNowIsMuted = e.videoCurrentNow[0].muted
|
||||||
|
e.e.find('i').toggleClass('fa-volume-off fa-volume-up')
|
||||||
|
e.e.toggleClass('btn-danger')
|
||||||
|
break;
|
||||||
|
case'play':
|
||||||
|
e.videoCurrentNow[0].playbackRate = $.timelapse.playRate;
|
||||||
|
$.timelapse.onPlayPause(true,true)
|
||||||
|
break;
|
||||||
|
case'setPlayBackRate':
|
||||||
|
$.timelapse.pause()
|
||||||
|
$.timelapse.playRate = parseFloat(e.e.attr('playRate'))
|
||||||
|
$.timelapse.play()
|
||||||
|
break;
|
||||||
|
case'stepFrontFront':
|
||||||
|
e.add=e.e.attr('add')
|
||||||
|
e.stepFrontFront=parseInt(e.e.attr('stepFrontFront'))
|
||||||
|
if(!e.stepFrontFront||isNaN(e.stepFrontFront)){e.stepFrontFront = 5}
|
||||||
|
if(e.add==="0"){
|
||||||
|
$.timelapse.playRate = e.stepFrontFront
|
||||||
|
}else{
|
||||||
|
$.timelapse.playRate += e.stepFrontFront
|
||||||
|
}
|
||||||
|
e.videoCurrentNow[0].playbackRate = $.timelapse.playRate;
|
||||||
|
e.videoCurrentNow[0].play()
|
||||||
|
break;
|
||||||
|
case'stepFront':
|
||||||
|
e.videoCurrentNow[0].currentTime += 5;
|
||||||
|
e.videoCurrentNow[0].pause()
|
||||||
|
break;
|
||||||
|
case'stepBackBack':
|
||||||
|
// e.videoCurrentNow=$.timelapse.display.find('.videoNow')
|
||||||
|
// e.videoCurrentAfter=$.timelapse.display.find('.videoAfter')
|
||||||
|
// e.videoCurrentBefore=$.timelapse.display.find('.videoBefore')
|
||||||
|
$.timelapse.rewind(e)
|
||||||
|
break;
|
||||||
|
case'stepBack':
|
||||||
|
e.videoCurrentNow[0].currentTime += -5;
|
||||||
|
e.videoCurrentNow[0].pause()
|
||||||
|
break;
|
||||||
|
case'video':
|
||||||
|
$.timelapse.e.find('video').each(function(n,v){
|
||||||
|
v.pause()
|
||||||
|
})
|
||||||
|
e.drawVideoHTML=function(position){
|
||||||
|
var video
|
||||||
|
var exisitingElement=$.timelapse.display.find('.'+position)
|
||||||
|
if(position){
|
||||||
|
video=e.video[position]
|
||||||
|
}else{
|
||||||
|
position='videoNow'
|
||||||
|
video=e.video
|
||||||
|
}
|
||||||
|
if(video){
|
||||||
|
$.timelapse.display.append('<video class="video_video '+position+'" video="'+video.href+'" preload><source src="'+video.href+'" type="video/'+video.ext+'"></video>')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.filename=e.e.attr('file')
|
||||||
|
e.video=$.timelapse.currentVideos[e.filename]
|
||||||
|
e.videoIsSame=(e.video.href==e.videoCurrentNow.attr('video'))
|
||||||
|
e.videoIsAfter=(e.video.href==e.videoCurrentAfter.attr('video'))
|
||||||
|
e.videoIsBefore=(e.video.href==e.videoCurrentBefore.attr('video'))
|
||||||
|
if(e.videoIsSame||e.videoIsAfter||e.videoIsBefore){
|
||||||
|
switch(true){
|
||||||
|
case e.videoIsSame:
|
||||||
|
$.ccio.log('$.timelapse','videoIsSame')
|
||||||
|
e.videoNow=$.timelapse.display.find('video.videoNow')
|
||||||
|
if(e.videoNow[0].paused===true){
|
||||||
|
e.videoNow[0].play()
|
||||||
|
}else{
|
||||||
|
e.videoNow[0].pause()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
break;
|
||||||
|
case e.videoIsAfter:
|
||||||
|
$.ccio.log('$.timelapse','videoIsAfter')
|
||||||
|
e.videoCurrentBefore.remove()
|
||||||
|
e.videoCurrentAfter.removeClass('videoAfter').addClass('videoNow')
|
||||||
|
e.videoCurrentNow.removeClass('videoNow').addClass('videoBefore')
|
||||||
|
e.drawVideoHTML('videoAfter')
|
||||||
|
break;
|
||||||
|
case e.videoIsBefore:
|
||||||
|
$.ccio.log('$.timelapse','videoIsBefore')
|
||||||
|
e.videoCurrentAfter.remove()
|
||||||
|
e.videoCurrentBefore.removeClass('videoBefore').addClass('videoNow')
|
||||||
|
e.videoCurrentNow.removeClass('videoNow').addClass('videoAfter')
|
||||||
|
e.drawVideoHTML('videoBefore')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$.ccio.log('$.timelapse','newSetOf3')
|
||||||
|
$.timelapse.display.empty()
|
||||||
|
e.drawVideoHTML()//videoNow
|
||||||
|
e.drawVideoHTML('videoBefore')
|
||||||
|
e.drawVideoHTML('videoAfter')
|
||||||
|
}
|
||||||
|
$.timelapse.display.find('video').each(function(n,v){
|
||||||
|
v.addEventListener('loadeddata', function() {
|
||||||
|
e.videoCurrentAfterPreview=$('.timelapse_video[href="'+$(v).attr('video')+'"] .frame')
|
||||||
|
if(e.videoCurrentAfterPreview.attr('set')!=='1'){
|
||||||
|
$.ccio.snapshotVideo(v,function(url,buffer){
|
||||||
|
e.videoCurrentAfterPreview.attr('set','1').css('background-image','url('+url+')')
|
||||||
|
if($(v).hasClass('videoAfter')){
|
||||||
|
v.currentTime=0
|
||||||
|
v.pause()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
})
|
||||||
|
e.videoNow=$.timelapse.display.find('video.videoNow')[0]
|
||||||
|
if($.timelapse.videoNowIsMuted){
|
||||||
|
e.videoNow.muted=true
|
||||||
|
}
|
||||||
|
$.timelapse.playButtonIcon.removeClass('fa-pause').addClass('fa-play')
|
||||||
|
$.timelapse.onended = function() {
|
||||||
|
$.timelapse.line.find('[file="'+e.video[$.timelapse.playDirection].filename+'"]').click()
|
||||||
|
};
|
||||||
|
e.videoNow.onended = $.timelapse.onended
|
||||||
|
e.videoNow.onerror = $.timelapse.onended
|
||||||
|
//
|
||||||
|
$(e.videoNow)
|
||||||
|
.off('play').on('play',$.timelapse.play)
|
||||||
|
.off('pause').on('pause',$.timelapse.onPlayPause)
|
||||||
|
.off('timeupdate').on('timeupdate',function(){
|
||||||
|
var value= (( e.videoNow.currentTime / e.videoNow.duration ) * 100)+"%"
|
||||||
|
$.timelapse.seekBarProgress.css("width",value);
|
||||||
|
$.timelapse.e.find('.timelapse_video[file="'+e.filename+'"] .progress-bar').css("width",value);
|
||||||
|
})
|
||||||
|
$.timelapse.play()
|
||||||
|
$.timelapse.seekBar.off("click").on("click", function(seek){
|
||||||
|
var offset = $(this).offset();
|
||||||
|
var left = (seek.pageX - offset.left);
|
||||||
|
var totalWidth = $.timelapse.seekBar.width();
|
||||||
|
var percentage = ( left / totalWidth );
|
||||||
|
var vidTime = e.videoNow.duration * percentage;
|
||||||
|
e.videoNow.currentTime = vidTime;
|
||||||
|
});
|
||||||
|
|
||||||
|
$.ccio.log('$.timelapse',e.video)
|
||||||
|
$.timelapse.line.find('.timelapse_video').removeClass('active')
|
||||||
|
e.videoCurrentNow=$.timelapse.display.find('.videoNow')
|
||||||
|
e.e.addClass('active')
|
||||||
|
if ($('#timelapse_video_line:hover').length === 0) {
|
||||||
|
$.timelapse.line.animate({scrollTop:$.timelapse.line.scrollTop() + e.e.position().top - $.timelapse.line.height()/2 + e.e.height()/2 - 40});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$.timelapse.e.find('.timelapse_playRate').text('x'+$.timelapse.playRate)
|
||||||
|
})
|
||||||
|
$.timelapse.e.on('hidden.bs.modal',function(e){
|
||||||
|
delete($.timelapse.currentVideos)
|
||||||
|
delete($.timelapse.currentVideosArray)
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,101 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//settings window
|
||||||
|
$.sM={e:$('#settings')};
|
||||||
|
$.sM.f=$.sM.e.find('form');
|
||||||
|
$.sM.links=$('#linkShinobi');
|
||||||
|
$.sM.g=$('#settings_mon_groups');
|
||||||
|
$.sM.md=$.sM.f.find('[detail]');
|
||||||
|
$.sM.md.change($.ccio.form.details);
|
||||||
|
$.sM.f.find('[selector]').change(function(e){
|
||||||
|
e.v=$(this).val();e.a=$(this).attr('selector')
|
||||||
|
$.sM.f.find('.'+e.a+'_input').hide()
|
||||||
|
$.sM.f.find('.'+e.a+'_'+e.v).show();
|
||||||
|
$.sM.f.find('.'+e.a+'_text').text($(this).find('option:selected').text())
|
||||||
|
});
|
||||||
|
$.sM.writewMonGroups=function(){
|
||||||
|
$.sM.f.find('[detail="mon_groups"]').val(JSON.stringify($user.mon_groups)).change()
|
||||||
|
}
|
||||||
|
$.sM.reDrawMonGroups=function(){
|
||||||
|
$.sM.g.empty();
|
||||||
|
$.ccio.pm('option',$user.mon_groups,'#settings_mon_groups')
|
||||||
|
$.sM.g.change();
|
||||||
|
};
|
||||||
|
$.sM.f.submit(function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
$.sM.writewMonGroups()
|
||||||
|
$.sM.linkChange()
|
||||||
|
e.e=$(this),e.s=e.e.serializeObject();
|
||||||
|
e.er=[];
|
||||||
|
if(e.s.pass!==''&&e.password_again===e.s.pass){e.er.push(lang['Passwords don\'t match'])};
|
||||||
|
if(e.er.length>0){$.sM.e.find('.msg').html(e.er.join('<br>'));return;}
|
||||||
|
$.each(e.s,function(n,v){e.s[n]=v.trim()})
|
||||||
|
$.ccio.cx({f:'settings',ff:'edit',form:e.s})
|
||||||
|
$.sM.e.modal('hide')
|
||||||
|
});
|
||||||
|
$.sM.e.on('shown.bs.modal',function(){
|
||||||
|
$.sM.reDrawMonGroups()
|
||||||
|
})
|
||||||
|
$.sM.g.change(function(e){
|
||||||
|
e.v=$(this).val();
|
||||||
|
e.group=$user.mon_groups[e.v];
|
||||||
|
if(!e.group){return}
|
||||||
|
$.sM.selectedMonGroup=e.group;
|
||||||
|
$.each(e.group,function(n,v){
|
||||||
|
$.sM.f.find('[group="'+n+'"]').val(v)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
$.sM.f.find('[group]').change(function(){
|
||||||
|
e = {}
|
||||||
|
e.v = $.sM.g.val()
|
||||||
|
if(!e.v||e.v==''){
|
||||||
|
e.e = $.sM.f.find('[group="name"]')
|
||||||
|
e.name = e.e.val()
|
||||||
|
$('.mon_groups .add').click();
|
||||||
|
e.v = $.sM.g.val()
|
||||||
|
e.e.val(e.name)
|
||||||
|
}
|
||||||
|
e.group=$user.mon_groups[e.v];
|
||||||
|
$.sM.f.find('[group]').each(function(n,v){
|
||||||
|
v=$(v)
|
||||||
|
e.group[v.attr('group')]=v.val()
|
||||||
|
});
|
||||||
|
$user.mon_groups[e.v]=e.group;
|
||||||
|
$.sM.g.find('option[value="'+$.sM.g.val()+'"]').text(e.group.name)
|
||||||
|
$.sM.writewMonGroups()
|
||||||
|
})
|
||||||
|
$.sM.f.on('click','.mon_groups .delete',function(e){
|
||||||
|
e.v=$.sM.g.val();
|
||||||
|
delete($user.mon_groups[e.v]);
|
||||||
|
$.sM.reDrawMonGroups()
|
||||||
|
})
|
||||||
|
$.sM.f.on('click','.mon_groups .add',function(e){
|
||||||
|
e.gid=$.ccio.gid(5);
|
||||||
|
$user.mon_groups[e.gid]={id:e.gid,name:e.gid};
|
||||||
|
$.sM.g.append($.ccio.tm('option',$user.mon_groups[e.gid]));
|
||||||
|
$.sM.g.val(e.gid)
|
||||||
|
$.sM.g.change();
|
||||||
|
});
|
||||||
|
$.sM.linkChange=function(){
|
||||||
|
var e={};
|
||||||
|
e.e=$.sM.e.find('[name="details"]')
|
||||||
|
e.details=JSON.parse(e.e.val())
|
||||||
|
e.details.links=[]
|
||||||
|
$.sM.links.find('.linksGroup').each(function(n,v){
|
||||||
|
var arr={}
|
||||||
|
$(v).find('[link]').each(function(m,b){
|
||||||
|
arr[$(b).attr('link')]=$(b).val()
|
||||||
|
})
|
||||||
|
e.details.links.push(arr)
|
||||||
|
})
|
||||||
|
e.e.val(JSON.stringify(e.details))
|
||||||
|
}
|
||||||
|
$.sM.f.on('change','[link]',$.sM.linkChange)
|
||||||
|
$.sM.e.on('click','.linkShinobi .delete',function(){
|
||||||
|
$(this).parents('.linksGroup').remove()
|
||||||
|
$.sM.linkChange()
|
||||||
|
})
|
||||||
|
$.sM.e.find('.linkShinobi .add').click(function(){
|
||||||
|
$.ccio.tm('link-set',{},'#linkShinobi')
|
||||||
|
$.sM.linkChange()
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,147 @@
|
||||||
|
$(document).ready(function(e){
|
||||||
|
//videos window
|
||||||
|
$.vidview={
|
||||||
|
e:$('#videos_viewer'),
|
||||||
|
pages:$('#videos_viewer_pages'),
|
||||||
|
limit:$('#videos_viewer_limit'),
|
||||||
|
dr:$('#videos_viewer_daterange'),
|
||||||
|
preview:$('#videos_viewer_preview'),
|
||||||
|
set:$('#videos_viewer_set')
|
||||||
|
}
|
||||||
|
$.vidview.set.change(function(){
|
||||||
|
var el = $(this)
|
||||||
|
var isCloud = (el.val() === 'cloud')
|
||||||
|
var zipDlButton = $.vidview.e.find('.export_selected')
|
||||||
|
if(isCloud){
|
||||||
|
zipDlButton.hide()
|
||||||
|
}else{
|
||||||
|
zipDlButton.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
$.vidview.f=$.vidview.e.find('form')
|
||||||
|
$.vidview.dr.daterangepicker({
|
||||||
|
startDate:$.ccio.timeObject().subtract(moment.duration("24:00:00")),
|
||||||
|
endDate:$.ccio.timeObject().add(moment.duration("24:00:00")),
|
||||||
|
timePicker: true,
|
||||||
|
timePicker24Hour: true,
|
||||||
|
timePickerSeconds: true,
|
||||||
|
timePickerIncrement: 30,
|
||||||
|
locale: {
|
||||||
|
format: 'MM/DD/YYYY h:mm A'
|
||||||
|
}
|
||||||
|
},function(start, end, label){
|
||||||
|
$.vidview.launcher.click()
|
||||||
|
$.vidview.dr.focus()
|
||||||
|
});
|
||||||
|
$.vidview.e.on('change','#videos_select_all',function(e){
|
||||||
|
e.e=$(this);
|
||||||
|
e.p=e.e.prop('checked')
|
||||||
|
e.a=$.vidview.e.find('input[type=checkbox][name]')
|
||||||
|
if(e.p===true){
|
||||||
|
e.a.prop('checked',true)
|
||||||
|
}else{
|
||||||
|
e.a.prop('checked',false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.vidview.f.submit(function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
$.vidview.launcher.click()
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
$('#videos_viewer_limit,#videos_viewer_daterange,#videos_viewer_set').change(function(){
|
||||||
|
$.vidview.f.submit()
|
||||||
|
})
|
||||||
|
$.vidview.getSelected = function(getArray){
|
||||||
|
var arr = {}
|
||||||
|
if(getArray){
|
||||||
|
arr = []
|
||||||
|
}
|
||||||
|
$.vidview.f.find('[data-ke] input:checked').each(function(n,v){
|
||||||
|
v=$(v).parents('tr')
|
||||||
|
if(getArray){
|
||||||
|
arr.push({filename:v.attr('data-file'),mid:v.attr('data-mid'),auth:v.attr('data-auth')})
|
||||||
|
}else{
|
||||||
|
arr[v.attr('data-file')]={mid:v.attr('data-mid'),auth:v.attr('data-auth')}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
$.vidview.e.find('.delete_selected').click(function(){
|
||||||
|
e = {}
|
||||||
|
e.s = $.vidview.getSelected()
|
||||||
|
if(Object.keys(e.s).length === 0){
|
||||||
|
$.ccio.init('note',{
|
||||||
|
title:'No Videos Selected',
|
||||||
|
text:'You must choose at least one video.',
|
||||||
|
type:'error'
|
||||||
|
},$user);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text(lang['Delete Selected Videos'])
|
||||||
|
e.html=lang.DeleteSelectedVideosMsg+'<div style="margin-bottom:15px"></div>'
|
||||||
|
var deleteLinks = []
|
||||||
|
$.each(e.s,function(n,v){
|
||||||
|
e.html+=n+'<br>';
|
||||||
|
if($.vidview.loadedVideos[n])deleteLinks.push($.vidview.loadedVideos[n].links.deleteVideo)
|
||||||
|
})
|
||||||
|
$.confirm.body.html(e.html)
|
||||||
|
$.confirm.click({title:'Delete Video',class:'btn-danger'},function(){
|
||||||
|
$.each(deleteLinks,function(n,link){
|
||||||
|
$.getJSON(link,function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
})
|
||||||
|
$.vidview.e.find('.export_selected').click(function(){
|
||||||
|
e = {}
|
||||||
|
var videos = $.vidview.getSelected(true)
|
||||||
|
if(videos.length === 0){
|
||||||
|
$.ccio.init('note',{
|
||||||
|
title:'No Videos Selected',
|
||||||
|
text:'You must choose at least one video.',
|
||||||
|
type:'error'
|
||||||
|
},$user);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text(lang['Export Selected Videos'])
|
||||||
|
var html = lang.ExportSelectedVideosMsg+'<div style="margin-bottom:15px"></div>'
|
||||||
|
$.each(videos,function(n,v){
|
||||||
|
html+=v.filename+'<br>';
|
||||||
|
})
|
||||||
|
$.confirm.body.html(html)
|
||||||
|
$.confirm.click({title:'Export Video',class:'btn-danger'},function(){
|
||||||
|
var queryVariables = []
|
||||||
|
queryVariables.push('videos='+JSON.stringify(videos))
|
||||||
|
if($.ccio.useUTC === true){
|
||||||
|
queryVariables.push('isUTC=true')
|
||||||
|
}
|
||||||
|
console.log(queryVariables)
|
||||||
|
var downloadZip = $.ccio.init('location',$user)+$user.auth_token+'/zipVideos/'+$user.ke+'?'+queryVariables.join('&')
|
||||||
|
$('#temp').html('<iframe>a</iframe>').find('iframe').attr('src',downloadZip);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
$.vidview.pages.on('click','[page]',function(e){
|
||||||
|
e.limit=$.vidview.limit.val();
|
||||||
|
e.page=$(this).attr('page');
|
||||||
|
$.vidview.current_page=e.page;
|
||||||
|
if(e.limit.replace(/ /g,'')===''){
|
||||||
|
e.limit='100';
|
||||||
|
}
|
||||||
|
if(e.limit.indexOf(',')>-1){
|
||||||
|
e.limit=parseInt(e.limit.split(',')[1])
|
||||||
|
}else{
|
||||||
|
e.limit=parseInt(e.limit)
|
||||||
|
}
|
||||||
|
$.vidview.limit.val((parseInt(e.page)-1)+'00,'+e.limit)
|
||||||
|
$.vidview.launcher.click()
|
||||||
|
})
|
||||||
|
$.vidview.e.on('click','.preview',function(e){
|
||||||
|
e.preventDefault()
|
||||||
|
e=$(this)
|
||||||
|
$.vidview.preview.html('<video class="video_video" video="'+e.attr('href')+'" preload controls autoplay><source src="'+e.attr('href')+'" type="video/mp4"></video>')
|
||||||
|
})
|
||||||
|
})
|
|
@ -1156,7 +1156,9 @@ switch($user.details.lang){
|
||||||
tmp+='</li>';
|
tmp+='</li>';
|
||||||
break;
|
break;
|
||||||
case'option':
|
case'option':
|
||||||
tmp+='<option auth="'+user.auth_token+'" value="'+d.id+'">'+d.name+'</option>'
|
var selected = ''
|
||||||
|
if(d.selected === true){selected = ' selected'}
|
||||||
|
tmp+='<option auth="'+user.auth_token+'"'+selected+' value="'+d.id+'">'+d.name+'</option>'
|
||||||
break;
|
break;
|
||||||
case'stream-element':
|
case'stream-element':
|
||||||
try{k.d=JSON.parse(d.details);}catch(er){k.d=d.details}
|
try{k.d=JSON.parse(d.details);}catch(er){k.d=d.details}
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/fullcalendar.min.css">
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/fullcalendar.min.css">
|
||||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/bootstrap-table.min.css">
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/bootstrap-table.min.css">
|
||||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.css">
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.css">
|
||||||
|
<% customAutoLoad.adminLibsCss.forEach(function(lib){ %>
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/<%-lib%>">
|
||||||
|
<% }) %>
|
||||||
<body class="shinobi-bg">
|
<body class="shinobi-bg">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@ -80,8 +83,14 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script>
|
||||||
|
var adminApiPrefix = "<%=originalURL%><%=config.webPaths.adminApiPrefix%>"
|
||||||
|
</script>
|
||||||
<% include blocks/confirm.ejs %>
|
<% include blocks/confirm.ejs %>
|
||||||
<% include blocks/subpermissions.ejs %>
|
<% include blocks/subpermissions.ejs %>
|
||||||
|
<% customAutoLoad.adminPageBlocks.forEach(function(block){ %>
|
||||||
|
<%- include(block) %>
|
||||||
|
<% }) %>
|
||||||
</body>
|
</body>
|
||||||
<script><% include ../libs/js/basic.js %></script>
|
<script><% include ../libs/js/basic.js %></script>
|
||||||
<script><% include ../libs/js/socket.io.js %></script>
|
<script><% include ../libs/js/socket.io.js %></script>
|
||||||
|
@ -275,3 +284,6 @@ $('body')
|
||||||
localStorage.removeItem('ShinobiLogin_'+location.host);location.href=location.href;
|
localStorage.removeItem('ShinobiLogin_'+location.host);location.href=location.href;
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
<% customAutoLoad.adminLibsJs.forEach(function(lib){ %>
|
||||||
|
<script src="<%-window.libURL%>libs/js/<%-lib%>"></script>
|
||||||
|
<% }) %>
|
||||||
|
|
|
@ -93,3 +93,4 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.apiwindow.js"></script>
|
||||||
|
|
|
@ -259,3 +259,4 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.detectorfilter.js"></script>
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
<div class="form-group-group blue where">
|
<div class="form-group-group blue where">
|
||||||
<h4><%- lang['Find Where'] %>
|
<h4><%- lang['Find Where'] %>
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<a class="btn btn-default btn-xs add"> <i class="fa fa-plus"></i> </a>
|
<a class="btn btn-default btn-xs add"> <i class="fa fa-plus"></i> </a>
|
||||||
<a class="btn btn-danger btn-xs remove"> <i class="fa fa-minus"></i> </a>
|
<a class="btn btn-danger btn-xs remove"> <i class="fa fa-minus"></i> </a>
|
||||||
</div>
|
</div>
|
||||||
</h4>
|
</h4>
|
||||||
<div id="filters_where">
|
<div id="filters_where">
|
||||||
|
@ -39,20 +39,20 @@
|
||||||
<div class="form-group col-md-4">
|
<div class="form-group col-md-4">
|
||||||
<label>
|
<label>
|
||||||
<div><select class="form-control" name="sort_by">
|
<div><select class="form-control" name="sort_by">
|
||||||
<option value="time" selected><%- lang['Start Time'] %></option>
|
<option value="time" selected><%- lang['Start Time'] %></option>
|
||||||
<option value="end"><%- lang['End Time'] %></option>
|
<option value="end"><%- lang['End Time'] %></option>
|
||||||
<option value="mid"><%- lang['Monitor ID'] %></option>
|
<option value="mid"><%- lang['Monitor ID'] %></option>
|
||||||
<option value="ext"><%- lang['File Type'] %></option>
|
<option value="ext"><%- lang['File Type'] %></option>
|
||||||
<option value="size"><%- lang['Filesize'] %></option>
|
<option value="size"><%- lang['Filesize'] %></option>
|
||||||
<option value="status"><%- lang['Video Status'] %></option>
|
<option value="status"><%- lang['Video Status'] %></option>
|
||||||
</select></div>
|
</select></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-4">
|
<div class="form-group col-md-4">
|
||||||
<label>
|
<label>
|
||||||
<div><select class="form-control" name="sort_by_direction">
|
<div><select class="form-control" name="sort_by_direction">
|
||||||
<option value="ASC" selected><%- lang['ASC'] %></option>
|
<option value="ASC" selected><%- lang['ASC'] %></option>
|
||||||
<option value="DESC"><%- lang['DESC'] %></option>
|
<option value="DESC"><%- lang['DESC'] %></option>
|
||||||
</select></div>
|
</select></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -68,8 +68,8 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><div><span><%- lang['Enabled'] %></span></div>
|
<label><div><span><%- lang['Enabled'] %></span></div>
|
||||||
<div><select class="form-control" name="enabled">
|
<div><select class="form-control" name="enabled">
|
||||||
<option value="0" selected><%- lang['No'] %></option>
|
<option value="0" selected><%- lang['No'] %></option>
|
||||||
<option value="1"><%- lang['Yes'] %></option>
|
<option value="1"><%- lang['Yes'] %></option>
|
||||||
</select></div>
|
</select></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -77,24 +77,24 @@
|
||||||
<div class="form-group col-md-12 hidden">
|
<div class="form-group col-md-12 hidden">
|
||||||
<label><div><span><%- lang['Archive'] %></span></div>
|
<label><div><span><%- lang['Archive'] %></span></div>
|
||||||
<div><select class="form-control" name="archive">
|
<div><select class="form-control" name="archive">
|
||||||
<option value="0" selected><%- lang['No'] %></option>
|
<option value="0" selected><%- lang['No'] %></option>
|
||||||
<option value="1"><%- lang['Yes'] %></option>
|
<option value="1"><%- lang['Yes'] %></option>
|
||||||
</select></div>
|
</select></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label><div><span><%- lang['Email Details'] %></span></div>
|
<label><div><span><%- lang['Email Details'] %></span></div>
|
||||||
<div><select class="form-control" name="email">
|
<div><select class="form-control" name="email">
|
||||||
<option value="0" selected><%- lang['No'] %></option>
|
<option value="0" selected><%- lang['No'] %></option>
|
||||||
<option value="1"><%- lang['Yes'] %></option>
|
<option value="1"><%- lang['Yes'] %></option>
|
||||||
</select></div>
|
</select></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label><div><span><%- lang['Delete Matches'] %></span></div>
|
<label><div><span><%- lang['Delete Matches'] %></span></div>
|
||||||
<div><select class="form-control" name="delete">
|
<div><select class="form-control" name="delete">
|
||||||
<option value="0" selected><%- lang['No'] %></option>
|
<option value="0" selected><%- lang['No'] %></option>
|
||||||
<option value="1"><%- lang['Yes'] %></option>
|
<option value="1"><%- lang['Yes'] %></option>
|
||||||
</select></div>
|
</select></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -115,4 +115,5 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.cronfilter.js"></script>
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
<div class="fixed-table-container">
|
<div class="fixed-table-container">
|
||||||
<div class="fixed-table-body">
|
<div class="fixed-table-body">
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<tbody class="search-body"></tbody>
|
<tbody class="search-body"></tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -48,4 +48,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.logviewer.js"></script>
|
||||||
|
|
|
@ -185,7 +185,7 @@
|
||||||
<script>
|
<script>
|
||||||
//add new
|
//add new
|
||||||
$.aN={e:$('#add_edit')};$.aN.f=$.aN.e.find('form')
|
$.aN={e:$('#add_edit')};$.aN.f=$.aN.e.find('form')
|
||||||
$.aN.modeIsEdit = false
|
$.aN.modeIsEdit = function(){return $('#edit').is(':checked')}
|
||||||
$.aN.f.submit(function(e){
|
$.aN.f.submit(function(e){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var formValues = $.aN.f.serializeObject()
|
var formValues = $.aN.f.serializeObject()
|
||||||
|
@ -193,7 +193,7 @@ $.aN.f.submit(function(e){
|
||||||
data: formValues
|
data: formValues
|
||||||
}
|
}
|
||||||
var webPath = 'registerAdmin'
|
var webPath = 'registerAdmin'
|
||||||
if($.aN.modeIsEdit){
|
if($.aN.modeIsEdit()){
|
||||||
webPath = 'editAdmin'
|
webPath = 'editAdmin'
|
||||||
postData.account = $.aN.selected
|
postData.account = $.aN.selected
|
||||||
}
|
}
|
||||||
|
@ -210,14 +210,23 @@ $.aN.e.on('change','[name="mail"]',function(){
|
||||||
var thisVal = $(this).val()
|
var thisVal = $(this).val()
|
||||||
$.each(users,function(n,user){
|
$.each(users,function(n,user){
|
||||||
if($.aN.selected && user.ke !== $.aN.selected.ke && thisVal.toLowerCase() === user.mail.toLowerCase()){
|
if($.aN.selected && user.ke !== $.aN.selected.ke && thisVal.toLowerCase() === user.mail.toLowerCase()){
|
||||||
new PNotify({text:"<%=lang['Email address is in use.']%>",type:'error'})
|
new PNotify({text:lang['Email address is in use.'],type:'error'})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
//client side group key check
|
||||||
|
$.aN.e.on('change','[name="ke"]',function(){
|
||||||
|
var thisVal = $(this).val()
|
||||||
|
$.each(users,function(n,user){
|
||||||
|
if(!$.aN.modeIsEdit() && user.ke === thisVal){
|
||||||
|
new PNotify({text:lang['Group Key is in use.'] + ' ' + lang['Create Sub-Accounts at /admin'],type:'error'})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
$.aN.e.on('change','[detail]',function(){
|
$.aN.e.on('change','[detail]',function(){
|
||||||
e = {}
|
e = {}
|
||||||
e.ar = {}
|
e.ar = {}
|
||||||
if($.aN.modeIsEdit){
|
if($.aN.modeIsEdit()){
|
||||||
try{
|
try{
|
||||||
e.ar = Object.assign(JSON.parse($.aN.selected.details),{})
|
e.ar = Object.assign(JSON.parse($.aN.selected.details),{})
|
||||||
}catch(err){
|
}catch(err){
|
||||||
|
@ -232,12 +241,10 @@ $.aN.e.on('change','[detail]',function(){
|
||||||
})
|
})
|
||||||
$('#edit').change(function(e){
|
$('#edit').change(function(e){
|
||||||
if($('#edit').is(':checked')){
|
if($('#edit').is(':checked')){
|
||||||
$.aN.modeIsEdit = true
|
$('#title').text(lang['Edit'])
|
||||||
$('#title').text("<%-lang['Edit']%>")
|
|
||||||
$.aN.e.find('[name="ke"]').prop('disabled',true)
|
$.aN.e.find('[name="ke"]').prop('disabled',true)
|
||||||
}else{
|
}else{
|
||||||
$.aN.modeIsEdit = false
|
$('#title').text(lang['Add New'])
|
||||||
$('#title').text("<%-lang['Add New']%>")
|
|
||||||
$.aN.e.find('input,select').prop('disabled',false)
|
$.aN.e.find('input,select').prop('disabled',false)
|
||||||
}
|
}
|
||||||
$.aN.e.find('[detail]').first().change()
|
$.aN.e.find('[detail]').first().change()
|
||||||
|
@ -288,6 +295,7 @@ $.aC.e.on('click','.delete',function(e){
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
$.aC.e.on('click','.permission',function(e){
|
$.aC.e.on('click','.permission',function(e){
|
||||||
|
$('#edit').prop('checked',true).change().parent().addClass('is-checked')
|
||||||
$.aN.e.modal('show')
|
$.aN.e.modal('show')
|
||||||
e.e=$(this).parents('tr');
|
e.e=$(this).parents('tr');
|
||||||
e.u=e.e.attr('ke');
|
e.u=e.e.attr('ke');
|
||||||
|
@ -303,7 +311,6 @@ $.aC.e.on('click','.permission',function(e){
|
||||||
$.each(JSON.parse(e.account.details),function(n,v){
|
$.each(JSON.parse(e.account.details),function(n,v){
|
||||||
$.aN.e.find('[detail="'+n+'"]').val(v)
|
$.aN.e.find('[detail="'+n+'"]').val(v)
|
||||||
})
|
})
|
||||||
$('#edit').prop('checked',true).change().parent().addClass('is-checked')
|
|
||||||
// $.pR.e.modal('show');
|
// $.pR.e.modal('show');
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
<div class="modal dark fade" id="monitorStates" role="dialog" aria-labelledby="monitorStatesLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<form 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="monitorStatesLabel"><i class="fa fa-align-right"></i> <%-lang['Monitor States']%></h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
<div><select class="form-control" id="monitorStatesSelector">
|
||||||
|
<option value=""><%-lang['Add New']%></option>
|
||||||
|
<optgroup label="<%-lang['Saved Presets']%>"></optgroup>
|
||||||
|
</select></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group-group green">
|
||||||
|
<h4><%- lang['Preset'] %>
|
||||||
|
<div class="pull-right">
|
||||||
|
<a class="btn btn-danger btn-xs delete" style="display:none"> <i class="fa fa-trash-o"></i> </a>
|
||||||
|
</div>
|
||||||
|
</h4>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><div><span><%-lang['Name']%></span></div>
|
||||||
|
<div><input class="form-control" name="name"></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group-group blue">
|
||||||
|
<h4><%- lang['Monitors'] %>
|
||||||
|
<div class="pull-right">
|
||||||
|
<a class="btn btn-default btn-xs add"> <i class="fa fa-plus"></i> </a>
|
||||||
|
</div>
|
||||||
|
</h4>
|
||||||
|
<div id="monitorStatesMonitors">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default pull-left" data-dismiss="modal"><i class="fa fa-times"></i> <%-lang.Close%></button>
|
||||||
|
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#schedules"><i class="fa fa-clock-o"></i> <%-lang.Schedules%></button>
|
||||||
|
<button type="submit" class="btn btn-success"><i class="fa fa-check"></i> <%-lang.Save%></button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$.monitorStates = {
|
||||||
|
e: $('#monitorStates'),
|
||||||
|
selector: $('#monitorStatesSelector'),
|
||||||
|
monitors: $('#monitorStatesMonitors'),
|
||||||
|
loaded: {}
|
||||||
|
}
|
||||||
|
$.monitorStates.f = $.monitorStates.e.find('form')
|
||||||
|
$.monitorStates.loadPresets = function(callback){
|
||||||
|
$.get($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke,function(d){
|
||||||
|
var html = ''
|
||||||
|
$.each(d.presets,function(n,v){
|
||||||
|
$.monitorStates.loaded[v.name] = v
|
||||||
|
html += '<option value="' + v.name + '">' + v.name + '</option>'
|
||||||
|
})
|
||||||
|
$.monitorStates.selector.find('optgroup').html(html)
|
||||||
|
if(callback)callback()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$.monitorStates.e.on('shown.bs.modal', function (e) {
|
||||||
|
if($.monitorStates.selector.val() === '')$.monitorStates.loadPresets()
|
||||||
|
})
|
||||||
|
$.monitorStates.add = function(loaded,doAppend){
|
||||||
|
if(!loaded){
|
||||||
|
json = ''
|
||||||
|
}else{
|
||||||
|
json = JSON.stringify(loaded,null,3)
|
||||||
|
}
|
||||||
|
var html = '<div class="state-monitor-row"><h4 style="margin-top:7.5px;margin-bottom:7.5px"><small> </small><div class="pull-right"><a class="btn btn-danger btn-xs delete-monitor"><i class="fa fa-trash-o"></i></a></div></h4><textarea class="json form-control" style="width:100%;height:300px">' + json +'</textarea></div>'
|
||||||
|
if(doAppend)$.monitorStates.monitors.append(html)
|
||||||
|
return html
|
||||||
|
}
|
||||||
|
$.monitorStates.e.find('.add').click(function(e){
|
||||||
|
$.monitorStates.add(null,true)
|
||||||
|
})
|
||||||
|
$.monitorStates.e.on('change','.json',function(e){
|
||||||
|
var el = $(this)
|
||||||
|
var val = el.val()
|
||||||
|
try{
|
||||||
|
el.css('border-color','green')
|
||||||
|
var parsed = JSON.parse(val)
|
||||||
|
el.val(JSON.stringify(parsed,null,3))
|
||||||
|
}catch(err){
|
||||||
|
el.css('border-color','red')
|
||||||
|
return $.ccio.init('note',{title:lang['Invalid JSON'],text:lang.InvalidJSONText,type:'error'})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.monitorStates.e.on('click','.delete',function(e){
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text(lang['Delete Monitor States Preset']);
|
||||||
|
$.confirm.body.html(lang.deleteMonitorStateText1);
|
||||||
|
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||||
|
var form = $.monitorStates.f.serializeObject()
|
||||||
|
$.post($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke + '/' + form.name + '/delete',function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
if(d.ok === true){
|
||||||
|
$.monitorStates.loadPresets()
|
||||||
|
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
$.monitorStates.e.on('click','.delete-monitor',function(e){
|
||||||
|
var el = $(this).parents('.state-monitor-row')
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text(lang['Delete Monitor State']);
|
||||||
|
$.confirm.body.html(lang.deleteMonitorStateText2)
|
||||||
|
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||||
|
el.remove()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
$.monitorStates.selector.change(function(e){
|
||||||
|
var selected = $(this).val()
|
||||||
|
var loaded = $.monitorStates.loaded[selected]
|
||||||
|
var namespace = $.monitorStates.e.find('[name="name"]')
|
||||||
|
var deleteButton = $.monitorStates.e.find('.delete')
|
||||||
|
if(loaded){
|
||||||
|
namespace.val(loaded.name)
|
||||||
|
var html = ''
|
||||||
|
$.each(loaded.details.monitors,function(n,v){
|
||||||
|
html += $.monitorStates.add(v)
|
||||||
|
})
|
||||||
|
$.monitorStates.monitors.html(html)
|
||||||
|
deleteButton.show()
|
||||||
|
}else{
|
||||||
|
namespace.val('')
|
||||||
|
$.monitorStates.monitors.empty()
|
||||||
|
deleteButton.hide()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.monitorStates.f.submit(function(e){
|
||||||
|
e.preventDefault()
|
||||||
|
var el = $(this)
|
||||||
|
var form = el.serializeObject()
|
||||||
|
var monitors = []
|
||||||
|
var failedToParseAJson = false
|
||||||
|
var rows = $.monitorStates.monitors.find('.state-monitor-row')
|
||||||
|
if(form.name === ''){
|
||||||
|
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Name cannot be empty.'],type:'error'})
|
||||||
|
}
|
||||||
|
if(rows.length === 0){
|
||||||
|
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Must be atleast one row'],type:'error'})
|
||||||
|
}
|
||||||
|
rows.each(function(n,v){
|
||||||
|
var el = $(v)
|
||||||
|
try{
|
||||||
|
console.log(el.find('.json').val())
|
||||||
|
var json = JSON.parse(el.find('.json').val())
|
||||||
|
if(json.mid)monitors.push(json)
|
||||||
|
}catch(err){
|
||||||
|
console.log(err)
|
||||||
|
failedToParseAJson = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if(failedToParseAJson === true){
|
||||||
|
return $.ccio.init('note',{title:lang['Invalid JSON'],text:lang.InvalidJSONText,type:'error'})
|
||||||
|
}
|
||||||
|
var data = {
|
||||||
|
monitors: monitors
|
||||||
|
}
|
||||||
|
$.post($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke + '/' + form.name + '/insert',{data:data},function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
if(d.ok === true){
|
||||||
|
$.monitorStates.loadPresets(function(){
|
||||||
|
$.monitorStates.selector.val(form.name)
|
||||||
|
})
|
||||||
|
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -169,7 +169,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><div><span><%-lang['Retry Connection']%></span></div>
|
<label><div><span><%-lang['Retry Connection']%></span></div>
|
||||||
<div><input class="form-control" detail="fatal_max" placeholder="10"></div>
|
<div><input class="form-control" detail="fatal_max" placeholder="0"></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -284,6 +284,14 @@
|
||||||
<div><input class="form-control" detail="hwaccel_device"></div>
|
<div><input class="form-control" detail="hwaccel_device"></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><div><span><%-lang['Use coProcessor']%></span></div>
|
||||||
|
<div><select class="form-control" detail="use_coprocessor">
|
||||||
|
<option value="0" selected><%-lang.No%></option>
|
||||||
|
<option value="1"><%-lang.Yes%></option>
|
||||||
|
</select></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- END of Input -->
|
<!-- END of Input -->
|
||||||
|
@ -842,6 +850,11 @@
|
||||||
<div><input class="form-control" detail="cust_record"></div>
|
<div><input class="form-control" detail="cust_record"></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group h_rec_mtd_input h_rec_mtd_sip" style="display:none">
|
||||||
|
<label><div><span><%-lang['Traditional Recording Flags']%></span></div>
|
||||||
|
<div><input class="form-control" detail="cust_sip_record"></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><div><span><%-lang['Output Method']%></span></div>
|
<label><div><span><%-lang['Output Method']%></span></div>
|
||||||
<div><input class="form-control" detail="custom_output" placeholder="-f flv rtmp://.."></div>
|
<div><input class="form-control" detail="custom_output" placeholder="-f flv rtmp://.."></div>
|
||||||
|
@ -1065,14 +1078,6 @@
|
||||||
</select></div>
|
</select></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group h_det_pam_input h_det_pam_1">
|
|
||||||
<label><div><span><%-lang['Show Matrices']%></span></div>
|
|
||||||
<div><select class="form-control" detail="detector_show_matrix">
|
|
||||||
<option value="0" selected><%-lang.No%></option>
|
|
||||||
<option value="1"><%-lang.Yes%></option>
|
|
||||||
</select></div>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><div><span><%-lang['Indifference']%></span></div>
|
<label><div><span><%-lang['Indifference']%></span></div>
|
||||||
<div><input class="form-control" detail="detector_sensitivity" placeholder="0.5"></div>
|
<div><input class="form-control" detail="detector_sensitivity" placeholder="0.5"></div>
|
||||||
|
@ -1114,16 +1119,6 @@
|
||||||
<div><input class="form-control" detail="detector_noise_filter_range" placeholder="6"></div>
|
<div><input class="form-control" detail="detector_noise_filter_range" placeholder="6"></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<!--
|
|
||||||
<div class="form-group">
|
|
||||||
<label><div><span><%-lang['Show Regions of Interest']%></span></div>
|
|
||||||
<div><select class="form-control" detail="detector_region_of_interest">
|
|
||||||
<option value="0" selected><%-lang.No%></option>
|
|
||||||
<option value="1"><%-lang.Yes%></option>
|
|
||||||
</select></div>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
<div class="form-group-group orange" section id="monSectionNoMotionDetector">
|
<div class="form-group-group orange" section id="monSectionNoMotionDetector">
|
||||||
<h4><%-lang['"No Motion" Detector']%></h4>
|
<h4><%-lang['"No Motion" Detector']%></h4>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -1149,6 +1144,29 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Start of Audio Detection -->
|
||||||
|
<div class="form-group-group orange" section id="monSectionAudioDetector">
|
||||||
|
<h4><%-lang['Audio Detector']%></h4>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><div><span><%-lang['Enabled']%></span></div>
|
||||||
|
<div><select class="form-control" detail="detector_audio">
|
||||||
|
<option value="0" selected><%-lang.No%></option>
|
||||||
|
<option value="1"><%-lang.Yes%></option>
|
||||||
|
</select></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><div><span><%-lang['Minimum dB']%></span></div>
|
||||||
|
<div><input class="form-control" detail="detector_audio_min_db" placeholder="5"></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><div><span><%-lang['Maximum dB']%></span></div>
|
||||||
|
<div><input class="form-control" detail="detector_audio_max_db" placeholder=""></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- END of Audio Detection -->
|
||||||
<div class="form-group-group orange shinobi-detector-opencv shinobi-detector-openalpr shinobi-detector-yolo shinobi-detector-dlib shinobi-detector_plug" section id="monSectionDetectorObject">
|
<div class="form-group-group orange shinobi-detector-opencv shinobi-detector-openalpr shinobi-detector-yolo shinobi-detector-dlib shinobi-detector_plug" section id="monSectionDetectorObject">
|
||||||
<h4><%-lang['Object Detection']%> <small><%-lang['Plugin']%> : <b class="shinobi-detector_name"></b> <b class="shinobi-detector-invert"><%-lang['Not Connected']%></b><b class="shinobi-detector" style="display:none"><%-lang['Connected']%></b></small></h4>
|
<h4><%-lang['Object Detection']%> <small><%-lang['Plugin']%> : <b class="shinobi-detector_name"></b> <b class="shinobi-detector-invert"><%-lang['Not Connected']%></b><b class="shinobi-detector" style="display:none"><%-lang['Connected']%></b></small></h4>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -1159,6 +1177,14 @@
|
||||||
</select></div>
|
</select></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><div><span><%-lang['Require Object to be in Region']%></span></div>
|
||||||
|
<div><select class="form-control" detail="detector_obj_region">
|
||||||
|
<option value="0" selected><%-lang.No%></option>
|
||||||
|
<option value="1"><%-lang.Yes%></option>
|
||||||
|
</select></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><div><span><%-lang['Check for Motion First']%></span></div>
|
<label><div><span><%-lang['Check for Motion First']%></span></div>
|
||||||
<div><select class="form-control" detail="detector_use_motion" selector="h_det_mot_fir">
|
<div><select class="form-control" detail="detector_use_motion" selector="h_det_mot_fir">
|
||||||
|
@ -1597,3 +1623,4 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.monitoredit.js"></script>
|
||||||
|
|
|
@ -35,4 +35,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.multimon.js"></script>
|
||||||
|
|
|
@ -84,3 +84,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.powervideo.js"></script>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-default pull-left" data-dismiss="modal"><i class="fa fa-times"></i> <%-lang.Close%></button>
|
<button type="button" class="btn btn-default pull-left" data-dismiss="modal"><i class="fa fa-times"></i> <%-lang.Close%></button>
|
||||||
<a class="btn btn-danger stop" style="display:none"><%-lang.Stop%><span> <i class="fa fa-pulse fa-spinner"></i></span></a>
|
<a class="btn btn-danger stop" style="display:none"><%-lang.Stop%><span> <i class="fa fa-pulse fa-spinner"></i></span></a>
|
||||||
<button type="submit" class="btn btn-success"><%-lang.Check%></button>
|
<button type="submit" class="btn btn-success"><%-lang.Check%></button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -91,4 +91,7 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- -->
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.probe.js"></script>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.onvifscanner.js"></script>
|
||||||
|
|
|
@ -81,3 +81,4 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.regioneditor.js"></script>
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
<div class="modal dark fade" id="schedules" role="dialog" aria-labelledby="schedulesLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<form 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="schedulesLabel"><i class="fa fa-clock-o"></i> <%-lang['Schedules']%></h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
<div><select class="form-control" id="schedulesSelector">
|
||||||
|
<option value=""><%-lang['Add New']%></option>
|
||||||
|
<optgroup label="<%-lang['Saved Schedules']%>"></optgroup>
|
||||||
|
</select></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group-group green">
|
||||||
|
<h4><%- lang['Schedule'] %>
|
||||||
|
<div class="pull-right">
|
||||||
|
<a class="btn btn-danger btn-xs delete" style="display:none"> <i class="fa fa-trash-o"></i> </a>
|
||||||
|
</div>
|
||||||
|
</h4>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><div><span><%-lang['Name']%></span></div>
|
||||||
|
<div><input class="form-control" name="name"></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><div><span><%-lang['Enabled']%></span></div>
|
||||||
|
<div><select class="form-control" name="enabled">
|
||||||
|
<option value="1" selected><%-lang.Yes%></option>
|
||||||
|
<option value="0"><%-lang.No%></option>
|
||||||
|
</select></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><div><span><%-lang['Start']%></span></div>
|
||||||
|
<div><input class="form-control" name="start" placeholder="HH:ss"></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><div><span><%-lang['End']%></span></div>
|
||||||
|
<div><input class="form-control" name="end" placeholder="HH:ss"></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><div><span><%-lang['Monitor States']%></span></div>
|
||||||
|
<div><select class="form-control" style="min-height:100px" multiple name="monitorStates">
|
||||||
|
</select></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default pull-left" data-dismiss="modal"><i class="fa fa-times"></i> <%-lang.Close%></button>
|
||||||
|
<button type="submit" class="btn btn-success"><i class="fa fa-check"></i> <%-lang.Save%></button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$.schedules = {
|
||||||
|
e: $('#schedules'),
|
||||||
|
selector: $('#schedulesSelector'),
|
||||||
|
loadedMonitorStates: {},
|
||||||
|
loadedSchedules: {}
|
||||||
|
}
|
||||||
|
$.schedules.f = $.schedules.e.find('form')
|
||||||
|
$.schedules.selectedStates = $.schedules.e.find('[name="monitorStates"]')
|
||||||
|
$.schedules.loadSchedules = function(callback){
|
||||||
|
$.get($.ccio.init('location',$user) + $user.auth_token + '/schedule/' + $user.ke,function(d){
|
||||||
|
console.log(d)
|
||||||
|
var html = ''
|
||||||
|
$.each(d.schedules,function(n,v){
|
||||||
|
$.schedules.loadedSchedules[v.name] = v
|
||||||
|
html += $.ccio.tm('option',{
|
||||||
|
id: v.name,
|
||||||
|
name: v.name
|
||||||
|
})
|
||||||
|
})
|
||||||
|
$.schedules.selector.find('optgroup').html(html)
|
||||||
|
if(callback)callback()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$.schedules.loadMonitorStates = function(){
|
||||||
|
$.get($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke,function(d){
|
||||||
|
var html = ''
|
||||||
|
$.each(d.presets,function(n,v){
|
||||||
|
$.schedules.loadedMonitorStates[v.name] = v
|
||||||
|
html += $.ccio.tm('option',{
|
||||||
|
id: v.name,
|
||||||
|
name: v.name
|
||||||
|
})
|
||||||
|
})
|
||||||
|
$.schedules.selectedStates.html(html)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$.schedules.e.on('shown.bs.modal', function (e) {
|
||||||
|
$.schedules.loadMonitorStates()
|
||||||
|
$.schedules.loadSchedules()
|
||||||
|
})
|
||||||
|
$.schedules.e.on('click','.delete',function(e){
|
||||||
|
$.confirm.e.modal('show');
|
||||||
|
$.confirm.title.text(lang['Delete Monitor States Preset']);
|
||||||
|
$.confirm.body.html(lang.deleteMonitorStateText1);
|
||||||
|
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||||
|
var form = $.schedules.f.serializeObject()
|
||||||
|
$.post($.ccio.init('location',$user) + $user.auth_token + '/schedule/' + $user.ke + '/' + form.name + '/delete',function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
if(d.ok === true){
|
||||||
|
$.schedules.loadSchedules()
|
||||||
|
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
$.schedules.selector.change(function(e){
|
||||||
|
var selected = $(this).val()
|
||||||
|
var loaded = $.schedules.loadedSchedules[selected]
|
||||||
|
var namespace = $.schedules.e.find('[name="name"]')
|
||||||
|
var deleteButton = $.schedules.e.find('.delete')
|
||||||
|
$.schedules.selectedStates.find('option:selected').removeAttr('selected')
|
||||||
|
if(loaded){
|
||||||
|
namespace.val(loaded.name)
|
||||||
|
var html = ''
|
||||||
|
$.each(loaded,function(n,v){
|
||||||
|
$.schedules.f.find('[name="' + n + '"]').val(v)
|
||||||
|
})
|
||||||
|
$.each(loaded.details.monitorStates,function(n,v){
|
||||||
|
$.schedules.selectedStates.find('option[value="' + v + '"]').prop('selected',true)
|
||||||
|
})
|
||||||
|
deleteButton.show()
|
||||||
|
}else{
|
||||||
|
namespace.val('')
|
||||||
|
deleteButton.hide()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.schedules.f.submit(function(e){
|
||||||
|
e.preventDefault()
|
||||||
|
var el = $(this)
|
||||||
|
var form = el.serializeObject()
|
||||||
|
var monitors = []
|
||||||
|
var failedToParseAJson = false
|
||||||
|
var rows = $.monitorStates.monitors.find('.state-monitor-row')
|
||||||
|
if(form.name === ''){
|
||||||
|
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Name cannot be empty.'],type:'error'})
|
||||||
|
}
|
||||||
|
if(form.start === ''){
|
||||||
|
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Start Time cannot be empty.'],type:'error'})
|
||||||
|
}
|
||||||
|
if(form.monitorStates instanceof Array === false){
|
||||||
|
form.monitorStates = [form.monitorStates]
|
||||||
|
}
|
||||||
|
console.log(form.monitorStates)
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
start: form.start,
|
||||||
|
end: form.end,
|
||||||
|
enabled: form.enabled,
|
||||||
|
details:{
|
||||||
|
monitorStates: form.monitorStates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.post($.ccio.init('location',$user) + $user.auth_token + '/schedule/' + $user.ke + '/' + form.name + '/insert',{data:data},function(d){
|
||||||
|
$.ccio.log(d)
|
||||||
|
if(d.ok === true){
|
||||||
|
$.schedules.loadSchedules(function(){
|
||||||
|
$.schedules.selector.val(form.name)
|
||||||
|
})
|
||||||
|
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -503,3 +503,4 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.usersettings.js"></script>
|
||||||
|
|
|
@ -77,4 +77,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.timelapse.js"></script>
|
||||||
|
|
|
@ -77,3 +77,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.vidview.js"></script>
|
||||||
|
|
|
@ -14,7 +14,22 @@
|
||||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/gridstack.min.css">
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/gridstack.min.css">
|
||||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/gridstack-extra.min.css">
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/gridstack-extra.min.css">
|
||||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/bootstrap-table.min.css">
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/bootstrap-table.min.css">
|
||||||
|
<!--
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.basic.css">
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.forms.css">
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.modal.css">
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.monitors.css">
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.powervideo.css">
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.ptzcontrols.css">
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.regioneditor.css">
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.rightotleft.css">
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.timelapse.css">
|
||||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.css">
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.css">
|
||||||
|
-->
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.old.css">
|
||||||
|
<% customAutoLoad.LibsCss.forEach(function(lib){ %>
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/<%-lib%>">
|
||||||
|
<% }) %>
|
||||||
<style id="theme">
|
<style id="theme">
|
||||||
<% if(details.theme&&details.theme!==''){ %><%- include(__dirname+'/web/libs/themes/'+details.theme+'/style.css'); %><% } %>
|
<% if(details.theme&&details.theme!==''){ %><%- include(__dirname+'/web/libs/themes/'+details.theme+'/style.css'); %><% } %>
|
||||||
</style>
|
</style>
|
||||||
|
@ -121,6 +136,8 @@
|
||||||
<% if(!details.sub){ %>
|
<% if(!details.sub){ %>
|
||||||
<li class="mdl-menu__item" data-toggle="modal" data-target="#onvif_probe"><div><i class="fa fa-rss"></i><div><%- lang.ONVIF %></div></div></li>
|
<li class="mdl-menu__item" data-toggle="modal" data-target="#onvif_probe"><div><i class="fa fa-rss"></i><div><%- lang.ONVIF %></div></div></li>
|
||||||
<li class="mdl-menu__item" data-toggle="modal" data-target="#probe"><div><i class="fa fa-search"></i><div><%- lang.FFprobe %></div></div></li>
|
<li class="mdl-menu__item" data-toggle="modal" data-target="#probe"><div><i class="fa fa-search"></i><div><%- lang.FFprobe %></div></div></li>
|
||||||
|
<li class="mdl-menu__item" data-toggle="modal" data-target="#monitorStates"><div><i class="fa fa-align-right"></i><div><%- lang['Monitor States'] %></div></div></li>
|
||||||
|
<li class="mdl-menu__item" data-toggle="modal" data-target="#schedules"><div><i class="fa fa-clock-o"></i><div><%- lang['Schedules'] %></div></div></li>
|
||||||
<li class="mdl-menu__item" data-toggle="modal" data-target="#filters"><div><i class="fa fa-filter"></i><div><%- lang.Filters %></div></div></li>
|
<li class="mdl-menu__item" data-toggle="modal" data-target="#filters"><div><i class="fa fa-filter"></i><div><%- lang.Filters %></div></div></li>
|
||||||
<% } %>
|
<% } %>
|
||||||
<li class="mdl-menu__item permission_view_logs" data-toggle="modal" data-target="#logs_modal"><div><i class="fa fa-exclamation-triangle"></i><div><%- lang.Logs %></div></div></li>
|
<li class="mdl-menu__item permission_view_logs" data-toggle="modal" data-target="#logs_modal"><div><i class="fa fa-exclamation-triangle"></i><div><%- lang.Logs %></div></div></li>
|
||||||
|
@ -167,7 +184,12 @@
|
||||||
<% include blocks/probe.ejs %>
|
<% include blocks/probe.ejs %>
|
||||||
<% include blocks/region.ejs %>
|
<% include blocks/region.ejs %>
|
||||||
<% include blocks/detectorfilters.ejs %>
|
<% include blocks/detectorfilters.ejs %>
|
||||||
|
<% include blocks/monitorStates.ejs %>
|
||||||
|
<% include blocks/schedules.ejs %>
|
||||||
<% include blocks/confirm.ejs %>
|
<% include blocks/confirm.ejs %>
|
||||||
|
<% customAutoLoad.PageBlocks.forEach(function(block){ %>
|
||||||
|
<%- include(block) %>
|
||||||
|
<% }) %>
|
||||||
<% if(config.DropboxAppKey){ %>
|
<% if(config.DropboxAppKey){ %>
|
||||||
<!--Dropbox Library, Change data-app-key to your app key. -->
|
<!--Dropbox Library, Change data-app-key to your app key. -->
|
||||||
<script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="<%= config.DropboxAppKey %>"></script>
|
<script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="<%= config.DropboxAppKey %>"></script>
|
||||||
|
@ -198,5 +220,15 @@
|
||||||
<script src="<%-window.libURL%>libs/js/gridstack.min.js"></script>
|
<script src="<%-window.libURL%>libs/js/gridstack.min.js"></script>
|
||||||
<script src="<%-window.libURL%>libs/js/gridstack.jQueryUI.min.js"></script>
|
<script src="<%-window.libURL%>libs/js/gridstack.jQueryUI.min.js"></script>
|
||||||
<script src="<%-window.libURL%>libs/js/basic.js"></script>
|
<script src="<%-window.libURL%>libs/js/basic.js"></script>
|
||||||
<script><% include ../libs/js/main.dash2.js %></script>
|
<script><% include ../libs/js/dash2.config.js %></script>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.basic.js"></script>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.confirm.js"></script>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.socketio.js"></script>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.gridstack.js"></script>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.elements.js"></script>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.elementbuilder.js"></script>
|
||||||
|
<script src="<%-window.libURL%>libs/js/dash2.init.js"></script>
|
||||||
|
<% customAutoLoad.LibsJs.forEach(function(lib){ %>
|
||||||
|
<script src="<%-window.libURL%>libs/js/<%-lib%>"></script>
|
||||||
|
<% }) %>
|
||||||
<% include blocks/help.ejs %>
|
<% include blocks/help.ejs %>
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
.list-group li .form-group {margin:0}
|
.list-group li .form-group {margin:0}
|
||||||
a {cursor:pointer}
|
a {cursor:pointer}
|
||||||
</style>
|
</style>
|
||||||
|
<% customAutoLoad.superLibsCss.forEach(function(lib){ %>
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/<%-lib%>">
|
||||||
|
<% }) %>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="index-page sidebar-collapse bg-hexagon">
|
<body class="index-page sidebar-collapse bg-hexagon">
|
||||||
|
@ -62,7 +65,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div id="main-card" class="card">
|
<div id="main-card" class="card">
|
||||||
<ul class="nav nav-tabs nav-tabs-neutral justify-content-center bg-primary" role="tablist">
|
<ul class="nav nav-tabs nav-tabs-neutral justify-content-center bg-primary" id="tablist" role="tablist">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link active" data-toggle="tab" href="#accounts" role="tab">Accounts</a>
|
<a class="nav-link active" data-toggle="tab" href="#accounts" role="tab">Accounts</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -169,8 +172,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="temp" style="display:none"></div>
|
||||||
</body>
|
</body>
|
||||||
|
<script>
|
||||||
|
var superApiPrefix = "<%=originalURL%><%=config.webPaths.superApiPrefix%>"
|
||||||
|
</script>
|
||||||
<% include blocks/confirm.ejs %>
|
<% include blocks/confirm.ejs %>
|
||||||
|
<% customAutoLoad.superPageBlocks.forEach(function(block){ %>
|
||||||
|
<%- include(block) %>
|
||||||
|
<% }) %>
|
||||||
<script src="<%-window.libURL%>libs/js/pnotify.custom.min.js" type="text/javascript"></script>
|
<script src="<%-window.libURL%>libs/js/pnotify.custom.min.js" type="text/javascript"></script>
|
||||||
<script><% include ../libs/js/moment.js %></script>
|
<script><% include ../libs/js/moment.js %></script>
|
||||||
<script src="<%-window.libURL%>libs/js/livestamp.min.js" type="text/javascript"></script>
|
<script src="<%-window.libURL%>libs/js/livestamp.min.js" type="text/javascript"></script>
|
||||||
|
@ -178,6 +188,7 @@
|
||||||
<script src="<%-window.libURL%>libs/js/placeholder.js" type="text/javascript"></script>
|
<script src="<%-window.libURL%>libs/js/placeholder.js" type="text/javascript"></script>
|
||||||
<script src="<%-window.libURL%>libs/js/now-ui-kit.js?v=1.1.0" type="text/javascript"></script>
|
<script src="<%-window.libURL%>libs/js/now-ui-kit.js?v=1.1.0" type="text/javascript"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
var lang = <%- JSON.stringify(lang) || {} %>;
|
||||||
PNotify.prototype.options.styling = "fontawesome";
|
PNotify.prototype.options.styling = "fontawesome";
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// the body of this function is in assets/js/now-ui-kit.js
|
// the body of this function is in assets/js/now-ui-kit.js
|
||||||
|
@ -530,4 +541,7 @@ $('body')
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<% include blocks/mainpermissions.ejs %>
|
<% include blocks/mainpermissions.ejs %>
|
||||||
|
<% customAutoLoad.superLibsJs.forEach(function(lib){ %>
|
||||||
|
<script src="<%-window.libURL%>libs/js/<%-lib%>"></script>
|
||||||
|
<% }) %>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue