Merge branch 'dev' into 'master'
Paladium : Critical Fixes See merge request Shinobi-Systems/Shinobi!452fix-multi-trigger
commit
1c7cc2e95b
|
@ -20,7 +20,7 @@ bash <(curl -s https://gitlab.com/Shinobi-Systems/Shinobi-Installer/raw/master/s
|
||||||
|
|
||||||
Once complete open port `8080` of your Docker host in a web browser.
|
Once complete open port `8080` of your Docker host in a web browser.
|
||||||
|
|
||||||
## Run Way
|
## "Run" Way
|
||||||
|
|
||||||
**Installing Shinobi**
|
**Installing Shinobi**
|
||||||
|
|
||||||
|
@ -85,6 +85,12 @@ docker run -d --name='Shinobi' -p '8080:8080/tcp' -v "/dev/shm/Shinobi/streams":
|
||||||
|
|
||||||
> Host mount paths have been updated in this document.
|
> Host mount paths have been updated in this document.
|
||||||
|
|
||||||
|
### Running without Included Database (NoDB)
|
||||||
|
|
||||||
|
For information about this please see this Merge Request done by @thtmnisamnstr. It thoroughly documents how to use the NoDB installation method.
|
||||||
|
|
||||||
|
https://gitlab.com/Shinobi-Systems/Shinobi/-/merge_requests/443
|
||||||
|
|
||||||
### Volumes
|
### Volumes
|
||||||
|
|
||||||
| Volumes | Description |
|
| Volumes | Description |
|
||||||
|
|
|
@ -70,13 +70,18 @@ cronKey="$(head -c 1024 < /dev/urandom | sha256sum | awk '{print substr($1,1,29)
|
||||||
|
|
||||||
cd /home/Shinobi
|
cd /home/Shinobi
|
||||||
mkdir -p libs/customAutoLoad
|
mkdir -p libs/customAutoLoad
|
||||||
|
|
||||||
if [ -e "/config/conf.json" ]; then
|
if [ -e "/config/conf.json" ]; then
|
||||||
cp /config/conf.json conf.json
|
cp /config/conf.json conf.json
|
||||||
elif [ ! -e "./conf.json" ]; then
|
elif [ ! -e "./conf.json" ]; then
|
||||||
cp conf.sample.json conf.json
|
cp conf.sample.json conf.json
|
||||||
fi
|
fi
|
||||||
|
# Create /config/conf.json if it doesn't exist
|
||||||
|
if [ ! -e "/config/conf.json" ]; then
|
||||||
|
node tools/modifyConfiguration.js cpuUsageMarker=CPU subscriptionId=$SUBSCRIPTION_ID thisIsDocker=true pluginKeys="$PLUGIN_KEYS" databaseType="$DB_TYPE" db="$DATABASE_CONFIG" ssl="$SSL_CONFIG"
|
||||||
|
cp /config/conf.json conf.json
|
||||||
|
fi
|
||||||
sudo sed -i -e 's/change_this_to_something_very_random__just_anything_other_than_this/'"$cronKey"'/g' conf.json
|
sudo sed -i -e 's/change_this_to_something_very_random__just_anything_other_than_this/'"$cronKey"'/g' conf.json
|
||||||
node tools/modifyConfiguration.js cpuUsageMarker=CPU subscriptionId=$SUBSCRIPTION_ID thisIsDocker=true pluginKeys="$PLUGIN_KEYS" db="$DATABASE_CONFIG" ssl="$SSL_CONFIG"
|
|
||||||
|
|
||||||
|
|
||||||
echo "============="
|
echo "============="
|
||||||
|
|
|
@ -5,6 +5,7 @@ ENV DB_USER=majesticflame \
|
||||||
DB_HOST='localhost' \
|
DB_HOST='localhost' \
|
||||||
DB_DATABASE=ccio \
|
DB_DATABASE=ccio \
|
||||||
DB_PORT=3306 \
|
DB_PORT=3306 \
|
||||||
|
DB_TYPE='mysql' \
|
||||||
SUBSCRIPTION_ID=sub_XXXXXXXXXXXX \
|
SUBSCRIPTION_ID=sub_XXXXXXXXXXXX \
|
||||||
PLUGIN_KEYS='{}' \
|
PLUGIN_KEYS='{}' \
|
||||||
SSL_ENABLED='false' \
|
SSL_ENABLED='false' \
|
||||||
|
|
|
@ -5,6 +5,7 @@ ENV DB_USER=majesticflame \
|
||||||
DB_HOST='localhost' \
|
DB_HOST='localhost' \
|
||||||
DB_DATABASE=ccio \
|
DB_DATABASE=ccio \
|
||||||
DB_PORT=3306 \
|
DB_PORT=3306 \
|
||||||
|
DB_TYPE='mysql' \
|
||||||
SUBSCRIPTION_ID=sub_XXXXXXXXXXXX \
|
SUBSCRIPTION_ID=sub_XXXXXXXXXXXX \
|
||||||
PLUGIN_KEYS='{}' \
|
PLUGIN_KEYS='{}' \
|
||||||
SSL_ENABLED='false' \
|
SSL_ENABLED='false' \
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
FROM node:16-buster-slim
|
||||||
|
|
||||||
|
ENV DB_USER=majesticflame \
|
||||||
|
DB_PASSWORD='' \
|
||||||
|
DB_HOST='localhost' \
|
||||||
|
DB_DATABASE=ccio \
|
||||||
|
DB_PORT=3306 \
|
||||||
|
DB_TYPE='mysql' \
|
||||||
|
SUBSCRIPTION_ID=sub_XXXXXXXXXXXX \
|
||||||
|
PLUGIN_KEYS='{}' \
|
||||||
|
SSL_ENABLED='false' \
|
||||||
|
SSL_COUNTRY='CA' \
|
||||||
|
SSL_STATE='BC' \
|
||||||
|
SSL_LOCATION='Vancouver' \
|
||||||
|
SSL_ORGANIZATION='Shinobi Systems' \
|
||||||
|
SSL_ORGANIZATION_UNIT='IT Department' \
|
||||||
|
SSL_COMMON_NAME='nvr.ninja' \
|
||||||
|
DB_DISABLE_INCLUDED=true
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN mkdir -p /home/Shinobi /config /var/lib/mysql
|
||||||
|
|
||||||
|
RUN apt update -y
|
||||||
|
RUN apt install wget curl net-tools -y
|
||||||
|
|
||||||
|
# Install FFmpeg
|
||||||
|
|
||||||
|
RUN apt update --fix-missing
|
||||||
|
RUN apt install -y software-properties-common \
|
||||||
|
libfreetype6-dev \
|
||||||
|
libgnutls28-dev \
|
||||||
|
libmp3lame-dev \
|
||||||
|
libass-dev \
|
||||||
|
libogg-dev \
|
||||||
|
libtheora-dev \
|
||||||
|
libvorbis-dev \
|
||||||
|
libvpx-dev \
|
||||||
|
libwebp-dev \
|
||||||
|
libssh2-1-dev \
|
||||||
|
libopus-dev \
|
||||||
|
librtmp-dev \
|
||||||
|
libx264-dev \
|
||||||
|
libx265-dev \
|
||||||
|
yasm
|
||||||
|
RUN apt install -y \
|
||||||
|
build-essential \
|
||||||
|
bzip2 \
|
||||||
|
coreutils \
|
||||||
|
procps \
|
||||||
|
gnutls-bin \
|
||||||
|
nasm \
|
||||||
|
tar \
|
||||||
|
x264
|
||||||
|
|
||||||
|
RUN apt install -y zip
|
||||||
|
|
||||||
|
RUN apt install -y \
|
||||||
|
ffmpeg \
|
||||||
|
git \
|
||||||
|
make \
|
||||||
|
g++ \
|
||||||
|
gcc \
|
||||||
|
pkg-config \
|
||||||
|
python3 \
|
||||||
|
wget \
|
||||||
|
tar \
|
||||||
|
sudo \
|
||||||
|
xz-utils
|
||||||
|
|
||||||
|
|
||||||
|
WORKDIR /home/Shinobi
|
||||||
|
COPY . .
|
||||||
|
#RUN rm -rf /home/Shinobi/plugins
|
||||||
|
COPY ./plugins /home/Shinobi/plugins
|
||||||
|
RUN chmod -R 777 /home/Shinobi/plugins
|
||||||
|
RUN npm i npm@latest -g && \
|
||||||
|
npm install --unsafe-perm && \
|
||||||
|
npm install pm2 -g
|
||||||
|
COPY ./Docker/pm2.yml ./
|
||||||
|
|
||||||
|
RUN npm i pg --save
|
||||||
|
|
||||||
|
# Copy default configuration files
|
||||||
|
# COPY ./config/conf.json ./config/super.json /home/Shinobi/
|
||||||
|
RUN chmod -f +x /home/Shinobi/Docker/init.sh
|
||||||
|
RUN sed -i -e 's/\r//g' /home/Shinobi/Docker/init.sh
|
||||||
|
# RUN chmod -f +x /home/Shinobi/shinobi
|
||||||
|
|
||||||
|
VOLUME ["/home/Shinobi/videos"]
|
||||||
|
VOLUME ["/home/Shinobi/libs/customAutoLoad"]
|
||||||
|
VOLUME ["/config"]
|
||||||
|
|
||||||
|
EXPOSE 8080 443 21 25
|
||||||
|
|
||||||
|
ENTRYPOINT ["sh","/home/Shinobi/Docker/init.sh"]
|
||||||
|
|
||||||
|
CMD [ "pm2-docker", "/home/Shinobi/Docker/pm2.yml" ]
|
|
@ -5,6 +5,7 @@ ENV DB_USER=majesticflame \
|
||||||
DB_HOST='localhost' \
|
DB_HOST='localhost' \
|
||||||
DB_DATABASE=ccio \
|
DB_DATABASE=ccio \
|
||||||
DB_PORT=3306 \
|
DB_PORT=3306 \
|
||||||
|
DB_TYPE='mysql' \
|
||||||
SUBSCRIPTION_ID=sub_XXXXXXXXXXXX \
|
SUBSCRIPTION_ID=sub_XXXXXXXXXXXX \
|
||||||
PLUGIN_KEYS='{}' \
|
PLUGIN_KEYS='{}' \
|
||||||
SSL_ENABLED='false' \
|
SSL_ENABLED='false' \
|
||||||
|
|
|
@ -3105,6 +3105,31 @@ module.exports = function(s,config,lang){
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "detail=detector_object_ignore_not_move",
|
||||||
|
"field": lang["Ignore Non-Moving"],
|
||||||
|
"default": "0",
|
||||||
|
"fieldType": "select",
|
||||||
|
"selector": "h_obj_ignore_move",
|
||||||
|
"possible": [
|
||||||
|
{
|
||||||
|
"name": lang.No,
|
||||||
|
"value": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": lang.Yes,
|
||||||
|
"value": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hidden: true,
|
||||||
|
"name": "detail=detector_object_move_percent",
|
||||||
|
"field": lang['Minimum Movement'],
|
||||||
|
"description": lang.inPercent,
|
||||||
|
"default": "5",
|
||||||
|
"form-group-class": "h_obj_ignore_move_input h_obj_ignore_move_1"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
isAdvanced: true,
|
isAdvanced: true,
|
||||||
"name": "detail=detector_send_frames_object",
|
"name": "detail=detector_send_frames_object",
|
||||||
|
@ -4935,24 +4960,6 @@ module.exports = function(s,config,lang){
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"field": lang['Show Thumbnails in Video List'],
|
|
||||||
attribute:'localStorage="showThumbnail"',
|
|
||||||
"description": "",
|
|
||||||
"default": "0",
|
|
||||||
"example": "",
|
|
||||||
"fieldType": "select",
|
|
||||||
"possible": [
|
|
||||||
{
|
|
||||||
"name": lang.No,
|
|
||||||
"value": "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": lang.Yes,
|
|
||||||
"value": "1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"field": lang.Themes,
|
"field": lang.Themes,
|
||||||
"name": "detail=theme",
|
"name": "detail=theme",
|
||||||
|
|
|
@ -196,6 +196,8 @@
|
||||||
"Trigger Camera Groups": "Trigger Camera Groups",
|
"Trigger Camera Groups": "Trigger Camera Groups",
|
||||||
"Motion Detection": "Motion Detection",
|
"Motion Detection": "Motion Detection",
|
||||||
"Object Detection": "Object Detection",
|
"Object Detection": "Object Detection",
|
||||||
|
"Minimum Movement": "Minimum Movement",
|
||||||
|
"inPercent": "In Percent",
|
||||||
"Hide Detection on Stream": "Hide Detection on Stream",
|
"Hide Detection on Stream": "Hide Detection on Stream",
|
||||||
"JPEG Mode": "JPEG Mode",
|
"JPEG Mode": "JPEG Mode",
|
||||||
"Reconnect Stream": "Reconnect Stream",
|
"Reconnect Stream": "Reconnect Stream",
|
||||||
|
@ -394,7 +396,7 @@
|
||||||
"Found Devices": "Found Devices",
|
"Found Devices": "Found Devices",
|
||||||
"Switch on for Still Image": "Switch on for Still Image",
|
"Switch on for Still Image": "Switch on for Still Image",
|
||||||
"Live Stream Toggle": "Live Stream Toggle",
|
"Live Stream Toggle": "Live Stream Toggle",
|
||||||
"RegionNote": "When adding points click on the edge of the polygon. Right click a point to remove.",
|
"RegionNote": "When adding points click on the edge of the polygon. Right click a point to remove it. The dimensions here are based on the Detector Settings of your Monitor. Regions will automatically scale to match Object Detection dimensions.",
|
||||||
"Points": "Points",
|
"Points": "Points",
|
||||||
"Minimum Change": "Minimum Change",
|
"Minimum Change": "Minimum Change",
|
||||||
"Maximum Change": "Maximum Change",
|
"Maximum Change": "Maximum Change",
|
||||||
|
@ -841,6 +843,7 @@
|
||||||
"Delete Motionless Video": "Delete Motionless Video",
|
"Delete Motionless Video": "Delete Motionless Video",
|
||||||
"Send Frames": "Send Frames <small>Push frames to be analyzed</small>",
|
"Send Frames": "Send Frames <small>Push frames to be analyzed</small>",
|
||||||
"Detector Rate": "Detector Rate <small>(FPS)</small>",
|
"Detector Rate": "Detector Rate <small>(FPS)</small>",
|
||||||
|
"Ignore Non-Moving": "Ignore Non-Moving",
|
||||||
"Feed-in Image Width": "Feed-in Image Width",
|
"Feed-in Image Width": "Feed-in Image Width",
|
||||||
"Feed-in Image Height": "Feed-in Image Height",
|
"Feed-in Image Height": "Feed-in Image Height",
|
||||||
"Check for Motion First": "Check for Motion First",
|
"Check for Motion First": "Check for Motion First",
|
||||||
|
|
|
@ -114,14 +114,16 @@ module.exports = (processCwd,config) => {
|
||||||
method : options.method || 'GET',
|
method : options.method || 'GET',
|
||||||
headers: {'Content-Type': 'application/json'}
|
headers: {'Content-Type': 'application/json'}
|
||||||
}
|
}
|
||||||
if(typeof options.postData === 'object'){
|
if(requestOptions.method !== 'GET'){
|
||||||
requestOptions.body = JSON.stringify(options.postData)
|
if(typeof options.postData === 'object'){
|
||||||
} else if(typeof options.postData === 'string'){
|
requestOptions.body = JSON.stringify(options.postData)
|
||||||
try{
|
}else if(options.postData && typeof options.postData === 'string'){
|
||||||
JSON.parse(options.postData)
|
try{
|
||||||
requestOptions.body = options.postData
|
JSON.parse(options.postData)
|
||||||
}catch(err){
|
requestOptions.body = options.postData
|
||||||
|
}catch(err){
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(hasUsernameAndPassword && hasDigestAuthEnabled){
|
if(hasUsernameAndPassword && hasDigestAuthEnabled){
|
||||||
|
|
|
@ -27,7 +27,7 @@ parentPort.on('message',(data) => {
|
||||||
case'init':
|
case'init':
|
||||||
config = Object.assign({},data.config)
|
config = Object.assign({},data.config)
|
||||||
lang = Object.assign({},data.lang)
|
lang = Object.assign({},data.lang)
|
||||||
remoteConnectionPort = config.ssl ? config.ssl.port || 443 : config.port || 8080
|
remoteConnectionPort = config.ssl && JSON.stringify(config.ssl) !== '{}' ? config.ssl.port || 443 : config.port || 8080
|
||||||
initialize()
|
initialize()
|
||||||
break;
|
break;
|
||||||
case'exit':
|
case'exit':
|
||||||
|
@ -332,7 +332,7 @@ function closeResponseTunnel(originalRequestId){
|
||||||
function initialize(){
|
function initialize(){
|
||||||
const selectedP2PServerId = config.p2pServerList[config.p2pHostSelected] ? config.p2pHostSelected : Object.keys(config.p2pServerList)[0]
|
const selectedP2PServerId = config.p2pServerList[config.p2pHostSelected] ? config.p2pHostSelected : Object.keys(config.p2pServerList)[0]
|
||||||
const p2pServerDetails = config.p2pServerList[selectedP2PServerId]
|
const p2pServerDetails = config.p2pServerList[selectedP2PServerId]
|
||||||
const selectedHost = 'ws://' + p2pServerDetails.host + ':' + p2pServerDetails.p2pPort
|
const selectedHost = `${p2pServerDetails.secure ? `wss` : 'ws'}://` + p2pServerDetails.host + ':' + p2pServerDetails.p2pPort
|
||||||
config.selectedHost = selectedHost
|
config.selectedHost = selectedHost
|
||||||
startConnection(selectedHost,config.p2pApiKey)
|
startConnection(selectedHost,config.p2pApiKey)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
const movingThings = require('shinobi-node-moving-things-tracker').Tracker
|
||||||
|
module.exports = (s,config,lang,app,io) => {
|
||||||
|
const objectTrackers = {}
|
||||||
|
const objectTrackerTimeouts = {}
|
||||||
|
function resetObjectTracker(trackerId,matrices){
|
||||||
|
const Tracker = movingThings.newTracker();
|
||||||
|
objectTrackers[trackerId] = {
|
||||||
|
frameCount: 1,
|
||||||
|
tracker: Tracker,
|
||||||
|
lastPositions: []
|
||||||
|
}
|
||||||
|
return objectTrackers[trackerId]
|
||||||
|
}
|
||||||
|
function setLastTracked(trackerId, trackedMatrices){
|
||||||
|
const theTracker = objectTrackers[trackerId]
|
||||||
|
theTracker.lastPositions = trackedMatrices
|
||||||
|
}
|
||||||
|
function getTracked(trackerId){
|
||||||
|
const theTracker = objectTrackers[trackerId]
|
||||||
|
const frameCount = theTracker.frameCount
|
||||||
|
const trackedObjects = theTracker.tracker.getJSONOfTrackedItems().map((matrix) => {
|
||||||
|
return {
|
||||||
|
id: matrix.id,
|
||||||
|
tag: matrix.name,
|
||||||
|
x: matrix.x,
|
||||||
|
y: matrix.y,
|
||||||
|
width: matrix.w,
|
||||||
|
height: matrix.h,
|
||||||
|
confidence: matrix.confidence,
|
||||||
|
isZombie: matrix.isZombie,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return trackedObjects;
|
||||||
|
}
|
||||||
|
function trackObject(trackerId,matrices){
|
||||||
|
if(!objectTrackers[trackerId]){
|
||||||
|
resetObjectTracker(trackerId)
|
||||||
|
}
|
||||||
|
const mappedMatrices = matrices.map((matrix) => {
|
||||||
|
return {
|
||||||
|
x: matrix.x,
|
||||||
|
y: matrix.y,
|
||||||
|
w: matrix.width,
|
||||||
|
h: matrix.height,
|
||||||
|
confidence: matrix.confidence,
|
||||||
|
name: matrix.tag,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const theTracker = objectTrackers[trackerId]
|
||||||
|
theTracker.tracker.updateTrackedItemsWithNewFrame(mappedMatrices, theTracker.frameCount);
|
||||||
|
++theTracker.frameCount
|
||||||
|
}
|
||||||
|
function trackObjectWithTimeout(trackerId,matrices){
|
||||||
|
clearTimeout(objectTrackerTimeouts[trackerId]);
|
||||||
|
objectTrackerTimeouts[trackerId] = setTimeout(() => {
|
||||||
|
objectTrackers[trackerId].tracker.reset()
|
||||||
|
delete(objectTrackers[trackerId])
|
||||||
|
delete(objectTrackerTimeouts[trackerId])
|
||||||
|
},1000 * 60);
|
||||||
|
trackObject(trackerId,matrices);
|
||||||
|
}
|
||||||
|
function objectHasMoved(matrices, options = {}) {
|
||||||
|
const { imgHeight = 1, imgWidth = 1, threshold = 0 } = options;
|
||||||
|
for (let i = 0; i < matrices.length; i++) {
|
||||||
|
const current = matrices[i];
|
||||||
|
if (i < matrices.length - 1) {
|
||||||
|
const next = matrices[i + 1];
|
||||||
|
let totalDistanceMoved = 0;
|
||||||
|
let numPointsCompared = 0;
|
||||||
|
if (next) {
|
||||||
|
// Compare each corner of the matrices
|
||||||
|
const currentCorners = [
|
||||||
|
{ x: current.x, y: current.y },
|
||||||
|
{ x: current.x + current.width, y: current.y },
|
||||||
|
{ x: current.x, y: current.y + current.height },
|
||||||
|
{ x: current.x + current.width, y: current.y + current.height }
|
||||||
|
];
|
||||||
|
const nextCorners = [
|
||||||
|
{ x: next.x, y: next.y },
|
||||||
|
{ x: next.x + next.width, y: next.y },
|
||||||
|
{ x: next.x, y: next.y + next.height },
|
||||||
|
{ x: next.x + next.width, y: next.y + next.height }
|
||||||
|
];
|
||||||
|
for (let j = 0; j < currentCorners.length; j++) {
|
||||||
|
const currentCorner = currentCorners[j];
|
||||||
|
const nextCorner = nextCorners[j];
|
||||||
|
const dx = nextCorner.x - currentCorner.x;
|
||||||
|
const dy = nextCorner.y - currentCorner.y;
|
||||||
|
const distanceMoved = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
|
||||||
|
const distanceMovedPercent =
|
||||||
|
(100 * distanceMoved) / Math.max(current.width, current.height);
|
||||||
|
totalDistanceMoved += distanceMovedPercent;
|
||||||
|
numPointsCompared++;
|
||||||
|
}
|
||||||
|
const averageDistanceMoved = totalDistanceMoved / numPointsCompared;
|
||||||
|
if (averageDistanceMoved < threshold) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function groupMatricesById(matrices) {
|
||||||
|
const matrixById = {};
|
||||||
|
const matrixTags = {};
|
||||||
|
|
||||||
|
matrices.forEach(matrix => {
|
||||||
|
const id = matrix.id;
|
||||||
|
const tag = matrix.tag;
|
||||||
|
if (!matrixById[id]) {
|
||||||
|
matrixById[id] = [];
|
||||||
|
}
|
||||||
|
matrixTags[tag] = id;
|
||||||
|
matrixById[id].push(matrix);
|
||||||
|
});
|
||||||
|
|
||||||
|
return matrixById
|
||||||
|
}
|
||||||
|
function getAllMatricesThatMoved(monitorConfig,matrices){
|
||||||
|
const monitorDetails = monitorConfig.details
|
||||||
|
const imgWidth = parseInt(monitorDetails.detector_scale_x_object) || 1280
|
||||||
|
const imgHeight = parseInt(monitorDetails.detector_scale_y_object) || 720
|
||||||
|
const objectMovePercent = parseInt(monitorDetails.detector_object_move_percent) || 5
|
||||||
|
const groupKey = monitorConfig.ke
|
||||||
|
const monitorId = monitorConfig.mid
|
||||||
|
const trackerId = `${groupKey}${monitorId}`
|
||||||
|
const theTracker = objectTrackers[trackerId]
|
||||||
|
const lastPositions = theTracker.lastPositions
|
||||||
|
const sortedById = groupMatricesById([...lastPositions,...matrices])
|
||||||
|
const movedMatrices = []
|
||||||
|
for (const objectId in sortedById) {
|
||||||
|
const sortedList = sortedById[objectId]
|
||||||
|
if(sortedList[1]){
|
||||||
|
const matrixHasMoved = objectHasMoved(sortedList,{
|
||||||
|
threshold: objectMovePercent,
|
||||||
|
imgWidth: imgWidth,
|
||||||
|
imgHeight: imgHeight,
|
||||||
|
});
|
||||||
|
if(matrixHasMoved){
|
||||||
|
movedMatrices.push(sortedList[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return movedMatrices
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
trackObjectWithTimeout,
|
||||||
|
resetObjectTracker,
|
||||||
|
trackObject,
|
||||||
|
getTracked,
|
||||||
|
setLastTracked,
|
||||||
|
getAllMatricesThatMoved,
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,12 @@ module.exports = (s,config,lang,app,io) => {
|
||||||
cutVideoLength,
|
cutVideoLength,
|
||||||
reEncodeVideoAndBinOriginalAddToQueue
|
reEncodeVideoAndBinOriginalAddToQueue
|
||||||
} = require('../video/utils.js')(s,config,lang)
|
} = require('../video/utils.js')(s,config,lang)
|
||||||
|
const {
|
||||||
|
getTracked,
|
||||||
|
setLastTracked,
|
||||||
|
trackObjectWithTimeout,
|
||||||
|
getAllMatricesThatMoved,
|
||||||
|
} = require('./tracking.js')(s,config,lang,app,io)
|
||||||
const {
|
const {
|
||||||
isEven,
|
isEven,
|
||||||
fetchTimeout,
|
fetchTimeout,
|
||||||
|
@ -97,7 +103,7 @@ module.exports = (s,config,lang,app,io) => {
|
||||||
}
|
}
|
||||||
return newString
|
return newString
|
||||||
}
|
}
|
||||||
const isAtleastOneMatrixInRegion = function(regions,matrices,callback){
|
const isAtleastOneMatrixInRegion = function(regions,matrices){
|
||||||
var regionPolys = []
|
var regionPolys = []
|
||||||
var matrixPoints = []
|
var matrixPoints = []
|
||||||
regions.forEach(function(region,n){
|
regions.forEach(function(region,n){
|
||||||
|
@ -108,46 +114,20 @@ module.exports = (s,config,lang,app,io) => {
|
||||||
regionPolys[n] = new P(new V(0,0), polyPoints)
|
regionPolys[n] = new P(new V(0,0), polyPoints)
|
||||||
})
|
})
|
||||||
var collisions = []
|
var collisions = []
|
||||||
var foundInRegion = false
|
|
||||||
matrices.forEach(function(matrix){
|
matrices.forEach(function(matrix){
|
||||||
var matrixPoly = new B(new V(matrix.x, matrix.y), matrix.width, matrix.height).toPolygon()
|
var matrixPoly = new B(new V(matrix.x, matrix.y), matrix.width, matrix.height).toPolygon()
|
||||||
|
var foundInRegion = false
|
||||||
regionPolys.forEach(function(region,n){
|
regionPolys.forEach(function(region,n){
|
||||||
var response = new SAT.Response()
|
if(!foundInRegion){
|
||||||
var collided = SAT.testPolygonPolygon(matrixPoly, region, response)
|
var response = new SAT.Response()
|
||||||
if(collided === true){
|
var collided = SAT.testPolygonPolygon(matrixPoly, region, response)
|
||||||
collisions.push({
|
if(collided === true){
|
||||||
matrix: matrix,
|
foundInRegion = true
|
||||||
region: regions[n]
|
collisions.push(matrix)
|
||||||
})
|
}
|
||||||
foundInRegion = true
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
if(callback)callback(foundInRegion,collisions)
|
|
||||||
return foundInRegion
|
|
||||||
}
|
|
||||||
const scanMatricesforCollisions = function(region,matrices){
|
|
||||||
var matrixPoints = []
|
|
||||||
var collisions = []
|
|
||||||
if (!region || !matrices){
|
|
||||||
if(callback)callback(collisions)
|
|
||||||
return collisions
|
|
||||||
}
|
|
||||||
var polyPoints = []
|
|
||||||
region.points.forEach(function(point){
|
|
||||||
polyPoints.push(new V(parseInt(point[0]),parseInt(point[1])))
|
|
||||||
})
|
|
||||||
var regionPoly = new P(new V(0,0), polyPoints)
|
|
||||||
matrices.forEach(function(matrix){
|
|
||||||
if (matrix){
|
|
||||||
var matrixPoly = new B(new V(matrix.x, matrix.y), matrix.width, matrix.height).toPolygon()
|
|
||||||
var response = new SAT.Response()
|
|
||||||
var collided = SAT.testPolygonPolygon(matrixPoly, regionPoly, response)
|
|
||||||
if(collided === true){
|
|
||||||
collisions.push(matrix)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return collisions
|
return collisions
|
||||||
}
|
}
|
||||||
const getLargestMatrix = (matrices) => {
|
const getLargestMatrix = (matrices) => {
|
||||||
|
@ -367,22 +347,6 @@ module.exports = (s,config,lang,app,io) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const checkForObjectsInRegions = (monitorConfig,eventDetails,filter,d,didCountingAlready) => {
|
|
||||||
const monitorDetails = monitorConfig.details
|
|
||||||
if(hasMatrices(eventDetails) && monitorDetails.detector_obj_region === '1'){
|
|
||||||
var regions = s.group[monitorConfig.ke].activeMonitors[monitorConfig.mid].parsedObjects.cords
|
|
||||||
var isMatrixInRegions = isAtleastOneMatrixInRegion(regions,eventDetails.matrices)
|
|
||||||
if(isMatrixInRegions){
|
|
||||||
s.debugLog('Matrix in region!')
|
|
||||||
if(filter.countObjects && monitorDetails.detector_obj_count === '1' && monitorDetails.detector_obj_count_in_region === '1' && !didCountingAlready){
|
|
||||||
countObjects(d)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
const runEventExecutions = async (eventTime,monitorConfig,eventDetails,forceSave,filter,d, triggerEvent) => {
|
const runEventExecutions = async (eventTime,monitorConfig,eventDetails,forceSave,filter,d, triggerEvent) => {
|
||||||
const monitorDetails = monitorConfig.details
|
const monitorDetails = monitorConfig.details
|
||||||
const detailString = JSON.stringify(eventDetails)
|
const detailString = JSON.stringify(eventDetails)
|
||||||
|
@ -674,6 +638,8 @@ module.exports = (s,config,lang,app,io) => {
|
||||||
}
|
}
|
||||||
const triggerEvent = async (d,forceSave) => {
|
const triggerEvent = async (d,forceSave) => {
|
||||||
var didCountingAlready = false
|
var didCountingAlready = false
|
||||||
|
const groupKey = d.ke
|
||||||
|
const monitorId = d.mid || d.id
|
||||||
const filter = {
|
const filter = {
|
||||||
halt : false,
|
halt : false,
|
||||||
addToMotionCounter : true,
|
addToMotionCounter : true,
|
||||||
|
@ -698,7 +664,6 @@ module.exports = (s,config,lang,app,io) => {
|
||||||
s.onEventTriggerBeforeFilterExtensions.forEach(function(extender){
|
s.onEventTriggerBeforeFilterExtensions.forEach(function(extender){
|
||||||
extender(d,filter)
|
extender(d,filter)
|
||||||
})
|
})
|
||||||
const eventDetails = d.details
|
|
||||||
const passedEventFilters = checkEventFilters(d,activeMonitor.details,filter)
|
const passedEventFilters = checkEventFilters(d,activeMonitor.details,filter)
|
||||||
if(!passedEventFilters)return;
|
if(!passedEventFilters)return;
|
||||||
const eventTime = new Date()
|
const eventTime = new Date()
|
||||||
|
@ -722,20 +687,37 @@ module.exports = (s,config,lang,app,io) => {
|
||||||
){
|
){
|
||||||
addToEventCounter(d)
|
addToEventCounter(d)
|
||||||
}
|
}
|
||||||
|
const eventDetails = d.details
|
||||||
if(
|
if(
|
||||||
(filter.countObjects || monitorDetails.detector_obj_count === '1') &&
|
(filter.countObjects || monitorDetails.detector_obj_count === '1') &&
|
||||||
monitorDetails.detector_obj_count_in_region !== '1'
|
monitorDetails.detector_obj_count_in_region !== '1'
|
||||||
){
|
){
|
||||||
didCountingAlready = true
|
didCountingAlready = true
|
||||||
countObjects(d)
|
countObjects(eventDetails.matrices)
|
||||||
}
|
}
|
||||||
if(filter.useLock){
|
if(filter.useLock){
|
||||||
const passedMotionLock = checkMotionLock(d,monitorDetails)
|
const passedMotionLock = checkMotionLock(d,monitorDetails)
|
||||||
if(!passedMotionLock)return
|
if(!passedMotionLock)return
|
||||||
}
|
}
|
||||||
const passedObjectInRegionCheck = checkForObjectsInRegions(monitorConfig,eventDetails,filter,d,didCountingAlready)
|
const thisHasMatrices = hasMatrices(eventDetails)
|
||||||
if(!passedObjectInRegionCheck)return
|
if(thisHasMatrices && monitorDetails.detector_obj_region === '1'){
|
||||||
|
var regions = s.group[monitorConfig.ke].activeMonitors[monitorConfig.mid].parsedObjects.cordsForObjectDetection
|
||||||
|
var matricesInRegions = isAtleastOneMatrixInRegion(regions,eventDetails.matrices)
|
||||||
|
eventDetails.matrices = matricesInRegions
|
||||||
|
if(matricesInRegions.length === 0)return;
|
||||||
|
if(filter.countObjects && monitorDetails.detector_obj_count === '1' && monitorDetails.detector_obj_count_in_region === '1' && !didCountingAlready){
|
||||||
|
countObjects(eventDetails.matrices)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(thisHasMatrices && monitorDetails.detector_object_ignore_not_move === '1'){
|
||||||
|
const trackerId = `${groupKey}${monitorId}`
|
||||||
|
trackObjectWithTimeout(trackerId,eventDetails.matrices)
|
||||||
|
const trackedObjects = getTracked(trackerId)
|
||||||
|
const objectsThatMoved = getAllMatricesThatMoved(monitorConfig,trackedObjects)
|
||||||
|
setLastTracked(trackerId, trackedObjects)
|
||||||
|
if(objectsThatMoved.length === 0)return;
|
||||||
|
eventDetails.matrices = objectsThatMoved
|
||||||
|
}
|
||||||
//
|
//
|
||||||
d.doObjectDetection = (
|
d.doObjectDetection = (
|
||||||
eventDetails.reason !== 'object' &&
|
eventDetails.reason !== 'object' &&
|
||||||
|
@ -762,10 +744,34 @@ module.exports = (s,config,lang,app,io) => {
|
||||||
doObjectDetection: d.doObjectDetection
|
doObjectDetection: d.doObjectDetection
|
||||||
},`DETECTOR_${monitorConfig.ke}${monitorConfig.mid}`);
|
},`DETECTOR_${monitorConfig.ke}${monitorConfig.mid}`);
|
||||||
}
|
}
|
||||||
|
function convertRegionPointsToNewDimensions(regions, options) {
|
||||||
|
const { fromWidth, fromHeight, toWidth, toHeight } = options;
|
||||||
|
|
||||||
|
// Compute the conversion factors for x and y coordinates
|
||||||
|
const xFactor = toWidth / fromWidth;
|
||||||
|
const yFactor = toHeight / fromHeight;
|
||||||
|
|
||||||
|
// Clone the regions array and update the points for each region
|
||||||
|
const newRegions = regions.map(region => {
|
||||||
|
const { points } = region;
|
||||||
|
|
||||||
|
// Clone the points array and update the coordinates
|
||||||
|
const newPoints = points.map(([x, y]) => {
|
||||||
|
const newX = Math.round(x * xFactor);
|
||||||
|
const newY = Math.round(y * yFactor);
|
||||||
|
return [newX.toString(), newY.toString()];
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clone the region object and update the points
|
||||||
|
return { ...region, points: newPoints };
|
||||||
|
});
|
||||||
|
|
||||||
|
return newRegions;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
countObjects: countObjects,
|
countObjects: countObjects,
|
||||||
isAtleastOneMatrixInRegion: isAtleastOneMatrixInRegion,
|
isAtleastOneMatrixInRegion,
|
||||||
scanMatricesforCollisions: scanMatricesforCollisions,
|
convertRegionPointsToNewDimensions,
|
||||||
getLargestMatrix: getLargestMatrix,
|
getLargestMatrix: getLargestMatrix,
|
||||||
addToEventCounter: addToEventCounter,
|
addToEventCounter: addToEventCounter,
|
||||||
clearEventCounter: clearEventCounter,
|
clearEventCounter: clearEventCounter,
|
||||||
|
@ -774,7 +780,6 @@ module.exports = (s,config,lang,app,io) => {
|
||||||
checkEventFilters: checkEventFilters,
|
checkEventFilters: checkEventFilters,
|
||||||
checkMotionLock: checkMotionLock,
|
checkMotionLock: checkMotionLock,
|
||||||
runMultiEventBasedRecord: runMultiEventBasedRecord,
|
runMultiEventBasedRecord: runMultiEventBasedRecord,
|
||||||
checkForObjectsInRegions: checkForObjectsInRegions,
|
|
||||||
runEventExecutions: runEventExecutions,
|
runEventExecutions: runEventExecutions,
|
||||||
createEventBasedRecording: createEventBasedRecording,
|
createEventBasedRecording: createEventBasedRecording,
|
||||||
closeEventBasedRecording: closeEventBasedRecording,
|
closeEventBasedRecording: closeEventBasedRecording,
|
||||||
|
|
|
@ -26,6 +26,7 @@ module.exports = (s,config,lang) => {
|
||||||
const {
|
const {
|
||||||
addEventDetailsToString,
|
addEventDetailsToString,
|
||||||
closeEventBasedRecording,
|
closeEventBasedRecording,
|
||||||
|
convertRegionPointsToNewDimensions,
|
||||||
triggerEvent,
|
triggerEvent,
|
||||||
} = require('../events/utils.js')(s,config,lang)
|
} = require('../events/utils.js')(s,config,lang)
|
||||||
const {
|
const {
|
||||||
|
@ -49,7 +50,7 @@ module.exports = (s,config,lang) => {
|
||||||
const getUpdateableFields = require('./updatedFields.js')
|
const getUpdateableFields = require('./updatedFields.js')
|
||||||
const processKill = (proc) => {
|
const processKill = (proc) => {
|
||||||
const response = {ok: true}
|
const response = {ok: true}
|
||||||
const processPID = parseInt(`${proc.pid}`)
|
const processPID = proc && proc.pid ? parseInt(`${proc.pid}`) : null
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
let alreadyResolved = false
|
let alreadyResolved = false
|
||||||
function doResolve(response){
|
function doResolve(response){
|
||||||
|
@ -1703,7 +1704,18 @@ module.exports = (s,config,lang) => {
|
||||||
activeMonitor.details = e.details
|
activeMonitor.details = e.details
|
||||||
switch(v){
|
switch(v){
|
||||||
case'cords':
|
case'cords':
|
||||||
activeMonitor.parsedObjects[v] = Object.values(s.parseJSON(e.details[v]))
|
const fromWidth = parseInt(e.details.detector_scale_x) || 640
|
||||||
|
const fromHeight = parseInt(e.details.detector_scale_y) || 480
|
||||||
|
const toWidth = parseInt(e.details.detector_scale_x_object) || 1280
|
||||||
|
const toHeight = parseInt(e.details.detector_scale_y_object) || 720
|
||||||
|
const theCords = Object.values(s.parseJSON(e.details[v])) || [];
|
||||||
|
activeMonitor.parsedObjects.cordsForObjectDetection = convertRegionPointsToNewDimensions(theCords,{
|
||||||
|
fromWidth,
|
||||||
|
fromHeight,
|
||||||
|
toWidth,
|
||||||
|
toHeight,
|
||||||
|
});
|
||||||
|
activeMonitor.parsedObjects.cords = theCords
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
activeMonitor.parsedObjects[v] = s.parseJSON(e.details[v])
|
activeMonitor.parsedObjects[v] = s.parseJSON(e.details[v])
|
||||||
|
|
|
@ -331,16 +331,16 @@ module.exports = function(s,config,lang){
|
||||||
"value": "us-west-1"
|
"value": "us-west-1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "US West 2)",
|
"name": "US West 2",
|
||||||
"value": "us-west-2"
|
"value": "us-west-2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "US East 1",
|
"name": "US East 1",
|
||||||
"value": "us-east-2"
|
"value": "us-east-1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "US East 2",
|
"name": "US East 2",
|
||||||
"value": "us-east-1"
|
"value": "us-east-2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Asia Pacific 1",
|
"name": "Asia Pacific 1",
|
||||||
|
|
|
@ -186,6 +186,10 @@ module.exports = function(s,config,lang,app){
|
||||||
res.write("\r\n");
|
res.write("\r\n");
|
||||||
res.write(content,'binary');
|
res.write(content,'binary');
|
||||||
res.write("\r\n");
|
res.write("\r\n");
|
||||||
|
if(!Emitter){
|
||||||
|
res.end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
var ip = s.getClientIp(req)
|
var ip = s.getClientIp(req)
|
||||||
s.camera('watch_on',{
|
s.camera('watch_on',{
|
||||||
id : req.params.id,
|
id : req.params.id,
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.226.0",
|
"@aws-sdk/client-s3": "^3.226.0",
|
||||||
"async": "^3.2.2",
|
"async": "^3.2.2",
|
||||||
"backblaze-b2": "^0.9.12",
|
"backblaze-b2": "^1.7.0",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"bson": "^4.6.1",
|
"bson": "^4.6.1",
|
||||||
"connection-tester": "^0.2.0",
|
"connection-tester": "^0.2.0",
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"node-abort-controller": "^3.0.1",
|
"node-abort-controller": "^3.0.1",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.7",
|
||||||
|
"shinobi-node-moving-things-tracker": "^0.9.1",
|
||||||
"node-onvif-events": "^2.0.5",
|
"node-onvif-events": "^2.0.5",
|
||||||
"node-ssh": "^12.0.4",
|
"node-ssh": "^12.0.4",
|
||||||
"node-telegram-bot-api": "^0.58.0",
|
"node-telegram-bot-api": "^0.58.0",
|
||||||
|
@ -1384,6 +1385,17 @@
|
||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/runtime": {
|
||||||
|
"version": "7.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
|
||||||
|
"integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
|
||||||
|
"dependencies": {
|
||||||
|
"regenerator-runtime": "^0.13.11"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@discordjs/collection": {
|
"node_modules/@discordjs/collection": {
|
||||||
"version": "0.1.6",
|
"version": "0.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz",
|
||||||
|
@ -1694,15 +1706,34 @@
|
||||||
"follow-redirects": "^1.14.4"
|
"follow-redirects": "^1.14.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/backblaze-b2": {
|
"node_modules/axios-retry": {
|
||||||
"version": "0.9.12",
|
"version": "3.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/backblaze-b2/-/backblaze-b2-0.9.12.tgz",
|
"resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.4.0.tgz",
|
||||||
"integrity": "sha1-b0IHJs7G0L787ohqS7bfUOnAGco=",
|
"integrity": "sha512-VdgaP+gHH4iQYCCNUWF2pcqeciVOdGrBBAYUfTY+wPcO5Ltvp/37MLFNCmJKo7Gj3SHvCSdL8ouI1qLYJN3liA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-sha1": "^1.0.1",
|
"@babel/runtime": "^7.15.4",
|
||||||
"q": "^1.4.1",
|
"is-retry-allowed": "^2.2.0"
|
||||||
"request": "^2.67.0",
|
}
|
||||||
"request-progress": "^3.0.0"
|
},
|
||||||
|
"node_modules/backblaze-b2": {
|
||||||
|
"version": "1.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/backblaze-b2/-/backblaze-b2-1.7.0.tgz",
|
||||||
|
"integrity": "sha512-8cVsKkXspuM1UeLI8WWSWw2JHfB7/IvqTtzvwhHqqhNyqcYl8iZ2lFpeuXGKcFA1TiSRlgALXWFJ9eKG6+3ZPg==",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.21.1",
|
||||||
|
"axios-retry": "^3.1.9",
|
||||||
|
"lodash": "^4.17.21"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/backblaze-b2/node_modules/axios": {
|
||||||
|
"version": "0.21.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||||
|
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/backoff": {
|
"node_modules/backoff": {
|
||||||
|
@ -4365,6 +4396,17 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-retry-allowed": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-shared-array-buffer": {
|
"node_modules/is-shared-array-buffer": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
|
||||||
|
@ -4735,6 +4777,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||||
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
|
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash.isequal": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
|
||||||
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
@ -5035,6 +5082,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
},
|
},
|
||||||
|
"node_modules/munkres-js": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/munkres-js/-/munkres-js-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-0oF4tBDvzx20CYzQ44tTJMfwTBJWXe7cE73Sa/u7Mz7X8jRtyOXOGE9kJBhCfX7Akku3Iy/WHa0sRgqLRq2xaQ=="
|
||||||
|
},
|
||||||
"node_modules/mv": {
|
"node_modules/mv": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
|
||||||
|
@ -5174,6 +5226,20 @@
|
||||||
"node": ">= 6.13.0"
|
"node": ">= 6.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/node-moving-things-tracker": {
|
||||||
|
"version": "0.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-moving-things-tracker/-/node-moving-things-tracker-0.9.1.tgz",
|
||||||
|
"integrity": "sha512-JVa+DbQRgOsOcfIIxhw3kTUfO407RdXnVqNgPvAlhUHu7PWziUah+MuTcaN4rRktBicj/l2scI64a2crBgrzKw==",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash.isequal": "^4.5.0",
|
||||||
|
"minimist": "^1.2.0",
|
||||||
|
"munkres-js": "^1.2.2",
|
||||||
|
"uuid": "^3.2.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"shinobi-node-moving-things-tracker": "main.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-onvif-events": {
|
"node_modules/node-onvif-events": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/node-onvif-events/-/node-onvif-events-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/node-onvif-events/-/node-onvif-events-2.0.5.tgz",
|
||||||
|
@ -5182,11 +5248,6 @@
|
||||||
"onvif": "git+https://github.com/agsh/onvif.git"
|
"onvif": "git+https://github.com/agsh/onvif.git"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-sha1": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-sha1/-/node-sha1-1.0.1.tgz",
|
|
||||||
"integrity": "sha1-Mu2EfYUTFXuW3sa3noxHvK63jhw="
|
|
||||||
},
|
|
||||||
"node_modules/node-ssh": {
|
"node_modules/node-ssh": {
|
||||||
"version": "12.0.4",
|
"version": "12.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/node-ssh/-/node-ssh-12.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/node-ssh/-/node-ssh-12.0.4.tgz",
|
||||||
|
@ -5839,15 +5900,6 @@
|
||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/q": {
|
|
||||||
"version": "1.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
|
|
||||||
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.6.0",
|
|
||||||
"teleport": ">=0.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/qs": {
|
"node_modules/qs": {
|
||||||
"version": "6.7.0",
|
"version": "6.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||||
|
@ -5907,6 +5959,11 @@
|
||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/regenerator-runtime": {
|
||||||
|
"version": "0.13.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
||||||
|
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
||||||
|
},
|
||||||
"node_modules/regex-not": {
|
"node_modules/regex-not": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
|
||||||
|
@ -5976,14 +6033,6 @@
|
||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/request-progress": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz",
|
|
||||||
"integrity": "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=",
|
|
||||||
"dependencies": {
|
|
||||||
"throttleit": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/request-promise": {
|
"node_modules/request-promise": {
|
||||||
"version": "4.2.6",
|
"version": "4.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz",
|
||||||
|
@ -6946,11 +6995,6 @@
|
||||||
"node": ">=8.0.0"
|
"node": ">=8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/throttleit": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw="
|
|
||||||
},
|
|
||||||
"node_modules/tildify": {
|
"node_modules/tildify": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz",
|
||||||
|
@ -8846,6 +8890,14 @@
|
||||||
"tslib": "^2.3.1"
|
"tslib": "^2.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@babel/runtime": {
|
||||||
|
"version": "7.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
|
||||||
|
"integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
|
||||||
|
"requires": {
|
||||||
|
"regenerator-runtime": "^0.13.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@discordjs/collection": {
|
"@discordjs/collection": {
|
||||||
"version": "0.1.6",
|
"version": "0.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz",
|
||||||
|
@ -9078,15 +9130,33 @@
|
||||||
"follow-redirects": "^1.14.4"
|
"follow-redirects": "^1.14.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"backblaze-b2": {
|
"axios-retry": {
|
||||||
"version": "0.9.12",
|
"version": "3.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/backblaze-b2/-/backblaze-b2-0.9.12.tgz",
|
"resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.4.0.tgz",
|
||||||
"integrity": "sha1-b0IHJs7G0L787ohqS7bfUOnAGco=",
|
"integrity": "sha512-VdgaP+gHH4iQYCCNUWF2pcqeciVOdGrBBAYUfTY+wPcO5Ltvp/37MLFNCmJKo7Gj3SHvCSdL8ouI1qLYJN3liA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"node-sha1": "^1.0.1",
|
"@babel/runtime": "^7.15.4",
|
||||||
"q": "^1.4.1",
|
"is-retry-allowed": "^2.2.0"
|
||||||
"request": "^2.67.0",
|
}
|
||||||
"request-progress": "^3.0.0"
|
},
|
||||||
|
"backblaze-b2": {
|
||||||
|
"version": "1.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/backblaze-b2/-/backblaze-b2-1.7.0.tgz",
|
||||||
|
"integrity": "sha512-8cVsKkXspuM1UeLI8WWSWw2JHfB7/IvqTtzvwhHqqhNyqcYl8iZ2lFpeuXGKcFA1TiSRlgALXWFJ9eKG6+3ZPg==",
|
||||||
|
"requires": {
|
||||||
|
"axios": "^0.21.1",
|
||||||
|
"axios-retry": "^3.1.9",
|
||||||
|
"lodash": "^4.17.21"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": {
|
||||||
|
"version": "0.21.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||||
|
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||||
|
"requires": {
|
||||||
|
"follow-redirects": "^1.14.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"backoff": {
|
"backoff": {
|
||||||
|
@ -11097,6 +11167,11 @@
|
||||||
"is-unc-path": "^1.0.0"
|
"is-unc-path": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-retry-allowed": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg=="
|
||||||
|
},
|
||||||
"is-shared-array-buffer": {
|
"is-shared-array-buffer": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
|
||||||
|
@ -11373,6 +11448,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||||
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
|
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
|
||||||
},
|
},
|
||||||
|
"lodash.isequal": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
|
||||||
|
},
|
||||||
"lru-cache": {
|
"lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
@ -11588,6 +11668,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
},
|
},
|
||||||
|
"munkres-js": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/munkres-js/-/munkres-js-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-0oF4tBDvzx20CYzQ44tTJMfwTBJWXe7cE73Sa/u7Mz7X8jRtyOXOGE9kJBhCfX7Akku3Iy/WHa0sRgqLRq2xaQ=="
|
||||||
|
},
|
||||||
"mv": {
|
"mv": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
|
||||||
|
@ -11697,6 +11782,17 @@
|
||||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
||||||
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA=="
|
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA=="
|
||||||
},
|
},
|
||||||
|
"shinobi-node-moving-things-tracker": {
|
||||||
|
"version": "0.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-moving-things-tracker/-/node-moving-things-tracker-0.9.1.tgz",
|
||||||
|
"integrity": "sha512-JVa+DbQRgOsOcfIIxhw3kTUfO407RdXnVqNgPvAlhUHu7PWziUah+MuTcaN4rRktBicj/l2scI64a2crBgrzKw==",
|
||||||
|
"requires": {
|
||||||
|
"lodash.isequal": "^4.5.0",
|
||||||
|
"minimist": "^1.2.0",
|
||||||
|
"munkres-js": "^1.2.2",
|
||||||
|
"uuid": "^3.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node-onvif-events": {
|
"node-onvif-events": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/node-onvif-events/-/node-onvif-events-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/node-onvif-events/-/node-onvif-events-2.0.5.tgz",
|
||||||
|
@ -11705,11 +11801,6 @@
|
||||||
"onvif": "git+https://github.com/agsh/onvif.git"
|
"onvif": "git+https://github.com/agsh/onvif.git"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node-sha1": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-sha1/-/node-sha1-1.0.1.tgz",
|
|
||||||
"integrity": "sha1-Mu2EfYUTFXuW3sa3noxHvK63jhw="
|
|
||||||
},
|
|
||||||
"node-ssh": {
|
"node-ssh": {
|
||||||
"version": "12.0.4",
|
"version": "12.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/node-ssh/-/node-ssh-12.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/node-ssh/-/node-ssh-12.0.4.tgz",
|
||||||
|
@ -12205,11 +12296,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/pushover-notifications/-/pushover-notifications-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/pushover-notifications/-/pushover-notifications-1.2.2.tgz",
|
||||||
"integrity": "sha512-+3Xcj+kiMiouZK1Ws8yGBTyl8WMPZZdELgl/iVxYqNwDdlaObBHMhEGPRC6Zb9t0BE27ikOoOqSIO1cKZOtsDA=="
|
"integrity": "sha512-+3Xcj+kiMiouZK1Ws8yGBTyl8WMPZZdELgl/iVxYqNwDdlaObBHMhEGPRC6Zb9t0BE27ikOoOqSIO1cKZOtsDA=="
|
||||||
},
|
},
|
||||||
"q": {
|
|
||||||
"version": "1.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
|
|
||||||
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
|
|
||||||
},
|
|
||||||
"qs": {
|
"qs": {
|
||||||
"version": "6.7.0",
|
"version": "6.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||||
|
@ -12254,6 +12340,11 @@
|
||||||
"resolve": "^1.1.6"
|
"resolve": "^1.1.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"regenerator-runtime": {
|
||||||
|
"version": "0.13.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
||||||
|
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
||||||
|
},
|
||||||
"regex-not": {
|
"regex-not": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
|
||||||
|
@ -12327,14 +12418,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"request-progress": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz",
|
|
||||||
"integrity": "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=",
|
|
||||||
"requires": {
|
|
||||||
"throttleit": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"request-promise": {
|
"request-promise": {
|
||||||
"version": "4.2.6",
|
"version": "4.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz",
|
||||||
|
@ -13071,11 +13154,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.1.tgz",
|
||||||
"integrity": "sha512-6usSlV9KyHsspvwu2duKH+FMUhqJnAh6J5J/4MITl8s94iSUQTLkJggdiewKv4RyARQccnigV48Z+khiuVZDJw=="
|
"integrity": "sha512-6usSlV9KyHsspvwu2duKH+FMUhqJnAh6J5J/4MITl8s94iSUQTLkJggdiewKv4RyARQccnigV48Z+khiuVZDJw=="
|
||||||
},
|
},
|
||||||
"throttleit": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw="
|
|
||||||
},
|
|
||||||
"tildify": {
|
"tildify": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz",
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.226.0",
|
"@aws-sdk/client-s3": "^3.226.0",
|
||||||
"async": "^3.2.2",
|
"async": "^3.2.2",
|
||||||
"backblaze-b2": "^0.9.12",
|
"backblaze-b2": "^1.7.0",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"bson": "^4.6.1",
|
"bson": "^4.6.1",
|
||||||
"connection-tester": "^0.2.0",
|
"connection-tester": "^0.2.0",
|
||||||
|
@ -41,6 +41,7 @@
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"node-abort-controller": "^3.0.1",
|
"node-abort-controller": "^3.0.1",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.7",
|
||||||
|
"shinobi-node-moving-things-tracker": "^0.9.1",
|
||||||
"node-onvif-events": "^2.0.5",
|
"node-onvif-events": "^2.0.5",
|
||||||
"node-ssh": "^12.0.4",
|
"node-ssh": "^12.0.4",
|
||||||
"node-telegram-bot-api": "^0.58.0",
|
"node-telegram-bot-api": "^0.58.0",
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
const fsOld = require('fs')
|
||||||
|
const fs = fsOld.promises
|
||||||
|
const spawn = require('child_process').spawn
|
||||||
|
const configLocation = process.argv[2] ? process.argv[2] : `${__dirname}/../conf.json`
|
||||||
|
const config = require(configLocation)
|
||||||
|
const customAutoLoadPath = `${__dirname}/../libs/customAutoLoad/`
|
||||||
|
|
||||||
|
async function getAllCustomAutoLoadModuleFolders(){
|
||||||
|
return (await fs.readdir(customAutoLoadPath)).filter((filename) => {
|
||||||
|
return fsOld.lstatSync(`${customAutoLoadPath}${filename}`).isDirectory()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function installModule(filename){
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
console.log(`Installing Module : ${filename}`)
|
||||||
|
const folderPath = `${customAutoLoadPath}${filename}`
|
||||||
|
const tempSh = `${folderPath}/tempSh.sh`
|
||||||
|
fsOld.writeFileSync(tempSh,`cd "${folderPath}" && npm install`)
|
||||||
|
const installProcess = spawn('sh',[tempSh])
|
||||||
|
installProcess.stdout.on('data',function(data){
|
||||||
|
const text = data.toString()
|
||||||
|
console.log(text)
|
||||||
|
})
|
||||||
|
installProcess.stderr.on('data',function(data){
|
||||||
|
const text = data.toString()
|
||||||
|
console.error(text)
|
||||||
|
})
|
||||||
|
installProcess.on('close',function(){
|
||||||
|
resolve()
|
||||||
|
fs.rm(tempSh)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function run(){
|
||||||
|
const folderList = await getAllCustomAutoLoadModuleFolders()
|
||||||
|
for (let i = 0; i < folderList.length; i++) {
|
||||||
|
const folderName = folderList[i]
|
||||||
|
await installModule(folderName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run().then(() => {
|
||||||
|
console.log('Done!')
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('RUN ERROR',err)
|
||||||
|
})
|
|
@ -7,7 +7,7 @@ $(document).ready(function(){
|
||||||
var addStorageMaxAmountsField = theForm.find('[detail="addStorage"]')
|
var addStorageMaxAmountsField = theForm.find('[detail="addStorage"]')
|
||||||
function drawAddStorageFields(){
|
function drawAddStorageFields(){
|
||||||
try{
|
try{
|
||||||
var addStorageData = JSON.parse($user.details.addStorage || '{}')
|
var addStorageData = safeJsonParse($user.details.addStorage || '{}')
|
||||||
var html = ''
|
var html = ''
|
||||||
$.each(addStorage,function(n,storage){
|
$.each(addStorage,function(n,storage){
|
||||||
var theStorage = addStorageData[storage.path]
|
var theStorage = addStorageData[storage.path]
|
||||||
|
@ -62,7 +62,6 @@ $(document).ready(function(){
|
||||||
})
|
})
|
||||||
return json
|
return json
|
||||||
}
|
}
|
||||||
$('body')
|
|
||||||
theForm.find('[detail]').change(onDetailFieldChange)
|
theForm.find('[detail]').change(onDetailFieldChange)
|
||||||
theForm.find('[detail]').change(function(){
|
theForm.find('[detail]').change(function(){
|
||||||
onDetailFieldChange(this)
|
onDetailFieldChange(this)
|
||||||
|
|
|
@ -6,6 +6,8 @@ var liveGrid = $('#monitors_live')
|
||||||
var liveGridData = null
|
var liveGridData = null
|
||||||
var liveGridOpenCountElements = $('.liveGridOpenCount')
|
var liveGridOpenCountElements = $('.liveGridOpenCount')
|
||||||
var liveGridOpenCount = 0
|
var liveGridOpenCount = 0
|
||||||
|
var liveGridPauseScrollTimeout = null;
|
||||||
|
var liveGridPlayingNow = {};
|
||||||
//
|
//
|
||||||
var onLiveStreamInitiateExtensions = []
|
var onLiveStreamInitiateExtensions = []
|
||||||
function onLiveStreamInitiate(callback){
|
function onLiveStreamInitiate(callback){
|
||||||
|
@ -337,222 +339,225 @@ function drawLiveGridBlock(monitorConfig,subStreamChannel){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function initiateLiveGridPlayer(monitor,subStreamChannel){
|
function initiateLiveGridPlayer(monitor,subStreamChannel){
|
||||||
var livePlayerElement = loadedLiveGrids[monitor.mid]
|
var monitorId = monitor.mid
|
||||||
var details = monitor.details
|
var details = monitor.details
|
||||||
var groupKey = monitor.ke
|
var groupKey = monitor.ke
|
||||||
var monitorId = monitor.mid
|
var monitorId = monitor.mid
|
||||||
|
var livePlayerBlocks = liveGridElements[monitorId]
|
||||||
|
var monitorItem = livePlayerBlocks.monitorItem
|
||||||
var loadedMonitor = loadedMonitors[monitorId]
|
var loadedMonitor = loadedMonitors[monitorId]
|
||||||
var loadedPlayer = loadedLiveGrids[monitor.mid]
|
var loadedPlayer = loadedLiveGrids[monitorId]
|
||||||
var websocketPath = checkCorrectPathEnding(location.pathname) + 'socket.io'
|
var websocketPath = checkCorrectPathEnding(location.pathname) + 'socket.io'
|
||||||
var containerElement = $(`#monitor_live_${monitor.mid}`)
|
var containerElement = $(`#monitor_live_${monitor.mid}`)
|
||||||
var streamType = subStreamChannel ? details.substream ? details.substream.output.stream_type : 'hls' : details.stream_type
|
var streamType = subStreamChannel ? details.substream ? details.substream.output.stream_type : 'hls' : details.stream_type
|
||||||
if(location.search === '?p2p=1'){
|
var isInView = isScrolledIntoView(monitorItem[0])
|
||||||
websocketPath = '/socket.io'
|
if(!isInView){
|
||||||
// websocketQuery.machineId = machineId
|
return;
|
||||||
}
|
}
|
||||||
|
liveGridPlayingNow[monitorId] = true
|
||||||
switch(streamType){
|
switch(streamType){
|
||||||
case'jpeg':
|
case'jpeg':
|
||||||
startJpegStream(monitorId)
|
startJpegStream(monitorId)
|
||||||
break;
|
break;
|
||||||
case'b64':
|
case'b64':
|
||||||
if(loadedPlayer.Base64 && loadedPlayer.Base64.connected){
|
if(loadedPlayer.Base64 && loadedPlayer.Base64.connected){
|
||||||
loadedPlayer.Base64.disconnect()
|
loadedPlayer.Base64.disconnect()
|
||||||
}
|
}
|
||||||
loadedPlayer.Base64 = io(location.origin,{ path: websocketPath, query: websocketQuery, transports: ['websocket'], forceNew: false})
|
loadedPlayer.Base64 = io(location.origin,{ path: websocketPath, query: websocketQuery, transports: ['websocket'], forceNew: false})
|
||||||
var ws = loadedPlayer.Base64
|
var ws = loadedPlayer.Base64
|
||||||
var buffer
|
var buffer
|
||||||
ws.on('diconnect',function(){
|
ws.on('diconnect',function(){
|
||||||
console.log('Base64 Stream Disconnected')
|
console.log('Base64 Stream Disconnected')
|
||||||
})
|
|
||||||
ws.on('connect',function(){
|
|
||||||
ws.emit('Base64',{
|
|
||||||
auth: $user.auth_token,
|
|
||||||
uid: $user.uid,
|
|
||||||
ke: monitor.ke,
|
|
||||||
id: monitor.mid,
|
|
||||||
channel: subStreamChannel
|
|
||||||
})
|
})
|
||||||
if(!loadedPlayer.ctx || loadedPlayer.ctx.length === 0){
|
ws.on('connect',function(){
|
||||||
loadedPlayer.ctx = containerElement.find('canvas');
|
ws.emit('Base64',{
|
||||||
}
|
auth: $user.auth_token,
|
||||||
var ctx = loadedPlayer.ctx[0]
|
uid: $user.uid,
|
||||||
var ctx2d = ctx.getContext("2d")
|
ke: monitor.ke,
|
||||||
loadedPlayer.image = new Image()
|
id: monitor.mid,
|
||||||
var image = loadedPlayer.image
|
channel: subStreamChannel
|
||||||
image.onload = function() {
|
})
|
||||||
loadedPlayer.imageLoading = false
|
if(!loadedPlayer.ctx || loadedPlayer.ctx.length === 0){
|
||||||
var x = 0
|
loadedPlayer.ctx = containerElement.find('canvas');
|
||||||
var y = 0
|
|
||||||
ctx.getContext("2d").drawImage(image,x,y,ctx.width,ctx.height)
|
|
||||||
URL.revokeObjectURL(loadedPlayer.imageUrl)
|
|
||||||
}
|
|
||||||
ws.on('data',function(imageData){
|
|
||||||
try{
|
|
||||||
if(loadedPlayer.imageLoading === true)return console.log('drop');
|
|
||||||
loadedPlayer.imageLoading = true
|
|
||||||
var arrayBufferView = new Uint8Array(imageData);
|
|
||||||
var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } );
|
|
||||||
loadedPlayer.imageUrl = URL.createObjectURL( blob );
|
|
||||||
loadedPlayer.image.src = loadedPlayer.imageUrl
|
|
||||||
loadedPlayer.last_frame = 'data:image/jpeg;base64,'+base64ArrayBuffer(imageData)
|
|
||||||
}catch(er){
|
|
||||||
debugLog('base64 frame')
|
|
||||||
}
|
}
|
||||||
// $.ccio.init('signal',d);
|
var ctx = loadedPlayer.ctx[0]
|
||||||
|
var ctx2d = ctx.getContext("2d")
|
||||||
|
loadedPlayer.image = new Image()
|
||||||
|
var image = loadedPlayer.image
|
||||||
|
image.onload = function() {
|
||||||
|
loadedPlayer.imageLoading = false
|
||||||
|
var x = 0
|
||||||
|
var y = 0
|
||||||
|
ctx.getContext("2d").drawImage(image,x,y,ctx.width,ctx.height)
|
||||||
|
URL.revokeObjectURL(loadedPlayer.imageUrl)
|
||||||
|
}
|
||||||
|
ws.on('data',function(imageData){
|
||||||
|
try{
|
||||||
|
if(loadedPlayer.imageLoading === true)return console.log('drop');
|
||||||
|
loadedPlayer.imageLoading = true
|
||||||
|
var arrayBufferView = new Uint8Array(imageData);
|
||||||
|
var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } );
|
||||||
|
loadedPlayer.imageUrl = URL.createObjectURL( blob );
|
||||||
|
loadedPlayer.image.src = loadedPlayer.imageUrl
|
||||||
|
loadedPlayer.last_frame = 'data:image/jpeg;base64,'+base64ArrayBuffer(imageData)
|
||||||
|
}catch(er){
|
||||||
|
debugLog('base64 frame')
|
||||||
|
}
|
||||||
|
// $.ccio.init('signal',d);
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
break;
|
||||||
break;
|
case'mp4':
|
||||||
case'mp4':
|
setTimeout(function(){
|
||||||
setTimeout(function(){
|
var stream = containerElement.find('.stream-element');
|
||||||
var stream = containerElement.find('.stream-element');
|
var onPoseidonError = function(){
|
||||||
var onPoseidonError = function(){
|
// setTimeout(function(){
|
||||||
// setTimeout(function(){
|
// mainSocket.f({f:'monitor',ff:'watch_on',id:monitorId})
|
||||||
// mainSocket.f({f:'monitor',ff:'watch_on',id:monitorId})
|
// },2000)
|
||||||
// },2000)
|
}
|
||||||
}
|
if(!loadedPlayer.PoseidonErrorCount)loadedPlayer.PoseidonErrorCount = 0
|
||||||
if(!loadedPlayer.PoseidonErrorCount)loadedPlayer.PoseidonErrorCount = 0
|
if(loadedPlayer.PoseidonErrorCount >= 5)return
|
||||||
if(loadedPlayer.PoseidonErrorCount >= 5)return
|
if(subStreamChannel ? details.substream.output.stream_flv_type === 'ws' : monitor.details.stream_flv_type === 'ws'){
|
||||||
if(subStreamChannel ? details.substream.output.stream_flv_type === 'ws' : monitor.details.stream_flv_type === 'ws'){
|
if(loadedPlayer.Poseidon){
|
||||||
if(loadedPlayer.Poseidon){
|
loadedPlayer.Poseidon.stop()
|
||||||
loadedPlayer.Poseidon.stop()
|
revokeVideoPlayerUrl(monitorId)
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
loadedPlayer.Poseidon = new Poseidon({
|
||||||
|
video: stream[0],
|
||||||
|
auth_token: $user.auth_token,
|
||||||
|
ke: monitor.ke,
|
||||||
|
uid: $user.uid,
|
||||||
|
id: monitor.mid,
|
||||||
|
url: location.origin,
|
||||||
|
path: websocketPath,
|
||||||
|
query: websocketQuery,
|
||||||
|
onError : onPoseidonError,
|
||||||
|
channel : subStreamChannel
|
||||||
|
})
|
||||||
|
loadedPlayer.Poseidon.start();
|
||||||
|
}catch(err){
|
||||||
|
// onPoseidonError()
|
||||||
|
console.log('onTryPoseidonError',err)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
stream.attr('src',getApiPrefix(`mp4`)+'/'+monitor.mid + (subStreamChannel ? `/${subStreamChannel}` : '')+'/s.mp4?time=' + (new Date()).getTime())
|
||||||
|
stream[0].onerror = function(err){
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},1000)
|
||||||
|
break;
|
||||||
|
case'flv':
|
||||||
|
if (flvjs.isSupported()) {
|
||||||
|
if(loadedPlayer.flv){
|
||||||
|
loadedPlayer.flv.destroy()
|
||||||
revokeVideoPlayerUrl(monitorId)
|
revokeVideoPlayerUrl(monitorId)
|
||||||
}
|
}
|
||||||
try{
|
var options = {};
|
||||||
loadedPlayer.Poseidon = new Poseidon({
|
if(monitor.details.stream_flv_type==='ws'){
|
||||||
video: stream[0],
|
if(monitor.details.stream_flv_maxLatency&&monitor.details.stream_flv_maxLatency!==''){
|
||||||
|
monitor.details.stream_flv_maxLatency = parseInt(monitor.details.stream_flv_maxLatency)
|
||||||
|
}else{
|
||||||
|
monitor.details.stream_flv_maxLatency = 20000;
|
||||||
|
}
|
||||||
|
options = {
|
||||||
|
type: 'flv',
|
||||||
|
isLive: true,
|
||||||
auth_token: $user.auth_token,
|
auth_token: $user.auth_token,
|
||||||
ke: monitor.ke,
|
ke: monitor.ke,
|
||||||
uid: $user.uid,
|
uid: $user.uid,
|
||||||
id: monitor.mid,
|
id: monitor.mid,
|
||||||
|
maxLatency: monitor.details.stream_flv_maxLatency,
|
||||||
|
hasAudio:false,
|
||||||
url: location.origin,
|
url: location.origin,
|
||||||
path: websocketPath,
|
path: websocketPath,
|
||||||
query: websocketQuery,
|
channel : subStreamChannel,
|
||||||
onError : onPoseidonError,
|
query: websocketQuery
|
||||||
channel : subStreamChannel
|
}
|
||||||
})
|
|
||||||
loadedPlayer.Poseidon.start();
|
|
||||||
}catch(err){
|
|
||||||
// onPoseidonError()
|
|
||||||
console.log('onTryPoseidonError',err)
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
stream.attr('src',getApiPrefix(`mp4`)+'/'+monitor.mid + (subStreamChannel ? `/${subStreamChannel}` : '')+'/s.mp4?time=' + (new Date()).getTime())
|
|
||||||
stream[0].onerror = function(err){
|
|
||||||
console.error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},1000)
|
|
||||||
break;
|
|
||||||
case'flv':
|
|
||||||
if (flvjs.isSupported()) {
|
|
||||||
if(loadedPlayer.flv){
|
|
||||||
loadedPlayer.flv.destroy()
|
|
||||||
revokeVideoPlayerUrl(monitorId)
|
|
||||||
}
|
|
||||||
var options = {};
|
|
||||||
if(monitor.details.stream_flv_type==='ws'){
|
|
||||||
if(monitor.details.stream_flv_maxLatency&&monitor.details.stream_flv_maxLatency!==''){
|
|
||||||
monitor.details.stream_flv_maxLatency = parseInt(monitor.details.stream_flv_maxLatency)
|
|
||||||
}else{
|
}else{
|
||||||
monitor.details.stream_flv_maxLatency = 20000;
|
options = {
|
||||||
}
|
type: 'flv',
|
||||||
options = {
|
isLive: true,
|
||||||
type: 'flv',
|
url: getApiPrefix(`flv`)+'/'+monitor.mid + (subStreamChannel ? `/${subStreamChannel}` : '')+'/s.flv'
|
||||||
isLive: true,
|
|
||||||
auth_token: $user.auth_token,
|
|
||||||
ke: monitor.ke,
|
|
||||||
uid: $user.uid,
|
|
||||||
id: monitor.mid,
|
|
||||||
maxLatency: monitor.details.stream_flv_maxLatency,
|
|
||||||
hasAudio:false,
|
|
||||||
url: location.origin,
|
|
||||||
path: websocketPath,
|
|
||||||
channel : subStreamChannel,
|
|
||||||
query: websocketQuery
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
options = {
|
|
||||||
type: 'flv',
|
|
||||||
isLive: true,
|
|
||||||
url: getApiPrefix(`flv`)+'/'+monitor.mid + (subStreamChannel ? `/${subStreamChannel}` : '')+'/s.flv'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadedPlayer.flv = flvjs.createPlayer(options);
|
|
||||||
loadedPlayer.flv.attachMediaElement(containerElement.find('.stream-element')[0]);
|
|
||||||
loadedPlayer.flv.on('error',function(err){
|
|
||||||
console.log(err)
|
|
||||||
});
|
|
||||||
loadedPlayer.flv.load();
|
|
||||||
loadedPlayer.flv.play();
|
|
||||||
}else{
|
|
||||||
new PNotify({title:'Stream cannot be started',text:'FLV.js is not supported on this browser. Try another stream type.',type:'error'});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case'hls':
|
|
||||||
function createSteamNow(){
|
|
||||||
clearTimeout(loadedPlayer.m3uCheck)
|
|
||||||
var url = getApiPrefix(`hls`) + '/' + monitor.mid + (subStreamChannel ? `/${subStreamChannel}` : '') + '/s.m3u8'
|
|
||||||
$.get(url,function(m3u){
|
|
||||||
if(m3u == 'File Not Found'){
|
|
||||||
loadedPlayer.m3uCheck = setTimeout(function(){
|
|
||||||
createSteamNow()
|
|
||||||
},2000)
|
|
||||||
}else{
|
|
||||||
var video = containerElement.find('.stream-element')[0]
|
|
||||||
if (isAppleDevice) {
|
|
||||||
video.src = url;
|
|
||||||
video.addEventListener('loadedmetadata', function() {
|
|
||||||
setTimeout(function(){
|
|
||||||
video.play();
|
|
||||||
},3000)
|
|
||||||
}, false);
|
|
||||||
}else{
|
|
||||||
var hlsOptions = safeJsonParse(dashboardOptions().hlsOptions) || {}
|
|
||||||
if(hlsOptions instanceof String){
|
|
||||||
hlsOptions = {}
|
|
||||||
new PNotify({
|
|
||||||
title: lang['Invalid JSON'],
|
|
||||||
text: lang.hlsOptionsInvalid,
|
|
||||||
type: `warning`,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if(loadedPlayer.hls){
|
|
||||||
loadedPlayer.hls.destroy()
|
|
||||||
revokeVideoPlayerUrl(monitorId)
|
|
||||||
}
|
|
||||||
loadedPlayer.hls = new Hls(hlsOptions)
|
|
||||||
loadedPlayer.hls.loadSource(url)
|
|
||||||
loadedPlayer.hls.attachMedia(video)
|
|
||||||
loadedPlayer.hls.on(Hls.Events.MANIFEST_PARSED,function() {
|
|
||||||
if (video.paused) {
|
|
||||||
video.play();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
loadedPlayer.flv = flvjs.createPlayer(options);
|
||||||
}
|
loadedPlayer.flv.attachMediaElement(containerElement.find('.stream-element')[0]);
|
||||||
createSteamNow()
|
loadedPlayer.flv.on('error',function(err){
|
||||||
break;
|
console.log(err)
|
||||||
case'mjpeg':
|
});
|
||||||
var liveStreamElement = containerElement.find('.stream-element')
|
loadedPlayer.flv.load();
|
||||||
var setSource = function(){
|
loadedPlayer.flv.play();
|
||||||
liveStreamElement.attr('src',getApiPrefix(`mjpeg`)+'/'+monitorId + (subStreamChannel ? `/${subStreamChannel}` : ''))
|
}else{
|
||||||
liveStreamElement.unbind('ready')
|
new PNotify({title:'Stream cannot be started',text:'FLV.js is not supported on this browser. Try another stream type.',type:'error'});
|
||||||
liveStreamElement.ready(function(){
|
}
|
||||||
|
break;
|
||||||
|
case'hls':
|
||||||
|
function createSteamNow(){
|
||||||
|
clearTimeout(loadedPlayer.m3uCheck)
|
||||||
|
var url = getApiPrefix(`hls`) + '/' + monitor.mid + (subStreamChannel ? `/${subStreamChannel}` : '') + '/s.m3u8'
|
||||||
|
$.get(url,function(m3u){
|
||||||
|
if(m3u == 'File Not Found'){
|
||||||
|
loadedPlayer.m3uCheck = setTimeout(function(){
|
||||||
|
createSteamNow()
|
||||||
|
},2000)
|
||||||
|
}else{
|
||||||
|
var video = containerElement.find('.stream-element')[0]
|
||||||
|
if (isAppleDevice) {
|
||||||
|
video.src = url;
|
||||||
|
video.addEventListener('loadedmetadata', function() {
|
||||||
|
setTimeout(function(){
|
||||||
|
video.play();
|
||||||
|
},3000)
|
||||||
|
}, false);
|
||||||
|
}else{
|
||||||
|
var hlsOptions = safeJsonParse(dashboardOptions().hlsOptions) || {}
|
||||||
|
if(hlsOptions instanceof String){
|
||||||
|
hlsOptions = {}
|
||||||
|
new PNotify({
|
||||||
|
title: lang['Invalid JSON'],
|
||||||
|
text: lang.hlsOptionsInvalid,
|
||||||
|
type: `warning`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(loadedPlayer.hls){
|
||||||
|
loadedPlayer.hls.destroy()
|
||||||
|
revokeVideoPlayerUrl(monitorId)
|
||||||
|
}
|
||||||
|
loadedPlayer.hls = new Hls(hlsOptions)
|
||||||
|
loadedPlayer.hls.loadSource(url)
|
||||||
|
loadedPlayer.hls.attachMedia(video)
|
||||||
|
loadedPlayer.hls.on(Hls.Events.MANIFEST_PARSED,function() {
|
||||||
|
if (video.paused) {
|
||||||
|
video.play();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
createSteamNow()
|
||||||
|
break;
|
||||||
|
case'mjpeg':
|
||||||
|
var liveStreamElement = containerElement.find('.stream-element')
|
||||||
|
var setSource = function(){
|
||||||
|
liveStreamElement.attr('src',getApiPrefix(`mjpeg`)+'/'+monitorId + (subStreamChannel ? `/${subStreamChannel}` : ''))
|
||||||
|
liveStreamElement.unbind('ready')
|
||||||
|
liveStreamElement.ready(function(){
|
||||||
|
setTimeout(function(){
|
||||||
|
liveStreamElement.contents().find("body").append('<style>img{width:100%;height:100%}</style>')
|
||||||
|
},1000)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setSource()
|
||||||
|
liveStreamElement.on('error',function(err){
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
liveStreamElement.contents().find("body").append('<style>img{width:100%;height:100%}</style>')
|
setSource()
|
||||||
},1000)
|
},4000)
|
||||||
})
|
})
|
||||||
}
|
break;
|
||||||
setSource()
|
}
|
||||||
liveStreamElement.on('error',function(err){
|
|
||||||
setTimeout(function(){
|
|
||||||
setSource()
|
|
||||||
},4000)
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$.each(onLiveStreamInitiateExtensions,function(n,extender){
|
$.each(onLiveStreamInitiateExtensions,function(n,extender){
|
||||||
extender(streamType,monitor,loadedPlayer,subStreamChannel)
|
extender(streamType,monitor,loadedPlayer,subStreamChannel)
|
||||||
})
|
})
|
||||||
|
@ -662,13 +667,15 @@ function loadPreviouslyOpenedLiveGridBlocks(){
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function closeAllLiveGridPlayers(rememberClose){
|
function closeAllLiveGridPlayers(rememberClose){
|
||||||
var watchedOn = dashboardOptions().watch_on || {}
|
$.each(loadedMonitors,function(monitorId,monitor){
|
||||||
$.each(watchedOn,function(n,groupOfMons){
|
mainSocket.f({
|
||||||
$.each(groupOfMons,function(monitorId,monitor){
|
f: 'monitor',
|
||||||
if(monitor === 1){
|
ff: 'watch_off',
|
||||||
mainSocket.f({f:'monitor',ff:'watch_off',id: monitorId})
|
id: monitor.mid
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
setTimeout(function(){
|
||||||
|
saveLiveGridBlockOpenState(monitorId,$user.ke,0)
|
||||||
|
},1000)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function saveLiveGridBlockOpenState(monitorId,groupKey,state){
|
function saveLiveGridBlockOpenState(monitorId,groupKey,state){
|
||||||
|
@ -870,6 +877,70 @@ function signalCheckLiveStream(options){
|
||||||
delete(liveGridData.signal);
|
delete(liveGridData.signal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function pauseMonitorItem(monitorId){
|
||||||
|
liveGridPlayingNow[monitorId] = false
|
||||||
|
closeLiveGridPlayer(monitorId,false)
|
||||||
|
}
|
||||||
|
function resumeMonitorItem(monitorId){
|
||||||
|
// needs to know about substream
|
||||||
|
liveGridPlayingNow[monitorId] = true
|
||||||
|
resetMonitorCanvas(monitorId,true,null)
|
||||||
|
}
|
||||||
|
function isScrolledIntoView(elem){
|
||||||
|
var el = $(elem)
|
||||||
|
var theWindow = $(window)
|
||||||
|
var docViewTop = theWindow.scrollTop();
|
||||||
|
var docViewBottom = docViewTop + theWindow.height();
|
||||||
|
|
||||||
|
var elemTop = el.offset().top;
|
||||||
|
var elemBottom = elemTop + el.height();
|
||||||
|
|
||||||
|
return (
|
||||||
|
elemTop >= docViewTop && elemTop <= docViewBottom ||
|
||||||
|
elemBottom >= docViewTop && elemBottom <= docViewBottom
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function pauseAllLiveGridPlayers(unpause){
|
||||||
|
$('.monitor_item').each(function(n,el){
|
||||||
|
var monitorId = $(el).attr('data-mid')
|
||||||
|
if(!unpause){
|
||||||
|
pauseMonitorItem(monitorId)
|
||||||
|
}else{
|
||||||
|
resumeMonitorItem(monitorId)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function setPauseStatusForMonitorItems(){
|
||||||
|
$('.monitor_item').each(function(n,el){
|
||||||
|
var monitorId = $(el).attr('data-mid')
|
||||||
|
var isVisible = isScrolledIntoView(el)
|
||||||
|
console.log(monitorId,isVisible)
|
||||||
|
if(isVisible){
|
||||||
|
if(!liveGridPlayingNow[monitorId])resumeMonitorItem(monitorId);
|
||||||
|
}else{
|
||||||
|
pauseMonitorItem(monitorId)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function setPauseScrollTimeout(){
|
||||||
|
clearTimeout(liveGridPauseScrollTimeout)
|
||||||
|
if(tabTree.name === 'liveGrid'){
|
||||||
|
liveGridPauseScrollTimeout = setTimeout(function(){
|
||||||
|
setPauseStatusForMonitorItems()
|
||||||
|
},700)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function openAllLiveGridPlayers(){
|
||||||
|
$.each(loadedMonitors,function(monitorId,monitor){
|
||||||
|
mainSocket.f({
|
||||||
|
f: 'monitor',
|
||||||
|
ff: 'watch_on',
|
||||||
|
id: monitor.mid
|
||||||
|
})
|
||||||
|
openLiveGrid()
|
||||||
|
})
|
||||||
|
}
|
||||||
$(document).ready(function(e){
|
$(document).ready(function(e){
|
||||||
liveGrid
|
liveGrid
|
||||||
.on('dblclick','.stream-block',function(){
|
.on('dblclick','.stream-block',function(){
|
||||||
|
@ -882,16 +953,16 @@ $(document).ready(function(e){
|
||||||
})
|
})
|
||||||
.on('click','.launch-live-grid-monitor',function(){
|
.on('click','.launch-live-grid-monitor',function(){
|
||||||
var monitorId = $(this).parents('[data-mid]').attr('data-mid')
|
var monitorId = $(this).parents('[data-mid]').attr('data-mid')
|
||||||
// if(isMobile){
|
if(isMobile){
|
||||||
// createLivePlayerTab(loadedMonitors[monitorId])
|
createLivePlayerTab(loadedMonitors[monitorId])
|
||||||
// }else{
|
}else{
|
||||||
mainSocket.f({
|
mainSocket.f({
|
||||||
f: 'monitor',
|
f: 'monitor',
|
||||||
ff: 'watch_on',
|
ff: 'watch_on',
|
||||||
id: monitorId
|
id: monitorId
|
||||||
})
|
})
|
||||||
openLiveGrid()
|
openLiveGrid()
|
||||||
// }
|
}
|
||||||
})
|
})
|
||||||
.on('click','.monitor-live-group-open',function(){
|
.on('click','.monitor-live-group-open',function(){
|
||||||
var monitorIds = $(this).attr('monitor-ids').split(',')
|
var monitorIds = $(this).attr('monitor-ids').split(',')
|
||||||
|
@ -1012,26 +1083,10 @@ $(document).ready(function(e){
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
$('.open-all-monitors').click(function(){
|
$('.open-all-monitors').click(function(){
|
||||||
$.each(loadedMonitors,function(monitorId,monitor){
|
openAllLiveGridPlayers()
|
||||||
mainSocket.f({
|
|
||||||
f: 'monitor',
|
|
||||||
ff: 'watch_on',
|
|
||||||
id: monitor.mid
|
|
||||||
})
|
|
||||||
openLiveGrid()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
$('.close-all-monitors').click(function(){
|
$('.close-all-monitors').click(function(){
|
||||||
$.each(loadedMonitors,function(monitorId,monitor){
|
closeAllLiveGridPlayers()
|
||||||
mainSocket.f({
|
|
||||||
f: 'monitor',
|
|
||||||
ff: 'watch_off',
|
|
||||||
id: monitor.mid
|
|
||||||
})
|
|
||||||
setTimeout(function(){
|
|
||||||
saveLiveGridBlockOpenState(monitorId,$user.ke,0)
|
|
||||||
},1000)
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
var dontShowDetectionSelectionOnStart = dashboardOptions().dontShowDetection != 1
|
var dontShowDetectionSelectionOnStart = dashboardOptions().dontShowDetection != 1
|
||||||
liveGridData = GridStack.init();
|
liveGridData = GridStack.init();
|
||||||
|
@ -1042,14 +1097,14 @@ $(document).ready(function(e){
|
||||||
},700)
|
},700)
|
||||||
})
|
})
|
||||||
.on('resizestop', function(){
|
.on('resizestop', function(){
|
||||||
// resetAllLiveGridDimensionsInMemory()
|
resetAllLiveGridDimensionsInMemory()
|
||||||
saveLiveGridBlockPositions()
|
saveLiveGridBlockPositions()
|
||||||
});
|
});
|
||||||
addOnTabReopen('liveGrid', function () {
|
addOnTabReopen('liveGrid', function () {
|
||||||
loadPreviouslyOpenedLiveGridBlocks()
|
pauseAllLiveGridPlayers(true)
|
||||||
})
|
})
|
||||||
addOnTabAway('liveGrid', function () {
|
addOnTabAway('liveGrid', function () {
|
||||||
closeAllLiveGridPlayers()
|
pauseAllLiveGridPlayers(false)
|
||||||
})
|
})
|
||||||
onInitWebsocket(function (d){
|
onInitWebsocket(function (d){
|
||||||
loadPreviouslyOpenedLiveGridBlocks()
|
loadPreviouslyOpenedLiveGridBlocks()
|
||||||
|
@ -1059,9 +1114,6 @@ $(document).ready(function(e){
|
||||||
})
|
})
|
||||||
onWebSocketEvent(function (d){
|
onWebSocketEvent(function (d){
|
||||||
switch(d.f){
|
switch(d.f){
|
||||||
case'init_success':
|
|
||||||
// loadPreviouslyOpenedLiveGridBlocks()
|
|
||||||
break;
|
|
||||||
case'video_build_success':
|
case'video_build_success':
|
||||||
d.status = 1
|
d.status = 1
|
||||||
d.mid = d.id || d.mid
|
d.mid = d.id || d.mid
|
||||||
|
@ -1185,12 +1237,14 @@ $(document).ready(function(e){
|
||||||
})
|
})
|
||||||
$(window).focus(function(){
|
$(window).focus(function(){
|
||||||
if(canBackgroundStream()){
|
if(canBackgroundStream()){
|
||||||
loadPreviouslyOpenedLiveGridBlocks()
|
pauseAllLiveGridPlayers(true)
|
||||||
}
|
}
|
||||||
}).blur(function(){
|
}).blur(function(){
|
||||||
if(canBackgroundStream()){
|
if(canBackgroundStream()){
|
||||||
closeAllLiveGridPlayers()
|
pauseAllLiveGridPlayers(false)
|
||||||
}
|
}
|
||||||
|
}).scroll(function(){
|
||||||
|
setPauseScrollTimeout()
|
||||||
})
|
})
|
||||||
dashboardSwitchCallbacks.monitorOrder = function(toggleState){
|
dashboardSwitchCallbacks.monitorOrder = function(toggleState){
|
||||||
if(toggleState !== 1){
|
if(toggleState !== 1){
|
||||||
|
|
|
@ -618,7 +618,7 @@ function importIntoMonitorEditor(options){
|
||||||
input_map_choices = monitorDetails.input_map_choices;
|
input_map_choices = monitorDetails.input_map_choices;
|
||||||
}
|
}
|
||||||
$.each(input_map_choices,function(n,v){
|
$.each(input_map_choices,function(n,v){
|
||||||
$.each(v,function(m,b){
|
$.each(safeJsonParse(v),function(m,b){
|
||||||
var parent = $('[input-mapping="'+n+'"] .choices')
|
var parent = $('[input-mapping="'+n+'"] .choices')
|
||||||
drawInputMapSelectorHtml(b,parent)
|
drawInputMapSelectorHtml(b,parent)
|
||||||
})
|
})
|
||||||
|
|
|
@ -647,7 +647,7 @@ function drawMatrices(event,options){
|
||||||
var html = ''
|
var html = ''
|
||||||
$.each(event.details.matrices,function(n,matrix){
|
$.each(event.details.matrices,function(n,matrix){
|
||||||
html += `<div class="stream-detected-object" name="${objectTagGroup}" style="height:${heightRatio * matrix.height}px;width:${widthRatio * matrix.width}px;top:${heightRatio * matrix.y}px;left:${widthRatio * matrix.x}px;">`
|
html += `<div class="stream-detected-object" name="${objectTagGroup}" style="height:${heightRatio * matrix.height}px;width:${widthRatio * matrix.width}px;top:${heightRatio * matrix.y}px;left:${widthRatio * matrix.x}px;">`
|
||||||
if(matrix.tag)html += `<span class="tag">${matrix.tag}</span>`
|
if(matrix.tag)html += `<span class="tag">${matrix.tag}${!isNaN(matrix.id) ? ` <small class="label label-default">${matrix.id}</small>`: ''}</span>`
|
||||||
html += '</div>'
|
html += '</div>'
|
||||||
})
|
})
|
||||||
theContainer.append(html)
|
theContainer.append(html)
|
||||||
|
|
|
@ -322,7 +322,7 @@ $(document).ready(function(e){
|
||||||
var html = ''
|
var html = ''
|
||||||
$.each(event.details.matrices,function(n,matrix){
|
$.each(event.details.matrices,function(n,matrix){
|
||||||
html += `<div class="stream-detected-object" name="${event.details.name}" style="height:${heightRatio * matrix.height}px;width:${widthRatio * matrix.width}px;top:${heightRatio * matrix.y}px;left:${widthRatio * matrix.x}px;">`
|
html += `<div class="stream-detected-object" name="${event.details.name}" style="height:${heightRatio * matrix.height}px;width:${widthRatio * matrix.width}px;top:${heightRatio * matrix.y}px;left:${widthRatio * matrix.x}px;">`
|
||||||
if(matrix.tag)html += `<span class="tag">${matrix.tag}</span>`
|
if(matrix.tag)html += `<span class="tag">${matrix.tag}${!isNaN(matrix.id) ? ` <small class="label label-default">${matrix.id}</small>`: ''}</span>`
|
||||||
html += '</div>'
|
html += '</div>'
|
||||||
})
|
})
|
||||||
streamObjectsContainer.append(html)
|
streamObjectsContainer.append(html)
|
||||||
|
|
Loading…
Reference in New Issue