Jump to Next/Previous Video for Timeline

node-20
Moe 2023-08-07 17:02:25 -07:00
parent c13215f05c
commit 3f08165fb8
4 changed files with 101 additions and 23 deletions

View File

@ -9139,9 +9139,11 @@ module.exports = function(s,config,lang){
"divContent": `
<div class="text-center">
<div class="btn-group">
<a class="btn btn-sm btn-default" timeline-action="jumpPrev" title="${lang.jumptoPreviousVideo}"><i class="fa fa-angle-double-left"></i></a>
<a class="btn btn-sm btn-default" timeline-action="jumpLeft" title="${lang.jumpFiveSeconds}"><i class="fa fa-arrow-circle-left"></i></a>
<a class="btn btn-sm btn-primary" timeline-action="playpause" title="${lang.Play}/${lang.Pause}"><i class="fa fa-play-circle-o"></i></a>
<a class="btn btn-sm btn-default" timeline-action="jumpRight" title="${lang.jumpFiveSeconds}"><i class="fa fa-arrow-circle-right"></i></a>
<a class="btn btn-sm btn-default" timeline-action="jumpNext" title="${lang.jumptoNextVideo}"><i class="fa fa-angle-double-right"></i></a>
</div>
<div class="btn-group">
<a class="btn btn-sm btn-default btn-success" timeline-action="speed" speed="1" title="${lang.Speed} x1">x1</a>

View File

@ -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...",

View File

@ -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);
}
try{
delete(onvifEventControllers[onvifIdKey])
s.debugLog('Can ',monitorConfig.name, 'read ONVIF Events?',monitorMode !== 'stop')
if(monitorMode !== 'stop'){
startMotion(onvifId,monitorConfig).then((detector) => {
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);
}
}
}

View File

@ -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)
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)){