diff --git a/web/assets/css/bs5.videoPlayer.css b/web/assets/css/bs5.videoPlayer.css
index 46bea314..54f593c7 100644
--- a/web/assets/css/bs5.videoPlayer.css
+++ b/web/assets/css/bs5.videoPlayer.css
@@ -29,3 +29,27 @@
.tab-videoPlayer:hover .tab-videoPlayer-event-objects {
display: none;
}
+
+/* video-time-strip */
+.video-time-img {
+ background-size: cover;
+ background-position: center;
+ min-height:400px;
+}
+.video-time-img:not(.video-time-no-img) .card-body:hover {
+ background: rgba(0,0,0,0.9);
+ color: #fff;
+}
+.video-time-strip {
+ min-height: 30px;
+ position: relative;
+}
+.video-time-needle {
+ position: absolute;
+ border-left: 3px solid #1f80f9;
+ height: 100%;
+ transition: none;
+}
+.video-time-needle-event {
+ border-left: 3px solid #828282;
+}
diff --git a/web/assets/js/bs5.recentVideos.js b/web/assets/js/bs5.recentVideos.js
index e213a8c5..dc46a8bf 100644
--- a/web/assets/js/bs5.recentVideos.js
+++ b/web/assets/js/bs5.recentVideos.js
@@ -2,8 +2,12 @@ $(document).ready(function(){
var theBlock = $('#recentVideos')
var theList = $('#recentVideosList')
var monitorList = theBlock.find('.monitors_list')
- function drawRowToList(row,toBegin){
+ function drawRowToList(row,toBegin,returnLastChild){
theList[toBegin ? 'prepend' : 'append'](createVideoRow(row))
+ if(returnLastChild){
+ var theChildren = theList.children()
+ return toBegin ? theChildren.first() : theChildren.last()
+ }
}
function loadVideos(options,callback){
theList.empty();
@@ -11,7 +15,8 @@ $(document).ready(function(){
var html = ``
var videos = data.videos || {}
$.each(videos,function(n,row){
- drawRowToList(row)
+ var createdCardCarrier = drawRowToList(row,false,true)
+ bindFrameFindingByMouseMove(createdCardCarrier,row)
})
getCountOfEvents({
monitorId: options.monitorId,
diff --git a/web/assets/js/bs5.videos.js b/web/assets/js/bs5.videos.js
index cf7344fe..757a713a 100644
--- a/web/assets/js/bs5.videos.js
+++ b/web/assets/js/bs5.videos.js
@@ -32,7 +32,7 @@ function createVideoLinks(video){
video.details = details
return video
}
-function applyEventListToVideos(videos,events){
+function applyDataListToVideos(videos,events,keyName,reverseList){
var updatedVideos = videos.concat([])
var currentEvents = events.concat([])
updatedVideos.forEach(function(video){
@@ -46,39 +46,109 @@ function applyEventListToVideos(videos,events){
currentEvents.splice(index, 1)
}
})
- video.events = videoEvents
+ if(reverseList)videoEvents = videoEvents.reverse()
+ video[keyName || 'events'] = videoEvents
})
return updatedVideos
}
-function createVideoRow(row,classOverride){
- var possibleEventFrames = ''
- var hasRows = row.events && row.events.length > 0
- if(hasRows){
- var eventMatrixHtml = ``
- var objectsFound = {}
- eventMatrixHtml += `
-
-
- | ${lang.Events} |
- ${row.events.length} |
-
`
- $.each(([]).concat(row.events).splice(0,11),function(n,theEvent){
- var imagePath = `${formattedTimeForFilename(theEvent.time,false,'YYYY-MM-DD')}/${formattedTimeForFilename(theEvent.time,false,'YYYY-MM-DDTHH-mm-ss')}.jpg`
- possibleEventFrames += ``
- })
- $.each(row.events,function(n,theEvent){
- $.each(theEvent.details.matrices,function(n,matrix){
- if(!objectsFound[matrix.tag])objectsFound[matrix.tag] = 1
- ++objectsFound[matrix.tag]
+function applyTimelapseFramesListToVideos(videos,events,keyName,reverseList){
+ var thisApiPrefix = getApiPrefix() + '/timelapse/' + $user.ke + '/'
+ var newVideos = applyDataListToVideos(videos,events,keyName,reverseList)
+ newVideos.forEach(function(video){
+ video.timelapseFrames.forEach(function(row){
+ var apiURL = thisApiPrefix + row.mid
+ row.href = libURL + apiURL + '/' + row.filename.split('T')[0] + '/' + row.filename
+ })
+ })
+ return newVideos
+}
+function getFrameOnVideoRow(percentageInward,video){
+ var startTime = new Date(video.time)
+ var endTime = new Date(video.end)
+ var timeDifference = endTime - startTime
+ var timeInward = timeDifference / (100 / percentageInward)
+ var timeAdded = new Date(startTime.getTime() + timeInward) // ms
+ // video.timelapseFrames.forEach(function(row){
+ // var isValid = new Date(row.time) > timeAdded
+ // console.log(new Date(row.time),timeAdded)
+ // if(isValid)console.log(row.time)
+ //
+ // })
+ var foundFrame = video.timelapseFrames.find(function(row){
+ return new Date(row.time) > timeAdded
+ });
+ return foundFrame
+}
+function bindFrameFindingByMouseMove(createdCardCarrier,video){
+ var createdCardElement = createdCardCarrier.find('.card').first()
+ var timeImg = createdCardElement.find('.video-time-img')
+ var timeStrip = createdCardElement.find('.video-time-strip')
+ var timeNeedleSeeker = createdCardElement.find('.video-time-needle-seeker')
+ if(video.timelapseFrames.length > 0){
+ createdCardElement.on('mousemove',function(evt){
+ var offest = createdCardElement.offset()
+ var elementWidth = createdCardElement.width() + 2
+ var amountMoved = evt.pageX - offest.left
+ var percentMoved = amountMoved / elementWidth * 100
+ var frameFound = getFrameOnVideoRow(percentMoved,video)
+ if(frameFound){
+ timeImg.css('background-image',`url(${frameFound.href})`)
+ }
+ timeNeedleSeeker.css('left',`${amountMoved}px`)
+ })
+ timeImg.css('background-image',`url(${getFrameOnVideoRow(1,video).href})`)
+ }else{
+ if(video.events.length === 0){
+ timeStrip.hide()
+ }else{
+ var eventMatrixHtml = ``
+ var objectsFound = {}
+ eventMatrixHtml += `
+
+
+ | ${lang.Events} |
+ ${video.events.length} |
+
`
+ $.each(([]).concat(video.events).splice(0,11),function(n,theEvent){
+ var imagePath = `${formattedTimeForFilename(theEvent.time,false,'YYYY-MM-DD')}/${formattedTimeForFilename(theEvent.time,false,'YYYY-MM-DDTHH-mm-ss')}.jpg`
+ possibleEventFrames += ``
})
- })
- $.each(objectsFound,function(tag,count){
- eventMatrixHtml += `
- | ${tag} |
- ${count} |
-
`
- })
- eventMatrixHtml += `
`
+ $.each(video.events,function(n,theEvent){
+ $.each(theEvent.details.matrices,function(n,matrix){
+ if(!objectsFound[matrix.tag])objectsFound[matrix.tag] = 1
+ ++objectsFound[matrix.tag]
+ })
+ })
+ $.each(objectsFound,function(tag,count){
+ eventMatrixHtml += `
+ | ${tag} |
+ ${count} |
+
`
+ })
+ eventMatrixHtml += `
`
+ timeStrip.append(eventMatrixHtml)
+ }
+ timeImg.css('min-height',`auto`).addClass('video-time-no-img')
+ }
+}
+function getPercentOfTimePositionFromVideo(video,theEvent){
+ var startTime = new Date(video.time)
+ var endTime = new Date(video.end)
+ var eventTime = new Date(theEvent.time)
+ var rangeMax = endTime - startTime
+ var eventMs = eventTime - startTime
+ var percentChanged = eventMs / rangeMax * 100
+
+ console.log(`percentChanged`,percentChanged)
+ return percentChanged
+}
+function createVideoRow(row,classOverride){
+ var eventMatrixHtml = ``
+ if(row.events && row.events.length > 0){
+ $.each(row.events,function(n,theEvent){
+ var leftPercent = getPercentOfTimePositionFromVideo(row,theEvent)
+ eventMatrixHtml += ``
+ })
}
var videoEndpoint = getLocation() + '/' + $user.auth_token + '/videos/' + $user.ke + '/' + row.mid + '/' + row.filename
return `
@@ -94,25 +164,27 @@ function createVideoRow(row,classOverride){
-
-
-
- ${moment(row.time).fromNow()}
+
+
+
+
+ ${moment(row.time).fromNow()}
+
+
+ ~${durationBetweenTimes(row.time,row.end)} ${lang.Minutes}
+
-
-
~${durationBetweenTimes(row.time,row.end)} ${lang.Minutes}
+
+
+
${lang.Started} : ${formattedTime(row.time,true)}
+
${lang.Ended} : ${formattedTime(row.end,true)}
+
-
-
-
${lang.Started} : ${formattedTime(row.time,true)}
-
${lang.Ended} : ${formattedTime(row.end,true)}
-
-
-
${possibleEventFrames}
-
`
@@ -148,12 +220,16 @@ function getVideos(options,callback){
}
$.getJSON(`${getApiPrefix(`videos`)}${monitorId ? `/${monitorId}` : ''}?${requestQueries.concat([`limit=${limit}`]).join('&')}`,function(data){
var videos = data.videos
- $.getJSON(`${getApiPrefix(`events`)}${monitorId ? `/${monitorId}` : ''}?${requestQueries.join('&')}`,function(eventData){
- var newVideos = applyEventListToVideos(videos,eventData)
- $.each(newVideos,function(n,video){
- loadVideoData(video)
+ $.getJSON(`${getApiPrefix(`timelapse`)}${monitorId ? `/${monitorId}` : ''}?${requestQueries.join('&')}`,function(timelapseFrames){
+ $.getJSON(`${getApiPrefix(`events`)}${monitorId ? `/${monitorId}` : ''}?${requestQueries.join('&')}`,function(eventData){
+ console.log(timelapseFrames)
+ var newVideos = applyDataListToVideos(videos,eventData)
+ newVideos = applyTimelapseFramesListToVideos(newVideos,timelapseFrames,'timelapseFrames',true)
+ $.each(newVideos,function(n,video){
+ loadVideoData(video)
+ })
+ callback({videos: newVideos})
})
- callback({videos: newVideos})
})
})
}