diff --git a/web/ajax/status.php b/web/ajax/status.php index 84399989d..ab5d61050 100644 --- a/web/ajax/status.php +++ b/web/ajax/status.php @@ -367,7 +367,7 @@ function getNearEvents() { else $midSql = ''; - $sql = "select E.Id as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where $sortColumn ".($sortOrder=='asc'?'<=':'>=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn ".($sortOrder=='asc'?'desc':'asc'); + $sql = "select E.Id as Id, E.StartTime as StartTime from Events as E inner join Monitors as M on E.MonitorId = M.Id where $sortColumn ".($sortOrder=='asc'?'<=':'>=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn ".($sortOrder=='asc'?'desc':'asc'); $result = dbQuery( $sql ); while ( $id = dbFetchNext( $result, 'Id' ) ) { if ( $id == $eventId ) { @@ -376,7 +376,7 @@ function getNearEvents() { } } - $sql = "select E.Id as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where $sortColumn ".($sortOrder=='asc'?'>=':'<=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn $sortOrder"; + $sql = "select E.Id as Id, E.StartTime as StartTime from Events as E inner join Monitors as M on E.MonitorId = M.Id where $sortColumn ".($sortOrder=='asc'?'>=':'<=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn $sortOrder"; $result = dbQuery( $sql ); while ( $id = dbFetchNext( $result, 'Id' ) ) { if ( $id == $eventId ) { @@ -388,6 +388,8 @@ function getNearEvents() { $result = array( 'EventId'=>$eventId ); $result['PrevEventId'] = empty($prevEvent)?0:$prevEvent['Id']; $result['NextEventId'] = empty($nextEvent)?0:$nextEvent['Id']; + $result['PrevEventStartTime'] = empty($prevEvent)?0:$prevEvent['StartTime']; + $result['NextEventStartTime'] = empty($nextEvent)?0:$nextEvent['StartTime']; $result['PrevEventDefVideoPath'] = empty($prevEvent)?0:(getEventDefaultVideoPath($prevEvent)); $result['NextEventDefVideoPath'] = empty($nextEvent)?0:(getEventDefaultVideoPath($nextEvent)); return( $result ); diff --git a/web/skins/classic/css/classic/views/event.css b/web/skins/classic/css/classic/views/event.css index e80710772..e3c666156 100644 --- a/web/skins/classic/css/classic/views/event.css +++ b/web/skins/classic/css/classic/views/event.css @@ -106,32 +106,32 @@ #monitorStatus #monitorState { } -#dvrControls { +.dvrControls { margin-top: 3px; margin-bottom: 2px; text-align: center; } -#dvrControls input { +.dvrControls input { height: 20px; width: 28px; padding-bottom: 3px; margin: 0 3px; } -#dvrControls input[disabled=disabled] { +.dvrControls input[disabled=disabled] { color: #aaaaaa; } -#dvrControls input.active { +.dvrControls input.active { border: 1px solid blue; } -#dvrControls input.inactive { +.dvrControls input.inactive { border: 1px solid green; } -#dvrControls input.unavail { +.dvrControls input.unavail { border: 1px solid red; } diff --git a/web/skins/classic/css/dark/views/event.css b/web/skins/classic/css/dark/views/event.css index 13ac0cc0b..de53a6ab5 100644 --- a/web/skins/classic/css/dark/views/event.css +++ b/web/skins/classic/css/dark/views/event.css @@ -89,32 +89,32 @@ #monitorStatus #monitorState { } -#dvrControls { +.dvrControls { margin-top: 3px; margin-bottom: 2px; text-align: center; } -#dvrControls input { +.dvrControls input { height: 20px; width: 28px; padding-bottom: 3px; margin: 0 3px; } -#dvrControls input[disabled=disabled] { +.dvrControls input[disabled=disabled] { color: #aaaaaa; } -#dvrControls input.active { +.dvrControls input.active { border: 1px solid blue; } -#dvrControls input.inactive { +.dvrControls input.inactive { border: 1px solid green; } -#dvrControls input.unavail { +.dvrControls input.unavail { border: 1px solid red; } diff --git a/web/skins/classic/css/flat/views/event.css b/web/skins/classic/css/flat/views/event.css index a41c56a38..2fae0321d 100644 --- a/web/skins/classic/css/flat/views/event.css +++ b/web/skins/classic/css/flat/views/event.css @@ -98,36 +98,36 @@ #monitorStatus #monitorState { } -#dvrControls { +.dvrControls { margin-top: 3px; margin-bottom: 2px; text-align: center; } -#dvrControls input { +.dvrControls input { padding: 10px 10px; width: 50px; margin: 0 3px; font-weight: 900; } -#dvrControls input[disabled=disabled] { +.dvrControls input[disabled=disabled] { color: #aaaaaa; } -#dvrControls input.active { +.dvrControls input.active { border: 0; background-color: #2ecc71; color: #fff; } -#dvrControls input.inactive { +.dvrControls input.inactive { border: 0; background-color: #e67e22; color: #fff; } -#dvrControls input.unavail { +.dvrControls input.unavail { background-color: #ccc; border: 0; cursor: default; diff --git a/web/skins/classic/views/event.php b/web/skins/classic/views/event.php index e0b97e768..bb8f8f2bc 100644 --- a/web/skins/classic/views/event.php +++ b/web/skins/classic/views/event.php @@ -167,7 +167,17 @@ if ( $Event->DefaultVideo() ) { var duration = Length() ?>, startTime = 'StartTime() ?>'; addVideoTimingTrack(document.getElementById('videoobj'), LabelFormat, monitorName, duration, startTime); + + nearEventsQuery( eventData.Id ); + vjsReplay(StartTime()) + $Event->Length())*1000 ?>); + +

+

+ + +

+ @@ -186,7 +196,7 @@ if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) { } } // end if stream method ?> -

+

diff --git a/web/skins/classic/views/js/event.js b/web/skins/classic/views/js/event.js index 20beaa885..29ca7aedf 100644 --- a/web/skins/classic/views/js/event.js +++ b/web/skins/classic/views/js/event.js @@ -1,5 +1,36 @@ var vid = null; +function vjsReplay(endTime) { + var video = videojs('videoobj').ready(function(){ + var player = this; + player.on('ended', function() { + switch(replayMode.value) { + case 'none': + break; + case 'single': + player.play(); + break; + case 'all': +// nextEventStartTime.getTime() is a mootools workaround, highjacks Date.parse + var gapDuration = (new Date().getTime()) + (nextEventStartTime.getTime() - endTime); + var x = setInterval(function() { + var now = new Date().getTime(); + var remainder = new Date(Math.round(gapDuration - now)).toISOString().substr(11,8);; + $j("#replayAllCountDown").html(remainder + " to next event."); + if (remainder < 0) { + clearInterval(x); + streamNext( true ); + } + }, 1000); + break; + case 'gapless': + streamNext( true ); + break; + } + }); + }); +} + function setButtonState( element, butClass ) { if ( element ) { element.className = butClass; @@ -164,13 +195,23 @@ function streamFastRev( action ) { } function streamPrev( action ) { - if ( action ) + if ( action ) { + if ( vid ) { + location.replace(thisUrl + '?view=event&eid=' + prevEventId + filterQuery + sortQuery); + return; + } streamReq.send( streamParms+"&command="+CMD_PREV ); + } } function streamNext( action ) { - if ( action ) + if ( action ) { + if ( vid ) { + location.replace(thisUrl + '?view=event&eid=' + nextEventId + filterQuery + sortQuery); + return; + } streamReq.send( streamParms+"&command="+CMD_NEXT ); + } } function streamZoomIn( x, y ) { @@ -251,6 +292,8 @@ function eventQuery( eventId ) { var prevEventId = 0; var nextEventId = 0; +var prevEventStartTime = 0; +var nextEventStartTime = 0; var PrevEventDefVideoPath = ""; var NextEventDefVideoPath = ""; @@ -259,6 +302,8 @@ function getNearEventsResponse( respObj, respText ) { return; prevEventId = respObj.nearevents.PrevEventId; nextEventId = respObj.nearevents.NextEventId; + prevEventStartTime = Date.parse(respObj.nearevents.PrevEventStartTime); + nextEventStartTime = Date.parse(respObj.nearevents.NextEventStartTime); PrevEventDefVideoPath = respObj.nearevents.PrevEventDefVideoPath; NextEventDefVideoPath = respObj.nearevents.NextEventDefVideoPath; @@ -266,12 +311,14 @@ function getNearEventsResponse( respObj, respText ) { if ( prevEventBtn ) prevEventBtn.disabled = !prevEventId; var nextEventBtn = $('nextEventBtn'); if ( nextEventBtn ) nextEventBtn.disabled = !nextEventId; + if (prevEventId == 0) $j('#prevBtnVjs').prop('disabled', true).attr('class', 'unavail'); + if (nextEventId == 0) $j('#nextBtnVjs').prop('disabled', true).attr('class', 'unavail'); } var nearEventsReq = new Request.JSON( { url: thisUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getNearEventsResponse } ); function nearEventsQuery( eventId ) { - var parms = "view=request&request=status&entity=nearevents&id="+eventId; + var parms = "view=request&request=status&entity=nearevents&id="+eventId+filterQuery+sortQuery; nearEventsReq.send( parms ); } diff --git a/web/skins/classic/views/js/event.js.php b/web/skins/classic/views/js/event.js.php index f4a14f1fe..b8dbd8d94 100644 --- a/web/skins/classic/views/js/event.js.php +++ b/web/skins/classic/views/js/event.js.php @@ -33,8 +33,8 @@ var eventData = { Length: 'Length() ?>' }; -var filterQuery = ''; -var sortQuery = ''; +var filterQuery = ''; +var sortQuery = ''; var scale = ; var canEditEvents = ;