diff --git a/definitions/base.js b/definitions/base.js index 6b768fe9..d27d33cc 100644 --- a/definitions/base.js +++ b/definitions/base.js @@ -9139,9 +9139,11 @@ module.exports = function(s,config,lang){ "divContent": `
+ +
x1 diff --git a/languages/en_CA.json b/languages/en_CA.json index 9bcfc920..b4312c8c 100644 --- a/languages/en_CA.json +++ b/languages/en_CA.json @@ -1022,6 +1022,8 @@ "activationRequired": "Activation Required", "autoResizeGrid": "Auto Resize Grid", "jumpFiveSeconds": "Jump 5 Seconds", + "jumptoNextVideo": "Jump to Next Video", + "jumptoPreviousVideo": "Jump to Previous Video", "featureRequiresActivationText": "The feature you are trying to use requires that your installation be activated. Please see the Help tab for more information.", "FileNotExistText": "Cannot save non existant file. Something went wrong.", "CameraNotRecordingText": "Settings may be incompatible. Check encoders. Restarting...", diff --git a/libs/events/onvif.js b/libs/events/onvif.js index 6f177fe8..90d524e6 100644 --- a/libs/events/onvif.js +++ b/libs/events/onvif.js @@ -33,7 +33,7 @@ module.exports = function(s,config,lang){ try { detector.listen((motion) => { if (motion) { - // onvifEventLog(`ONVIF Event Detected!`) + onvifEventLog(`ONVIF Event Detected!`) triggerEvent({ f: 'trigger', id: monitorId, @@ -49,16 +49,17 @@ module.exports = function(s,config,lang){ // imgWidth: img.width, } }) - // } else { - // onvifEventLog(`ONVIF Event Stopped`) + } else { + onvifEventLog(`ONVIF Event Stopped`) } }); } catch(e) { + console.error(e) onvifEventLog(`ONVIF Event Error`,e) } return detector } - function initializeOnvifEvents(monitorConfig){ + async function initializeOnvifEvents(monitorConfig){ const monitorMode = monitorConfig.mode const groupKey = monitorConfig.ke const monitorId = monitorConfig.mid @@ -74,13 +75,19 @@ module.exports = function(s,config,lang){ onvifEventControllers[onvifIdKey].close() s.debugLog('ONVIF Event Module Warning : This could cause a memory leak?') }catch(err){ - s.debugLog('ONVIF Event Module Error', err); + s.debugLog('ONVIF Event Module Error', err.stack); } - delete(onvifEventControllers[onvifIdKey]) - if(monitorMode !== 'stop'){ - startMotion(onvifId,monitorConfig).then((detector) => { + try{ + delete(onvifEventControllers[onvifIdKey]) + s.debugLog('Can ',monitorConfig.name, 'read ONVIF Events?',monitorMode !== 'stop') + if(monitorMode !== 'stop'){ + s.debugLog('Starting ONVIF Event Reader on ',monitorConfig.name) + const detector = await startMotion(onvifId,monitorConfig) onvifEventControllers[onvifIdKey] = detector; - }) + } + }catch(err){ + console.error(err) + s.debugLog('ONVIF Event Module Start Error', err.stack); } } } diff --git a/web/assets/js/bs5.timeline.js b/web/assets/js/bs5.timeline.js index 5457bac2..dc176192 100644 --- a/web/assets/js/bs5.timeline.js +++ b/web/assets/js/bs5.timeline.js @@ -222,6 +222,18 @@ $(document).ready(function(){ setTimeOfCanvasVideos(clickTime) setHollowClickQueue() } + function timeStripActionWithPausePlay(restartPlaySpeed){ + return new Promise((resolve,reject) => { + var currentlyPlaying = !!isPlaying; + timeStripPlay(true) + resolve(timeChanging) + if(currentlyPlaying){ + setTimeout(() => { + timeStripPlay() + },restartPlaySpeed || 500) + } + }) + } function createTimeline(){ timeStripItemIncrement = 0; var timeChangingTimeout = null @@ -243,17 +255,12 @@ $(document).ready(function(){ // make tick timeStripVisTick = timeStripVis.addCustomTime(dateNow, `${lang.Time}`); timeStripVis.on('click', async function(properties) { - var currentlyPlaying = !!isPlaying; - timeStripPlay(true) - if(!timeChanging){ - var clickTime = properties.time; - await resetTimeline(clickTime) - } - if(currentlyPlaying){ - setTimeout(() => { - timeStripPlay() - },500) - } + var clickTime = properties.time; + timeStripActionWithPausePlay().then((timeChanging) => { + if(!timeChanging){ + resetTimeline(clickTime) + } + }) }); timeStripVis.on('rangechange', function(properties){ timeChanging = true @@ -290,11 +297,11 @@ $(document).ready(function(){ if(difference <= 60){ return 0.1 }else if(difference > minute && difference <= hour){ - return 0.3 + return 0.1 }else if(difference > hour && difference < day){ - return 0.6 + return 0.3 }else if(difference >= day){ - return 10 + return 0.9 } } function scrollTimeline(addHours){ @@ -573,6 +580,9 @@ $(document).ready(function(){ } newTime = new Date(newTime) await resetTimeline(newTime) + checkScroll(tickTime) + } + function checkScroll(tickTime){ if(tickTime <= timeStripAutoScrollPositionStart){ scrollTimeline(-timeStripAutoScrollAmount) }else if(tickTime >= timeStripAutoScrollPositionEnd){ @@ -670,6 +680,57 @@ $(document).ready(function(){ timeStripItemColors[monitorId] = itemColor }) } + function findEndingLatestInCanvas(){ + var foundVideo = {time: 0}; + $.each(loadedVideosOnCanvas,function(monitorId,video){ + if(!video)return; + var videoTime = new Date(video.time).getTime() + if(new Date(foundVideo.time).getTime() < videoTime){ + foundVideo = video; + } + }) + if(!foundVideo.mid)return null; + return foundVideo + } + function findCurrentVideoIndex(video){ + var currentVideoIndex = loadedVideosOnTimeStrip.findIndex((item) => { + return video.mid === item.mid && video.time == item.time + }); + return currentVideoIndex + } + function findNextVideo(){ + var tickTime = getTickDate() + let closestObject = [...loadedVideosOnTimeStrip] + .sort((a, b) => new Date(a.time) - new Date(b.time)) + .find(obj => new Date(obj.time) > tickTime); + return closestObject; + } + function findPreviousVideo(){ + var tickTime = getTickDate() + let closestObject = [...loadedVideosOnTimeStrip] + .sort((a, b) => new Date(b.time) - new Date(a.time)) + .find(obj => new Date(obj.time) < tickTime); + return closestObject; + } + async function jumpToVideo(video){ + var clickTime = new Date(video.time) + timeStripActionWithPausePlay().then(async (timeChanging) => { + if(!timeChanging){ + await resetTimeline(clickTime) + checkScroll(clickTime) + } + }) + } + async function jumpToNextVideo(){ + var video = findNextVideo() + if(!video)return console.log('No More!') + await jumpToVideo(video) + } + async function jumpToPreviousVideo(){ + var video = findPreviousVideo() + if(!video)return console.log('No More!') + await jumpToVideo(video) + } sideMenuList.on('click','[timeline-menu-action]',function(){ var el = $(this) var type = el.attr('timeline-menu-action') @@ -705,6 +766,12 @@ $(document).ready(function(){ case'jumpRight': jumpTimeline(5000,'right') break; + case'jumpNext': + jumpToNextVideo() + break; + case'jumpPrev': + jumpToPreviousVideo() + break; case'speed': var speed = parseInt(el.attr('speed')) if(featureIsActivated(true)){