Merge pull request #40 from digital-gnome/AjaxNavigationAndResizing

Ajax navigation and resizing
This commit is contained in:
Isaac Connor 2017-10-22 22:44:30 -04:00 committed by GitHub
commit 7ccf06ec3e
10 changed files with 166 additions and 75 deletions

View File

@ -108,6 +108,7 @@ $statusData = array(
"elements" => array( "elements" => array(
"Id" => array( "sql" => "Events.Id" ), "Id" => array( "sql" => "Events.Id" ),
"MonitorId" => true, "MonitorId" => true,
"MonitorName" => array("sql" => "(SELECT Monitors.Name FROM Monitors WHERE Monitors.Id = Events.MonitorId)"),
"Name" => true, "Name" => true,
"Cause" => true, "Cause" => true,
"StartTime" => true, "StartTime" => true,

View File

@ -1,6 +1,10 @@
.vjsMessage { #content .vjsMessage {
font-size: 2em; width: 100%;
line-height: 1.5; position: absolute;
left: 0;
z-index: 10;
margin: 0;
font-size: 200%;
color: white; color: white;
background-color: black; background-color: black;
display: inline-block; display: inline-block;
@ -40,6 +44,7 @@ span.noneCue {
#eventVideo { #eventVideo {
display: inline-block; display: inline-block;
postion: relative;
} }
#menuBar1 { #menuBar1 {
@ -112,6 +117,8 @@ span.noneCue {
} }
#imageFeed { #imageFeed {
display: inline-block;
position: relative;
text-align: center; text-align: center;
} }

View File

@ -1,6 +1,10 @@
.vjsMessage { #content .vjsMessage {
font-size: 2em; width: 100%;
line-height: 1.5; position: absolute;
left: 0;
z-index: 10;
margin: 0;
font-size: 200%;
color: white; color: white;
background-color: black; background-color: black;
display: inline-block; display: inline-block;
@ -95,6 +99,8 @@ span.noneCue {
} }
#imageFeed { #imageFeed {
display: inline-block;
position: relative;
text-align: center; text-align: center;
} }
@ -255,7 +261,8 @@ span.noneCue {
} }
#eventVideo { #eventVideo {
display: inline-block; display: inline-block;
position: relative;
} }
#thumbsKnob { #thumbsKnob {

View File

@ -1,6 +1,10 @@
.vjsMessage { #content .vjsMessage {
font-size: 2em; width: 100%;
line-height: 1.5; position: absolute;
left: 0;
z-index: 10;
margin: 0;
font-size: 200%;
color: white; color: white;
background-color: black; background-color: black;
display: inline-block; display: inline-block;
@ -100,6 +104,8 @@ span.noneCue {
visibility: hidden; visibility: hidden;
} }
#imageFeed { #imageFeed {
display: inline-block;
position: relative;
text-align: center; text-align: center;
} }
@ -272,6 +278,7 @@ span.noneCue {
} }
#eventVideo { #eventVideo {
display: inline-block; display: inline-block;
position: relative;
} }
#video-controls { #video-controls {

View File

@ -31,6 +31,7 @@ $rates = array(
); );
$scales = array( $scales = array(
'auto' => translate('Scale to Fit'),
'' => translate('Fixed Width/Height'), '' => translate('Fixed Width/Height'),
'400' => '4x', '400' => '4x',
'300' => '3x', '300' => '3x',
@ -44,6 +45,8 @@ $scales = array(
'12.5' => '1/8x', '12.5' => '1/8x',
); );
if (isset($_REQUEST['view'])) unset($scales[$_REQUEST['view'] == 'event' ? '' : 'auto']); //Remove the option we aren't using on montage or event
$bandwidth_options = array( $bandwidth_options = array(
'high' => translate('High'), 'high' => translate('High'),
'medium' => translate('Medium'), 'medium' => translate('Medium'),

View File

@ -283,6 +283,17 @@ function convertLabelFormat(LabelFormat, monitorName){
} }
function addVideoTimingTrack(video, LabelFormat, monitorName, duration, startTime){ function addVideoTimingTrack(video, LabelFormat, monitorName, duration, startTime){
//This is a hacky way to handle changing the texttrack. If we ever upgrade vjs in a revamp replace this. Old method preserved because it's the right way.
let cues = vid.textTracks()[0].cues();
let labelFormat = convertLabelFormat(LabelFormat, monitorName);
startTime = moment(startTime);
for (let i = 0; i <= duration; i++) {
cues[i] = {id: i, index: i, startTime: i, Ca: i+1, text: startTime.format(labelFormat)};
startTime.add(1, 's');
}
}
/*
var labelFormat = convertLabelFormat(LabelFormat, monitorName); var labelFormat = convertLabelFormat(LabelFormat, monitorName);
var webvttformat = 'HH:mm:ss.SSS', webvttdata="WEBVTT\n\n"; var webvttformat = 'HH:mm:ss.SSS', webvttdata="WEBVTT\n\n";
@ -304,6 +315,7 @@ function addVideoTimingTrack(video, LabelFormat, monitorName, duration, startTim
track.src = 'data:plain/text;charset=utf-8,'+encodeURIComponent(webvttdata); track.src = 'data:plain/text;charset=utf-8,'+encodeURIComponent(webvttdata);
video.appendChild(track); video.appendChild(track);
} }
*/
function changeGroup( e, depth ) { function changeGroup( e, depth ) {
var group_id = $('group'+depth).get('value'); var group_id = $('group'+depth).get('value');

View File

@ -14,7 +14,7 @@
font-size: .3em; font-size: .3em;
} }
.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar.vjs-zm { .vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
visibility: visible; visibility: visible;
opacity: 1; opacity: 1;
bottom: -2em; bottom: -2em;

View File

@ -36,14 +36,17 @@ if ( $user['MonitorIds'] ) {
} }
$Monitor = $Event->Monitor(); $Monitor = $Event->Monitor();
if ( isset( $_REQUEST['rate'] ) ) if (isset($_REQUEST['rate'])) {
$rate = validInt($_REQUEST['rate']); $rate = validInt($_REQUEST['rate']);
else } else {
$rate = reScale( RATE_BASE, $Monitor->DefaultRate(), ZM_WEB_DEFAULT_RATE ); $rate = reScale(RATE_BASE, $Monitor->DefaultRate(), ZM_WEB_DEFAULT_RATE);
}
if ( isset( $_REQUEST['scale'] ) ) { if (isset($_REQUEST['scale'])) {
$scale = validInt($_REQUEST['scale']); $scale = validInt($_REQUEST['scale']);
} else if ( isset( $_COOKIE['zmEventScale'.$Event->MonitorId()] ) ) { } else if (isset($_COOKIE['zmEventScaleAuto'])) { //If we're using scale to fit use it on all monitors
$scale = 'auto';
} else if (isset($_COOKIE['zmEventScale'.$Event->MonitorId()])) {
$scale = $_COOKIE['zmEventScale'.$Event->MonitorId()]; $scale = $_COOKIE['zmEventScale'.$Event->MonitorId()];
} else { } else {
$scale = reScale( SCALE_BASE, $Monitor->DefaultScale(), ZM_WEB_DEFAULT_SCALE ); $scale = reScale( SCALE_BASE, $Monitor->DefaultScale(), ZM_WEB_DEFAULT_SCALE );
@ -153,20 +156,11 @@ if ( $Event->DefaultVideo() ) {
<div id="videoFeed"> <div id="videoFeed">
<video id="videoobj" class="video-js vjs-default-skin" width="<?php echo reScale( $Event->Width(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $scale ) ?>" data-setup='{ "controls": true, "playbackRates": [0.5, 1, 1.5, 2, 4, 8, 16, 32, 64, 128, 256], "autoplay": true, "preload": "auto", "plugins": { "zoomrotate": { "zoom": "<?php echo $Zoom ?>"}}}'> <video id="videoobj" class="video-js vjs-default-skin" width="<?php echo reScale( $Event->Width(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $scale ) ?>" data-setup='{ "controls": true, "playbackRates": [0.5, 1, 1.5, 2, 4, 8, 16, 32, 64, 128, 256], "autoplay": true, "preload": "auto", "plugins": { "zoomrotate": { "zoom": "<?php echo $Zoom ?>"}}}'>
<source src="<?php echo $Event->getStreamSrc( array( 'mode'=>'mpeg','format'=>'h264' ) ); ?>" type="video/mp4"> <source src="<?php echo $Event->getStreamSrc( array( 'mode'=>'mpeg','format'=>'h264' ) ); ?>" type="video/mp4">
<track id="monitorCaption" kind="captions" label="English" srclang="en" src='data:plain/text;charset=utf-8,"WEBVTT\n\n 00:00:00.000 --> 00:00:01.000 ZoneMinder"' default>
Your browser does not support the video tag. Your browser does not support the video tag.
</video> </video>
</div> </div>
<!--script>includeVideoJs();</script--> <!--script>includeVideoJs();</script-->
<script type="text/javascript">
var LabelFormat = "<?php echo validJsStr($Monitor->LabelFormat())?>";
var monitorName = "<?php echo validJsStr($Monitor->Name())?>";
var duration = <?php echo $Event->Length() ?>, startTime = '<?php echo $Event->StartTime() ?>';
addVideoTimingTrack(document.getElementById('videoobj'), LabelFormat, monitorName, duration, startTime);
nearEventsQuery( eventData.Id );
vjsReplay(<?php echo (strtotime($Event->StartTime()) + $Event->Length())*1000 ?>);
</script>
<p id="dvrControls" class="dvrControls"> <p id="dvrControls" class="dvrControls">
<input type="button" value="&lt;+" id="prevBtn" title="<?php echo translate('Prev') ?>" class="inactive" onclick="streamPrev( true );"/> <input type="button" value="&lt;+" id="prevBtn" title="<?php echo translate('Prev') ?>" class="inactive" onclick="streamPrev( true );"/>
@ -191,7 +185,7 @@ if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
} }
} // end if stream method } // end if stream method
?> ?>
<div id="alarmCueJpeg" class="alarmCue" style="width: <?php echo reScale($Event->Width(), $scale);?>px;"></div> <div id="alarmCue" class="alarmCue" style="width: <?php echo reScale($Event->Width(), $scale);?>px;"></div>
<div id="progressBar" style="width: <?php echo reScale($Event->Width(), $scale);?>px;"> <div id="progressBar" style="width: <?php echo reScale($Event->Width(), $scale);?>px;">
<div class="progressBox" id="progressBox" title="" style="width: 0%;"></div> <div class="progressBox" id="progressBox" title="" style="width: 0%;"></div>
</div><!--progressBar--> </div><!--progressBar-->

View File

@ -1,9 +1,10 @@
var vid = null; var vid = null;
function vjsReplay(endTime) { function vjsReplay() {
var video = videojs('videoobj').ready(function(){ vid.ready(function(){
var player = this; var player = this;
player.on('ended', function() { player.on('ended', function() {
var endTime = (Date.parse(eventData.EndTime)).getTime();
switch(replayMode.value) { switch(replayMode.value) {
case 'none': case 'none':
break; break;
@ -12,19 +13,23 @@ function vjsReplay(endTime) {
break; break;
case 'all': case 'all':
if (nextEventId == 0) { if (nextEventId == 0) {
$j("#videoobj").html('<p class="vjsMessage">No more events</p>'); let overLaid = $j("#videoobj");
overLaid.append('<p class="vjsMessage" style="height: '+overLaid.height()+'px; line-height: '+overLaid.height()+'px;">No more events</p>');
} else { } else {
var nextStartTime = nextEventStartTime.getTime(); //nextEventStartTime.getTime() is a mootools workaround, highjacks Date.parse var nextStartTime = nextEventStartTime.getTime(); //nextEventStartTime.getTime() is a mootools workaround, highjacks Date.parse
if (nextStartTime <= endTime) { if (nextStartTime <= endTime) {
streamNext( true ); streamNext( true );
return; return;
} }
$j("#videoobj").html('<p class="vjsMessage"></p>'); let overLaid = $j("#videoobj");
vid.pause();
overLaid.append('<p class="vjsMessage" style="height: '+overLaid.height()+'px; line-height: '+overLaid.height()+'px;"></p>');
var gapDuration = (new Date().getTime()) + (nextStartTime - endTime); var gapDuration = (new Date().getTime()) + (nextStartTime - endTime);
let messageP = $j(".vjsMessage");
var x = setInterval(function() { var x = setInterval(function() {
var now = new Date().getTime(); var now = new Date().getTime();
var remainder = new Date(Math.round(gapDuration - now)).toISOString().substr(11,8); var remainder = new Date(Math.round(gapDuration - now)).toISOString().substr(11,8);
$j(".vjsMessage").html(remainder + ' to next event.'); messageP.html(remainder + ' to next event.');
if (remainder < 0) { if (remainder < 0) {
clearInterval(x); clearInterval(x);
streamNext( true ); streamNext( true );
@ -48,20 +53,15 @@ function initialAlarmCues (eventId) {
$j.getJSON("api/events/"+eventId+".json", setAlarmCues); //get frames data for alarmCues and inserts into html $j.getJSON("api/events/"+eventId+".json", setAlarmCues); //get frames data for alarmCues and inserts into html
} }
function setAlarmCues (data) { function setAlarmCues (data) {
cueFrames = data.event.Frame; cueFrames = data.event.Frame;
alarmSpans = renderAlarmCues(); alarmSpans = renderAlarmCues();
if ( vid ) { $j(".alarmCue").html(alarmSpans);
$j(".vjs-progress-control").append('<div class="alarmCue">' + alarmSpans + '</div>');
$j(".vjs-control-bar").addClass("vjs-zm");
} else {
$j("#alarmCueJpeg").html(alarmSpans);
}
} }
function renderAlarmCues () { function renderAlarmCues () {
if (cueFrames) { if (cueFrames) {
var cueRatio = (vid ? $j("#videoobj").width() : $j("#evtStream").width()) / (cueFrames[cueFrames.length - 1].Delta * 100);//use videojs width or nph-zms width var cueRatio = (vid ? $j("#videoobj").width() : $j("#evtStream").width()) / (cueFrames[cueFrames.length - 1].Delta * 100);//use videojs width or zms width
var minAlarm = Math.ceil(1/cueRatio); var minAlarm = Math.ceil(1/cueRatio);
var spanTimeStart = 0; var spanTimeStart = 0;
var spanTimeEnd = 0; var spanTimeEnd = 0;
@ -118,6 +118,7 @@ function renderAlarmCues () {
spanTime = spanTimeEnd - spanTimeStart; spanTime = spanTimeEnd - spanTimeStart;
alarmed = 0; alarmed = 0;
pix = Math.round(cueRatio * spanTime); pix = Math.round(cueRatio * spanTime);
if (pixSkew >= .5 || pixSkew <= -.5) pix += Math.round(pixSkew);
alarmHtml += '<span class="alarmCue" style="width: ' + pix + 'px;"></span>'; alarmHtml += '<span class="alarmCue" style="width: ' + pix + 'px;"></span>';
} }
} }
@ -134,27 +135,54 @@ function setButtonState( element, butClass ) {
} }
} }
var resizeTimer;
function endOfResize(e) {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(changeScale, 250);
}
function scaleToFit () {
$j(window).on('resize', endOfResize) //set delayed scaling when Scale to Fit is selected
let ratio = eventData.Width/eventData.Height;
let container = $j('#content');
let feed = $j(vid ? '#videoobj' : '#evtStream');
let viewPort = $j(window);
let newHeight = viewPort.height() - (container.outerHeight(true) - feed.outerHeight(true));
let newWidth = ratio * newHeight;
if (newWidth > container.innerWidth()) {
newWidth = container.innerWidth();
newHeight = newWidth / ratio;
}
return {width: Math.floor(newWidth), height: Math.floor(newHeight)};
}
function changeScale() { function changeScale() {
var scale = $('scale').get('value'); let scale = $j('#scale').val();
var baseWidth = eventData.Width; if (scale == "auto") {
var baseHeight = eventData.Height; let newSize = scaleToFit();
var newWidth = ( baseWidth * scale ) / SCALE_BASE; var newWidth = newSize.width;
var newHeight = ( baseHeight * scale ) / SCALE_BASE; var newHeight = newSize.height;
if ( vid ) {
// Using video.js
$j("#videoobj").width(newWidth);
$j("#videoobj").height(newHeight);
$j("div.alarmCue").html(renderAlarmCues());//just re-render alarmCues. skip ajax call
Cookie.write( 'zmEventScale'+eventData.MonitorId, scale, { duration: 10*365 } );
} else { } else {
streamScale( scale ); $j(window).off('resize', endOfResize); //remove resize handler when Scale to Fit is not active
var streamImg = document.getElementById('evtStream'); var newWidth = eventData.Width * scale / SCALE_BASE;
streamImg.style.width = newWidth + "px"; var newHeight = eventData.Height * scale / SCALE_BASE;
streamImg.style.height = newHeight + "px"; }
$j("#alarmCueJpeg").width(newWidth); let alarmCue = $j('div.alarmCue');
let eventViewer = $j(vid ? '#videoobj' : '#evtStream')
eventViewer.width(newWidth);
eventViewer.height(newHeight);
if ( !vid ) { // zms needs extra sizing
streamScale(scale == "auto" ? Math.round(newWidth / eventData.Width * SCALE_BASE) : scale);
alarmCue.width(newWidth);
drawProgressBar(); drawProgressBar();
$j("#alarmCueJpeg").html(renderAlarmCues()); }
Cookie.write( 'zmEventScale'+eventData.MonitorId, scale, { duration: 10*365 } ); alarmCue.html(renderAlarmCues());//just re-render alarmCues. skip ajax call
if (scale == "auto") {
Cookie.write('zmEventScaleAuto', 'auto', {duration: 10*365});
}else{
Cookie.write('zmEventScale'+eventData.MonitorId, scale, {duration: 10*365});
Cookie.dispose('zmEventScaleAuto');
} }
} }
@ -176,7 +204,7 @@ var zmsBroke = false; //Use alternate navigation if zms has crashed
function getCmdResponse( respObj, respText ) { function getCmdResponse( respObj, respText ) {
if ( checkStreamForErrors( "getCmdResponse", respObj ) ) { if ( checkStreamForErrors( "getCmdResponse", respObj ) ) {
console.log('Got an error from getCmdResponse'); console.log('Got an error from getCmdResponse');
var zmsBroke = true; zmsBroke = true;
return; return;
} }
@ -301,7 +329,11 @@ function streamFastRev( action ) {
function streamPrev(action) { function streamPrev(action) {
if (action) { if (action) {
if (vid || PrevEventDefVideoPath.indexOf("view_video") >=0 || $j("#vjsMessage").length || zmsBroke) { //handles this or prev being video.js, or end of events $j(".vjsMessage").remove();
if (vid && PrevEventDefVideoPath.indexOf("view_video") > 0) {
CurEventDefVideoPath = PrevEventDefVideoPath;
eventQuery(prevEventId);
} else if (zmsBroke || (vid && PrevEventDefVideoPath.indexOf("view_video") < 0) || $j("#vjsMessage").length || PrevEventDefVideoPath.indexOf("view_video") > 0) {//zms broke, leaving videojs, last event, moving to videojs
location.replace(thisUrl + '?view=event&eid=' + prevEventId + filterQuery + sortQuery); location.replace(thisUrl + '?view=event&eid=' + prevEventId + filterQuery + sortQuery);
} else { } else {
streamReq.send(streamParms+"&command="+CMD_PREV); streamReq.send(streamParms+"&command="+CMD_PREV);
@ -311,13 +343,22 @@ function streamPrev(action) {
function streamNext(action) { function streamNext(action) {
if (action) { if (action) {
$j(".vjsMessage").remove();//This shouldn't happen
if (nextEventId == 0) { //handles deleting last event. if (nextEventId == 0) { //handles deleting last event.
let replaceStream = $j(vid ? "#videoobj" : "#evtStream"); vid ? vid.pause() : streamPause();
replaceStream.replaceWith('<p class="vjsMessage" style="width:' + replaceStream.css("width") + '; height: ' + replaceStream.css("height") + ';line-height: ' + replaceStream.css("height") + ';">No more events</p>'); let hideContainer = $j( vid ? "#eventVideo" : "#imageFeed");
} else if (vid || NextEventDefVideoPath.indexOf("view_video") >=0 || zmsBroke) { //handles current or next switch to video.js let hideStream = $j(vid ? "#videoobj" : "#evtStream").height() + (vid ? 0 :$j("#progressBar").height());
hideContainer.prepend('<p class="vjsMessage" style="height: ' + hideStream + 'px; line-height: ' + hideStream + 'px;">No more events</p>');
if (vid == null) zmsBroke = true;
return;
}
if (vid && NextEventDefVideoPath.indexOf("view_video") > 0) { //on and staying with videojs
CurEventDefVideoPath = NextEventDefVideoPath;
eventQuery(nextEventId);
} else if (zmsBroke || (vid && NextEventDefVideoPath.indexOf("view_video") < 0) || NextEventDefVideoPath.indexOf("view_video") > 0) {//reload zms, leaving vjs, moving to vjs
location.replace(thisUrl + '?view=event&eid=' + nextEventId + filterQuery + sortQuery); location.replace(thisUrl + '?view=event&eid=' + nextEventId + filterQuery + sortQuery);
} else { } else {
streamReq.send( streamParms+"&command="+CMD_NEXT ); streamReq.send(streamParms+"&command="+CMD_NEXT);
} }
} }
} }
@ -348,6 +389,7 @@ function streamQuery() {
var slider = null; var slider = null;
var scroll = null; var scroll = null;
var CurEventDefVideoPath = null;
function getEventResponse( respObj, respText ) { function getEventResponse( respObj, respText ) {
if ( checkStreamForErrors( "getEventResponse", respObj ) ) { if ( checkStreamForErrors( "getEventResponse", respObj ) ) {
@ -374,7 +416,7 @@ function getEventResponse( respObj, respText ) {
$('dataFrames').set( 'text', eventData.Frames+"/"+eventData.AlarmFrames ); $('dataFrames').set( 'text', eventData.Frames+"/"+eventData.AlarmFrames );
$('dataScore').set( 'text', eventData.TotScore+"/"+eventData.AvgScore+"/"+eventData.MaxScore ); $('dataScore').set( 'text', eventData.TotScore+"/"+eventData.AvgScore+"/"+eventData.MaxScore );
$('eventName').setProperty( 'value', eventData.Name ); $('eventName').setProperty( 'value', eventData.Name );
history.replaceState(null, null, '?view=event&eid=' + eventData.Id + filterQuery + sortQuery);//if popup removed, check if this allows forward
if ( canEditEvents ) { if ( canEditEvents ) {
if ( parseInt(eventData.Archived) ) { if ( parseInt(eventData.Archived) ) {
$('archiveEvent').addClass( 'hidden' ); $('archiveEvent').addClass( 'hidden' );
@ -387,7 +429,14 @@ function getEventResponse( respObj, respText ) {
// Technically, events can be different sizes, so may need to update the size of the image, but it might be better to have it stay scaled... // Technically, events can be different sizes, so may need to update the size of the image, but it might be better to have it stay scaled...
//var eventImg = $('eventImage'); //var eventImg = $('eventImage');
//eventImg.setStyles( { 'width': eventData.width, 'height': eventData.height } ); //eventImg.setStyles( { 'width': eventData.width, 'height': eventData.height } );
drawProgressBar(); if (vid && CurEventDefVideoPath) {
vid.src({type: 'video/mp4', src: CurEventDefVideoPath}); //Currently mp4 is all we use
initialAlarmCues(eventData.Id);//ajax and render, new event
addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartTime);
CurEventDefVideoPath = null;
} else {
drawProgressBar();
}
nearEventsQuery( eventData.Id ); nearEventsQuery( eventData.Id );
} }
@ -693,6 +742,7 @@ function getActResponse( respObj, respText ) {
return; return;
if ( respObj.refreshParent ) if ( respObj.refreshParent )
if (refreshParent == false) refreshParent = true; //Bypass filter window redirect fix.
refreshParentWindow(); refreshParentWindow();
if ( respObj.refreshEvent ) if ( respObj.refreshEvent )
@ -793,7 +843,7 @@ function videoEvent() {
// Called on each event load because each event can be a different width // Called on each event load because each event can be a different width
function drawProgressBar() { function drawProgressBar() {
var barWidth = (eventData.Width * $j('#scale').val()) / SCALE_BASE; let barWidth = $j('#evtStream').width();
$j('#progressBar').css( 'width', barWidth ); $j('#progressBar').css( 'width', barWidth );
} }
@ -807,7 +857,7 @@ function updateProgressBar() {
} // end function updateProgressBar() } // end function updateProgressBar()
// Handles seeking when clicking on the progress bar. // Handles seeking when clicking on the progress bar.
function progressBarSeek (){ function progressBarNav (){
$j('#progressBar').click(function(e){ $j('#progressBar').click(function(e){
var x = e.pageX - $j(this).offset().left; var x = e.pageX - $j(this).offset().left;
var seekTime = (x / $j('#progressBar').width()) * parseFloat(eventData.Length); var seekTime = (x / $j('#progressBar').width()) * parseFloat(eventData.Length);
@ -924,11 +974,15 @@ function setupListener() {
function initPage() { function initPage() {
//FIXME prevent blocking...not sure what is happening or best way to unblock //FIXME prevent blocking...not sure what is happening or best way to unblock
if ( $('videoobj') ) { if ($j('#videoobj').length) {
vid = videojs("videoobj"); vid = videojs("videoobj");
initialAlarmCues(eventData.Id); //call ajax+renderAlarmCues after videojs is. should be only call to initialAlarmCues on vjs streams addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartTime);
$j(".vjs-progress-control").append('<div class="alarmCue"></div>');//add a place for videojs only on first load
nearEventsQuery(eventData.Id);
initialAlarmCues(eventData.Id); //call ajax+renderAlarmCues after videojs is initialized
vjsReplay();
} }
if ( vid ) { if (vid) {
/* /*
setupListener(); setupListener();
vid.removeAttribute("controls"); vid.removeAttribute("controls");
@ -947,10 +1001,10 @@ function initPage() {
window.videoobj.load(); window.videoobj.load();
streamPlay(); */ streamPlay(); */
} else { } else {
progressBarSeek (); progressBarNav ();
streamCmdTimer = streamQuery.delay( 250 ); streamCmdTimer = streamQuery.delay( 250 );
eventQuery.pass( eventData.Id ).delay( 500 ); eventQuery.pass( eventData.Id ).delay( 500 );
initialAlarmCues(eventData.Id); //call ajax+renderAlarmCues for nph-zms. initialAlarmCues(eventData.Id); //call ajax+renderAlarmCues for zms.
if ( canStreamNative ) { if ( canStreamNative ) {
var streamImg = $('imageFeed').getElement('img'); var streamImg = $('imageFeed').getElement('img');
@ -959,6 +1013,7 @@ function initPage() {
$(streamImg).addEvent( 'click', function( event ) { handleClick( event ); } ); $(streamImg).addEvent( 'click', function( event ) { handleClick( event ); } );
} }
} }
if (scale == "auto") changeScale();
} }
// Kick everything off // Kick everything off

View File

@ -30,13 +30,18 @@ var eventData = {
MonitorId: '<?php echo $Event->MonitorId() ?>', MonitorId: '<?php echo $Event->MonitorId() ?>',
Width: '<?php echo $Event->Width() ?>', Width: '<?php echo $Event->Width() ?>',
Height: '<?php echo $Event->Height() ?>', Height: '<?php echo $Event->Height() ?>',
Length: '<?php echo $Event->Length() ?>' Length: '<?php echo $Event->Length() ?>',
StartTime: '<?php echo $Event->StartTime() ?>',
EndTime: '<?php echo $Event->EndTime() ?>',
MonitorName: '<?php echo $Monitor->Name() ?>'
}; };
var filterQuery = '<?php echo isset($filterQuery)?validJsStr(htmlspecialchars_decode($filterQuery)):'' ?>'; var filterQuery = '<?php echo isset($filterQuery)?validJsStr(htmlspecialchars_decode($filterQuery)):'' ?>';
var sortQuery = '<?php echo isset($sortQuery)?validJsStr(htmlspecialchars_decode($sortQuery)):'' ?>'; var sortQuery = '<?php echo isset($sortQuery)?validJsStr(htmlspecialchars_decode($sortQuery)):'' ?>';
var scale = <?php echo $scale ?>; var scale = "<?php echo $scale ?>";
var LabelFormat = "<?php echo validJsStr($Monitor->LabelFormat())?>";
var canEditEvents = <?php echo canEdit( 'Events' )?'true':'false' ?>; var canEditEvents = <?php echo canEdit( 'Events' )?'true':'false' ?>;
var streamTimeout = <?php echo 1000*ZM_WEB_REFRESH_STATUS ?>; var streamTimeout = <?php echo 1000*ZM_WEB_REFRESH_STATUS ?>;