zoneminder/web/skins/classic/views/js/watch.js

641 lines
22 KiB
JavaScript
Raw Normal View History

2017-05-19 01:50:56 +08:00
function setButtonState( element, butClass ) {
element.className = butClass;
element.disabled = (butClass != 'inactive');
}
2016-04-05 02:58:07 +08:00
2017-05-19 01:50:56 +08:00
function showEvents() {
$('ptzControls').addClass( 'hidden' );
$('events').removeClass( 'hidden' );
if ( $('eventsControl') )
$('eventsControl').addClass('hidden');
if ( $('controlControl') )
$('controlControl').removeClass('hidden');
showMode = "events";
}
function showPtzControls() {
$('events').addClass( 'hidden' );
$('ptzControls').removeClass( 'hidden' );
if ( $('eventsControl') )
$('eventsControl').removeClass('hidden');
if ( $('controlControl') )
$('controlControl').addClass('hidden');
showMode = "control";
}
function changeScale() {
var scale = $('scale').get('value');
Add h264 event view functionality and new feature alarmCues (#2012) * Fix nearEventsQuery Removed dbEscape from getNearEvents previous event because it only returns 0. Now matches next. Changed getEventDefaultVideoPath function to return a web path rather than the absolute path based on ic0ns branch. Also added start times to allow for videoJS replaymode. * Unescape filters Filters need to be unescaped * Add initial values to page load * Add replay modes to videojs * rough in figuring out a frame in between bulk frames * Add alarmCues Add a graphical indication of where alarm frames happened in an event. Similar to what zmNinja shows. * Add remaining buttons to videojs Functionality for all buttons on videojs streams. FF/RW buttons show as active when they are active. * Whitespace and fix Bulkframe calcs * Fix zms events trying to generate with mp4 code ZMS events would attempt to generate frames as though they were an mp4/passthrough type because the full eventpath wasn't passed * ZMS scrub bar Move zms scrub bar to bottom of image feed. Make it simpler and more like videojs style. * Wrap event feeds properly * Fix dvrControls on watch view * Add scaleToFit Add a scaleToFit option to event view * Add navigation for videoJS streams Disables nav buttons at beginning and end of events. Handles switching from zms to videojs. If zms crashes changes next event function to reload page instead of ajax. * Add scaleToFit to watch and frame view Adds scaleToFit to watch view. Since frame view uses the watch cookie this required changes to frame view * Add transition to zoom * Change stills view to match stream Move stills slider bar to match scrub bar on streams. Allow it to resize, make it larger. Add alarmcues. * Add Stills for every event Add stills for every event. Match size to stream size * Progressbox transitions
2017-12-05 10:26:59 +08:00
var newWidth;
var newHeight;
if (scale == "auto") {
let newSize = scaleToFit(monitorWidth, monitorHeight, $j('#liveStream'+monitorId), $j('#replayStatus'));
newWidth = newSize.width;
newHeight = newSize.height;
autoScale = newSize.autoScale;
} else {
$j(window).off('resize', endOfResize); //remove resize handler when Scale to Fit is not active
newWidth = monitorWidth * scale / SCALE_BASE;
newHeight = monitorHeight * scale / SCALE_BASE;
}
2017-05-19 01:50:56 +08:00
Cookie.write( 'zmWatchScale'+monitorId, scale, { duration: 10*365 } );
/*Stream could be an applet so can't use moo tools*/
Add h264 event view functionality and new feature alarmCues (#2012) * Fix nearEventsQuery Removed dbEscape from getNearEvents previous event because it only returns 0. Now matches next. Changed getEventDefaultVideoPath function to return a web path rather than the absolute path based on ic0ns branch. Also added start times to allow for videoJS replaymode. * Unescape filters Filters need to be unescaped * Add initial values to page load * Add replay modes to videojs * rough in figuring out a frame in between bulk frames * Add alarmCues Add a graphical indication of where alarm frames happened in an event. Similar to what zmNinja shows. * Add remaining buttons to videojs Functionality for all buttons on videojs streams. FF/RW buttons show as active when they are active. * Whitespace and fix Bulkframe calcs * Fix zms events trying to generate with mp4 code ZMS events would attempt to generate frames as though they were an mp4/passthrough type because the full eventpath wasn't passed * ZMS scrub bar Move zms scrub bar to bottom of image feed. Make it simpler and more like videojs style. * Wrap event feeds properly * Fix dvrControls on watch view * Add scaleToFit Add a scaleToFit option to event view * Add navigation for videoJS streams Disables nav buttons at beginning and end of events. Handles switching from zms to videojs. If zms crashes changes next event function to reload page instead of ajax. * Add scaleToFit to watch and frame view Adds scaleToFit to watch view. Since frame view uses the watch cookie this required changes to frame view * Add transition to zoom * Change stills view to match stream Move stills slider bar to match scrub bar on streams. Allow it to resize, make it larger. Add alarmcues. * Add Stills for every event Add stills for every event. Match size to stream size * Progressbox transitions
2017-12-05 10:26:59 +08:00
var streamImg = $('liveStream'+monitorId);
2017-05-19 01:50:56 +08:00
if ( streamImg ) {
streamImg.style.width = newWidth + "px";
streamImg.style.height = newHeight + "px";
Add h264 event view functionality and new feature alarmCues (#2012) * Fix nearEventsQuery Removed dbEscape from getNearEvents previous event because it only returns 0. Now matches next. Changed getEventDefaultVideoPath function to return a web path rather than the absolute path based on ic0ns branch. Also added start times to allow for videoJS replaymode. * Unescape filters Filters need to be unescaped * Add initial values to page load * Add replay modes to videojs * rough in figuring out a frame in between bulk frames * Add alarmCues Add a graphical indication of where alarm frames happened in an event. Similar to what zmNinja shows. * Add remaining buttons to videojs Functionality for all buttons on videojs streams. FF/RW buttons show as active when they are active. * Whitespace and fix Bulkframe calcs * Fix zms events trying to generate with mp4 code ZMS events would attempt to generate frames as though they were an mp4/passthrough type because the full eventpath wasn't passed * ZMS scrub bar Move zms scrub bar to bottom of image feed. Make it simpler and more like videojs style. * Wrap event feeds properly * Fix dvrControls on watch view * Add scaleToFit Add a scaleToFit option to event view * Add navigation for videoJS streams Disables nav buttons at beginning and end of events. Handles switching from zms to videojs. If zms crashes changes next event function to reload page instead of ajax. * Add scaleToFit to watch and frame view Adds scaleToFit to watch view. Since frame view uses the watch cookie this required changes to frame view * Add transition to zoom * Change stills view to match stream Move stills slider bar to match scrub bar on streams. Allow it to resize, make it larger. Add alarmcues. * Add Stills for every event Add stills for every event. Match size to stream size * Progressbox transitions
2017-12-05 10:26:59 +08:00
streamImg.src = streamImg.src.replace(/scale=\d+/i, 'scale='+(scale== 'auto' ? autoScale : scale));
2017-05-19 01:50:56 +08:00
} else {
console.error("No element found for liveStream.");
}
}
var alarmState = STATE_IDLE;
var lastAlarmState = STATE_IDLE;
2017-05-19 01:50:56 +08:00
function setAlarmState( currentAlarmState ) {
alarmState = currentAlarmState;
var stateString = "Unknown";
var stateClass = "";
if ( alarmState == STATE_ALARM )
stateClass = "alarm";
else if ( alarmState == STATE_ALERT )
stateClass = "alert";
$('stateValue').set( 'text', stateStrings[alarmState] );
if ( stateClass )
$('stateValue').setProperty( 'class', stateClass );
else
$('stateValue').removeProperty( 'class' );
var isAlarmed = ( alarmState == STATE_ALARM || alarmState == STATE_ALERT );
var wasAlarmed = ( lastAlarmState == STATE_ALARM || lastAlarmState == STATE_ALERT );
var newAlarm = ( isAlarmed && !wasAlarmed );
var oldAlarm = ( !isAlarmed && wasAlarmed );
if ( newAlarm ) {
if ( SOUND_ON_ALARM ) {
// Enable the alarm sound
if ( !canPlayPauseAudio )
$('alarmSound').removeClass( 'hidden' );
else
$('MediaPlayer').Play();
}
2017-05-19 01:50:56 +08:00
if ( POPUP_ON_ALARM ) {
window.focus();
}
2017-05-19 01:50:56 +08:00
}
if ( SOUND_ON_ALARM ) {
if ( oldAlarm ) {
// Disable alarm sound
if ( !canPlayPauseAudio )
$('alarmSound').addClass( 'hidden' );
else
$('MediaPlayer').Stop();
}
}
if ( oldAlarm) //done with an event do a refresh
eventCmdQuery();
2017-05-19 01:50:56 +08:00
lastAlarmState = alarmState;
}
var streamCmdParms = "view=request&request=stream&connkey="+connKey;
var streamCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStreamCmdResponse } );
var streamCmdTimer = null;
var streamStatus;
2017-05-19 01:50:56 +08:00
function getStreamCmdResponse( respObj, respText ) {
watchdogOk("stream");
if ( streamCmdTimer )
streamCmdTimer = clearTimeout( streamCmdTimer );
2017-05-19 01:50:56 +08:00
if ( respObj.result == 'Ok' ) {
streamStatus = respObj.status;
$('fpsValue').set( 'text', streamStatus.fps );
2017-05-19 01:50:56 +08:00
setAlarmState( streamStatus.state );
2017-05-19 01:50:56 +08:00
$('levelValue').set( 'text', streamStatus.level );
if ( streamStatus.level > 95 )
$('levelValue').className = "alarm";
else if ( streamStatus.level > 80 )
$('levelValue').className = "alert";
else
$('levelValue').className = "ok";
var delayString = secsToTime( streamStatus.delay );
if ( streamStatus.paused == true ) {
$('modeValue').set( 'text', "Paused" );
$('rate').addClass( 'hidden' );
$('delayValue').set( 'text', delayString );
$('delay').removeClass( 'hidden' );
$('level').removeClass( 'hidden' );
streamCmdPause( false );
} else if ( streamStatus.delayed == true ) {
$('modeValue').set( 'text', "Replay" );
$('rateValue').set( 'text', streamStatus.rate );
$('rate').removeClass( 'hidden' );
$('delayValue').set( 'text', delayString );
$('delay').removeClass( 'hidden' );
$('level').removeClass( 'hidden' );
if ( streamStatus.rate == 1 ) {
streamCmdPlay( false );
} else if ( streamStatus.rate > 0 ) {
if ( streamStatus.rate < 1 )
streamCmdSlowFwd( false );
else
2017-05-19 01:50:56 +08:00
streamCmdFastFwd( false );
} else {
if ( streamStatus.rate > -1 )
streamCmdSlowRev( false );
else
2017-05-19 01:50:56 +08:00
streamCmdFastRev( false );
} // rate
2017-05-19 01:50:56 +08:00
} else {
$('modeValue').set( 'text', "Live" );
$('rate').addClass( 'hidden' );
$('delay').addClass( 'hidden' );
$('level').addClass( 'hidden' );
streamCmdPlay( false );
} // end if paused or delayed
2017-05-19 01:50:56 +08:00
$('zoomValue').set( 'text', streamStatus.zoom );
if ( streamStatus.zoom == "1.0" )
setButtonState( $('zoomOutBtn'), 'unavail' );
else
setButtonState( $('zoomOutBtn'), 'inactive' );
if ( canEditMonitors ) {
if ( streamStatus.enabled ) {
$('enableAlarmsLink').addClass( 'hidden' );
$('disableAlarmsLink').removeClass( 'hidden' );
if ( streamStatus.forced ) {
$('forceAlarmLink').addClass( 'hidden' );
$('cancelAlarmLink').removeClass( 'hidden' );
} else {
$('forceAlarmLink').removeClass( 'hidden' );
$('cancelAlarmLink').addClass( 'hidden' );
}
$('forceCancelAlarm').removeClass( 'hidden' );
} else {
$('enableAlarmsLink').removeClass( 'hidden' );
$('disableAlarmsLink').addClass( 'hidden' );
$('forceCancelAlarm').addClass( 'hidden' );
}
$('enableDisableAlarms').removeClass( 'hidden' );
}
2017-05-19 01:50:56 +08:00
} else {
checkStreamForErrors("getStreamCmdResponse", respObj);//log them
// Try to reload the image stream.
var streamImg = document.getElementById('liveStream');
if ( streamImg )
streamImg.src = streamImg.src.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) ));
}
var streamCmdTimeout = statusRefreshTimeout;
if ( alarmState == STATE_ALARM || alarmState == STATE_ALERT )
streamCmdTimeout = streamCmdTimeout/5;
streamCmdTimer = streamCmdQuery.delay( streamCmdTimeout );
}
function streamCmdPause( action ) {
setButtonState( $('pauseBtn'), 'active' );
setButtonState( $('playBtn'), 'inactive' );
setButtonState( $('stopBtn'), 'inactive' );
setButtonState( $('fastFwdBtn'), 'inactive' );
setButtonState( $('slowFwdBtn'), 'inactive' );
setButtonState( $('slowRevBtn'), 'inactive' );
setButtonState( $('fastRevBtn'), 'inactive' );
if ( action )
streamCmdReq.send( streamCmdParms+"&command="+CMD_PAUSE );
}
function streamCmdPlay( action ) {
setButtonState( $('pauseBtn'), 'inactive' );
setButtonState( $('playBtn'), 'active' );
if ( streamStatus.delayed == true ) {
setButtonState( $('stopBtn'), 'inactive' );
setButtonState( $('fastFwdBtn'), 'inactive' );
setButtonState( $('slowFwdBtn'), 'inactive' );
setButtonState( $('slowRevBtn'), 'inactive' );
setButtonState( $('fastRevBtn'), 'inactive' );
2017-05-19 01:50:56 +08:00
} else {
setButtonState( $('stopBtn'), 'unavail' );
setButtonState( $('fastFwdBtn'), 'unavail' );
setButtonState( $('slowFwdBtn'), 'unavail' );
setButtonState( $('slowRevBtn'), 'unavail' );
setButtonState( $('fastRevBtn'), 'unavail' );
2017-05-19 01:50:56 +08:00
}
if ( action )
streamCmdReq.send( streamCmdParms+"&command="+CMD_PLAY );
}
2017-05-19 01:50:56 +08:00
function streamCmdStop( action ) {
setButtonState( $('pauseBtn'), 'inactive' );
setButtonState( $('playBtn'), 'unavail' );
setButtonState( $('stopBtn'), 'active' );
setButtonState( $('fastFwdBtn'), 'unavail' );
setButtonState( $('slowFwdBtn'), 'unavail' );
setButtonState( $('slowRevBtn'), 'unavail' );
setButtonState( $('fastRevBtn'), 'unavail' );
if ( action )
streamCmdReq.send( streamCmdParms+"&command="+CMD_STOP );
setButtonState( $('stopBtn'), 'unavail' );
setButtonState( $('playBtn'), 'active' );
}
2017-05-19 01:50:56 +08:00
function streamCmdFastFwd( action ) {
setButtonState( $('pauseBtn'), 'inactive' );
setButtonState( $('playBtn'), 'inactive' );
setButtonState( $('stopBtn'), 'inactive' );
setButtonState( $('fastFwdBtn'), 'inactive' );
setButtonState( $('slowFwdBtn'), 'inactive' );
setButtonState( $('slowRevBtn'), 'inactive' );
setButtonState( $('fastRevBtn'), 'inactive' );
if ( action )
streamCmdReq.send( streamCmdParms+"&command="+CMD_FASTFWD );
}
2017-05-19 01:50:56 +08:00
function streamCmdSlowFwd( action ) {
setButtonState( $('pauseBtn'), 'inactive' );
setButtonState( $('playBtn'), 'inactive' );
setButtonState( $('stopBtn'), 'inactive' );
setButtonState( $('fastFwdBtn'), 'inactive' );
setButtonState( $('slowFwdBtn'), 'active' );
setButtonState( $('slowRevBtn'), 'inactive' );
setButtonState( $('fastRevBtn'), 'inactive' );
if ( action )
streamCmdReq.send( streamCmdParms+"&command="+CMD_SLOWFWD );
setButtonState( $('pauseBtn'), 'active' );
setButtonState( $('slowFwdBtn'), 'inactive' );
}
2017-05-19 01:50:56 +08:00
function streamCmdSlowRev( action ) {
setButtonState( $('pauseBtn'), 'inactive' );
setButtonState( $('playBtn'), 'inactive' );
setButtonState( $('stopBtn'), 'inactive' );
setButtonState( $('fastFwdBtn'), 'inactive' );
setButtonState( $('slowFwdBtn'), 'inactive' );
setButtonState( $('slowRevBtn'), 'active' );
setButtonState( $('fastRevBtn'), 'inactive' );
if ( action )
streamCmdReq.send( streamCmdParms+"&command="+CMD_SLOWREV );
setButtonState( $('pauseBtn'), 'active' );
setButtonState( $('slowRevBtn'), 'inactive' );
}
function streamCmdFastRev( action ) {
setButtonState( $('pauseBtn'), 'inactive' );
setButtonState( $('playBtn'), 'inactive' );
setButtonState( $('stopBtn'), 'inactive' );
setButtonState( $('fastFwdBtn'), 'inactive' );
setButtonState( $('slowFwdBtn'), 'inactive' );
setButtonState( $('slowRevBtn'), 'inactive' );
setButtonState( $('fastRevBtn'), 'inactive' );
if ( action )
streamCmdReq.send( streamCmdParms+"&command="+CMD_FASTREV );
}
2017-05-19 01:50:56 +08:00
function streamCmdZoomIn( x, y ) {
streamCmdReq.send( streamCmdParms+"&command="+CMD_ZOOMIN+"&x="+x+"&y="+y );
}
2017-05-19 01:50:56 +08:00
function streamCmdZoomOut() {
streamCmdReq.send( streamCmdParms+"&command="+CMD_ZOOMOUT );
}
2017-05-19 01:50:56 +08:00
function streamCmdScale( scale ) {
streamCmdReq.send( streamCmdParms+"&command="+CMD_SCALE+"&scale="+scale );
}
2017-05-19 01:50:56 +08:00
function streamCmdPan( x, y ) {
streamCmdReq.send( streamCmdParms+"&command="+CMD_PAN+"&x="+x+"&y="+y );
}
2017-05-19 01:50:56 +08:00
function streamCmdQuery() {
streamCmdReq.send( streamCmdParms+"&command="+CMD_QUERY );
}
var statusCmdParms = "view=request&request=status&entity=monitor&id="+monitorId+"&element[]=Status&element[]=FrameRate";
var statusCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'post', data: statusCmdParms, timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStatusCmdResponse } );
var statusCmdTimer = null;
2017-05-19 01:50:56 +08:00
function getStatusCmdResponse( respObj, respText ) {
watchdogOk("status");
if ( statusCmdTimer )
statusCmdTimer = clearTimeout( statusCmdTimer );
2017-05-19 01:50:56 +08:00
if ( respObj.result == 'Ok' ) {
$('fpsValue').set( 'text', respObj.monitor.FrameRate );
setAlarmState( respObj.monitor.Status );
} else
checkStreamForErrors("getStatusCmdResponse", respObj);
2017-05-19 01:50:56 +08:00
var statusCmdTimeout = statusRefreshTimeout;
if ( alarmState == STATE_ALARM || alarmState == STATE_ALERT )
statusCmdTimeout = statusCmdTimeout/5;
statusCmdTimer = statusCmdQuery.delay( statusCmdTimeout );
}
2017-05-19 01:50:56 +08:00
function statusCmdQuery() {
statusCmdReq.send();
}
var alarmCmdParms = "view=request&request=alarm&id="+monitorId;
var alarmCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getAlarmCmdResponse, onTimeout: streamCmdQuery } );
var alarmCmdFirst = true;
2017-05-19 01:50:56 +08:00
function getAlarmCmdResponse( respObj, respText ) {
checkStreamForErrors("getAlarmCmdResponse", respObj);
}
2017-05-19 01:50:56 +08:00
function cmdDisableAlarms() {
alarmCmdReq.send( alarmCmdParms+"&command=disableAlarms" );
}
2017-05-19 01:50:56 +08:00
function cmdEnableAlarms() {
alarmCmdReq.send( alarmCmdParms+"&command=enableAlarms" );
}
2017-05-19 01:50:56 +08:00
function cmdForceAlarm() {
alarmCmdReq.send( alarmCmdParms+"&command=forceAlarm" );
}
2017-05-19 01:50:56 +08:00
function cmdCancelForcedAlarm() {
alarmCmdReq.send( alarmCmdParms+"&command=cancelForcedAlarm" );
}
2017-05-19 01:50:56 +08:00
function getActResponse( respObj, respText ) {
if ( respObj.result == 'Ok' ) {
if ( respObj.refreshParent ) {
window.opener.location.reload();
}
2017-05-19 01:50:56 +08:00
}
eventCmdQuery();
}
2017-05-19 01:50:56 +08:00
function deleteEvent( event, eventId ) {
var actParms = "view=request&request=event&action=delete&id="+eventId;
var actReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: 3000, data: actParms, onSuccess: getActResponse } );
actReq.send();
event.stop();
}
var eventCmdParms = "view=request&request=status&entity=events&id="+monitorId+"&count="+maxDisplayEvents+"&sort=Id%20desc";
var eventCmdReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, data: eventCmdParms, link: 'cancel', onSuccess: getEventCmdResponse, onTimeout: eventCmdQuery } );
var eventCmdTimer = null;
var eventCmdFirst = true;
2017-05-19 01:50:56 +08:00
function highlightRow( row ) {
$(row).toggleClass( 'highlight' );
}
function getEventCmdResponse( respObj, respText ) {
watchdogOk("event");
if ( eventCmdTimer )
eventCmdTimer = clearTimeout( eventCmdTimer );
if ( respObj.result == 'Ok' ) {
var dbEvents = respObj.events.reverse();
var eventList = $('eventList');
var eventListBody = $(eventList).getElement( 'tbody' );
var eventListRows = $(eventListBody).getElements( 'tr' );
eventListRows.each( function( row ) { row.removeClass( 'updated' ); } );
for ( var i = 0; i < dbEvents.length; i++ ) {
var event = dbEvents[i];
var row = $('event'+event.Id);
var newEvent = (row == null ? true : false);
if ( newEvent ) {
row = new Element( 'tr', { 'id': 'event'+event.Id } );
new Element( 'td', { 'class': 'colId' } ).inject( row );
new Element( 'td', { 'class': 'colName' } ).inject( row );
new Element( 'td', { 'class': 'colTime' } ).inject( row );
new Element( 'td', { 'class': 'colSecs' } ).inject( row );
new Element( 'td', { 'class': 'colFrames' } ).inject( row );
new Element( 'td', { 'class': 'colScore' } ).inject( row );
new Element( 'td', { 'class': 'colDelete' } ).inject( row );
var cells = row.getElements( 'td' );
var link = new Element( 'a', { 'href': '#', 'events': { 'click': createEventPopup.pass( [event.Id, '&trms=1&attr1=MonitorId&op1=%3d&val1='+monitorId+'&page=1', event.Width, event.Height] ) } });
link.set( 'text', event.Id );
link.inject( row.getElement( 'td.colId' ) );
link = new Element( 'a', { 'href': '#', 'events': { 'click': createEventPopup.pass( [event.Id, '&trms=1&attr1=MonitorId&op1=%3d&val1='+monitorId+'&page=1', event.Width, event.Height] ) } });
link.set( 'text', event.Name );
link.inject( row.getElement( 'td.colName' ) );
row.getElement( 'td.colTime' ).set( 'text', event.StartTime );
row.getElement( 'td.colSecs' ).set( 'text', event.Length );
link = new Element( 'a', { 'href': '#', 'events': { 'click': createFramesPopup.pass( [event.Id, event.Width, event.Height] ) } });
link.set( 'text', event.Frames+'/'+event.AlarmFrames );
link.inject( row.getElement( 'td.colFrames' ) );
link = new Element( 'a', { 'href': '#', 'events': { 'click': createFramePopup.pass( [event.Id, '0', event.Width, event.Height] ) } });
link.set( 'text', event.AvgScore+'/'+event.MaxScore );
link.inject( row.getElement( 'td.colScore' ) );
link = new Element( 'a', { 'href': '#', 'title': deleteString, 'events': { 'click': function( e ) { deleteEvent( e, event.Id ); }, 'mouseover': highlightRow.pass( row ), 'mouseout': highlightRow.pass( row ) } });
link.set( 'text', 'X' );
link.inject( row.getElement( 'td.colDelete' ) );
if ( i == 0 ) {
row.inject( $(eventListBody) );
} else {
row.inject( $(eventListBody), 'top' );
if ( !eventCmdFirst )
row.addClass( 'recent' );
}
2017-05-19 01:50:56 +08:00
} else {
row.getElement( 'td.colName a' ).set( 'text', event.Name );
row.getElement( 'td.colSecs' ).set( 'text', event.Length );
row.getElement( 'td.colFrames a' ).set( 'text', event.Frames+'/'+event.AlarmFrames );
row.getElement( 'td.colScore a' ).set( 'text', event.AvgScore+'/'+event.MaxScore );
row.removeClass( 'recent' );
}
row.addClass( 'updated' );
}
2017-05-19 01:50:56 +08:00
var rows = $(eventListBody).getElements( 'tr' );
for ( var i = 0; i < rows.length; i++ ) {
if ( !rows[i].hasClass( 'updated' ) ) {
rows[i].destroy();
rows.splice( i, 1 );
i--;
}
}
2017-05-19 01:50:56 +08:00
while ( rows.length > maxDisplayEvents ) {
rows[rows.length-1].destroy();
rows.length--;
}
} else
checkStreamForErrors("getEventCmdResponse", respObj);
2017-05-19 01:50:56 +08:00
var eventCmdTimeout = eventsRefreshTimeout;
if ( alarmState == STATE_ALARM || alarmState == STATE_ALERT )
eventCmdTimeout = eventCmdTimeout/5;
eventCmdTimer = eventCmdQuery.delay( eventCmdTimeout );
eventCmdFirst = false;
}
2017-05-19 01:50:56 +08:00
function eventCmdQuery() {
if ( eventCmdTimer ) //avoid firing another if we are firing one
eventCmdTimer = clearTimeout( eventCmdTimer );
eventCmdReq.send();
}
var controlParms = "view=request&request=control&id="+monitorId;
var controlReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getControlResponse } );
2017-05-19 01:50:56 +08:00
function getControlResponse( respObj, respText ) {
if ( !respObj )
return;
//console.log( respText );
if ( respObj.result != 'Ok' ) {
alert( "Control response was status = "+respObj.status+"\nmessage = "+respObj.message );
}
}
function controlCmd( control, event, xtell, ytell ) {
var locParms = "";
if ( event && (xtell || ytell) ) {
var xEvent = new Event( event );
var target = xEvent.target;
var coords = $(target).getCoordinates();
var l = coords.left;
var t = coords.top;
var x = xEvent.page.x - l;
var y = xEvent.page.y - t;
if ( xtell ) {
var xge = parseInt( (x*100)/coords.width );
if ( xtell == -1 )
xge = 100 - xge;
else if ( xtell == 2 )
xge = 2*(50 - xge);
locParms += "&xge="+xge;
}
2017-05-19 01:50:56 +08:00
if ( ytell ) {
var yge = parseInt( (y*100)/coords.height );
if ( ytell == -1 )
yge = 100 - yge;
else if ( ytell == 2 )
yge = 2*(50 - yge);
locParms += "&yge="+yge;
}
2017-05-19 01:50:56 +08:00
}
controlReq.send( controlParms+"&control="+control+locParms );
if ( streamMode == "single" )
fetchImage.pass( $('imageFeed').getElement('img') ).delay( 1000 );
}
2017-05-19 01:50:56 +08:00
function controlCmdImage( x, y ) {
var imageControlParms = controlParms;
imageControlParms += "&scale="+scale;
imageControlParms += "&control="+imageControlMode;
2017-05-19 01:50:56 +08:00
controlReq.send( imageControlParms+"&x="+x+"&y="+y );
if ( streamMode == "single" )
fetchImage.pass( $('imageFeed').getElement('img') ).delay( 1000 );
}
2017-05-19 01:50:56 +08:00
function fetchImage( streamImage ) {
2017-05-30 23:35:52 +08:00
streamImage.src = streamImage.src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
2017-05-19 01:50:56 +08:00
}
function handleClick( event ) {
var target = event.target;
var x = event.page.x - $(target).getLeft();
var y = event.page.y - $(target).getTop();
if ( showMode == "events" || !imageControlMode ) {
if ( event.shift )
streamCmdPan( x, y );
else
2017-05-19 01:50:56 +08:00
streamCmdZoomIn( x, y );
} else {
controlCmdImage( x, y );
}
}
2017-05-19 01:50:56 +08:00
function appletRefresh() {
if ( streamStatus && (!streamStatus.paused && !streamStatus.delayed) ) {
var streamImg = $('liveStream');
var parent = streamImg.getParent();
streamImg.dispose();
streamImg.inject( parent );
if ( appletRefreshTime )
appletRefresh.delay( appletRefreshTime*1000 );
} else {
appletRefresh.delay( 15*1000 ); //if we are paused or delayed check every 15 seconds if we are live yet...
}
}
var watchdogInactive = {
2017-05-19 01:50:56 +08:00
'stream': false,
'status': false,
'event': false
};
var watchdogFunctions = {
2017-05-19 01:50:56 +08:00
'stream': streamCmdQuery,
'status': statusCmdQuery,
'event': eventCmdQuery
};
//Make sure the various refreshes are still taking effect
2017-05-19 01:50:56 +08:00
function watchdogCheck( type ) {
if ( watchdogInactive[type] ) {
console.log( "Detected streamWatch of type: " + type + " stopped, restarting" );
watchdogFunctions[type]();
watchdogInactive[type] = false;
2017-05-19 01:50:56 +08:00
} else {
watchdogInactive[type] = true;
}
}
function watchdogOk( type ) {
watchdogInactive[type] = false;
}
function initPage() {
if ( streamMode == "single" ) {
statusCmdTimer = statusCmdQuery.delay( (Math.random()+0.1)*statusRefreshTimeout );
watchdogCheck.pass('status').periodical(statusRefreshTimeout*2);
} else {
streamCmdTimer = streamCmdQuery.delay( (Math.random()+0.1)*statusRefreshTimeout );
watchdogCheck.pass('stream').periodical(statusRefreshTimeout*2);
}
eventCmdTimer = eventCmdQuery.delay( (Math.random()+0.1)*statusRefreshTimeout );
watchdogCheck.pass('event').periodical(eventsRefreshTimeout*2);
if ( canStreamNative || streamMode == "single" ) {
var streamImg = $('imageFeed').getElement('img');
if ( !streamImg )
streamImg = $('imageFeed').getElement('object');
if ( streamMode == "single" ) {
streamImg.addEvent( 'click', fetchImage.pass( streamImg ) );
fetchImage.pass( streamImg ).periodical( imageRefreshTimeout );
} else
streamImg.addEvent( 'click', function( event ) { handleClick( event ); } );
}
if ( refreshApplet && appletRefreshTime )
appletRefresh.delay( appletRefreshTime*1000 );
Add h264 event view functionality and new feature alarmCues (#2012) * Fix nearEventsQuery Removed dbEscape from getNearEvents previous event because it only returns 0. Now matches next. Changed getEventDefaultVideoPath function to return a web path rather than the absolute path based on ic0ns branch. Also added start times to allow for videoJS replaymode. * Unescape filters Filters need to be unescaped * Add initial values to page load * Add replay modes to videojs * rough in figuring out a frame in between bulk frames * Add alarmCues Add a graphical indication of where alarm frames happened in an event. Similar to what zmNinja shows. * Add remaining buttons to videojs Functionality for all buttons on videojs streams. FF/RW buttons show as active when they are active. * Whitespace and fix Bulkframe calcs * Fix zms events trying to generate with mp4 code ZMS events would attempt to generate frames as though they were an mp4/passthrough type because the full eventpath wasn't passed * ZMS scrub bar Move zms scrub bar to bottom of image feed. Make it simpler and more like videojs style. * Wrap event feeds properly * Fix dvrControls on watch view * Add scaleToFit Add a scaleToFit option to event view * Add navigation for videoJS streams Disables nav buttons at beginning and end of events. Handles switching from zms to videojs. If zms crashes changes next event function to reload page instead of ajax. * Add scaleToFit to watch and frame view Adds scaleToFit to watch view. Since frame view uses the watch cookie this required changes to frame view * Add transition to zoom * Change stills view to match stream Move stills slider bar to match scrub bar on streams. Allow it to resize, make it larger. Add alarmcues. * Add Stills for every event Add stills for every event. Match size to stream size * Progressbox transitions
2017-12-05 10:26:59 +08:00
if (scale == "auto") changeScale();
}
// Kick everything off
window.addEvent( 'domready', initPage );