Merge branch 'storageareas' of github.com:connortechnology/ZoneMinder into storageareas
This commit is contained in:
commit
bd95cd1de9
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
$servers = Server::find_all();
|
$servers = Server::find_all();
|
||||||
$ServersById = array(''=>'All');
|
$ServersById = array();
|
||||||
foreach ( $servers as $S ) {
|
foreach ( $servers as $S ) {
|
||||||
$ServersById[$S->Id()] = $S;
|
$ServersById[$S->Id()] = $S;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ foreach ( array('ServerFilter','StorageFilter') as $var ) {
|
||||||
session_write_close();
|
session_write_close();
|
||||||
|
|
||||||
$storage_areas = Storage::find_all();
|
$storage_areas = Storage::find_all();
|
||||||
$StorageById = array(''=>'All');
|
$StorageById = array();
|
||||||
foreach ( $storage_areas as $S ) {
|
foreach ( $storage_areas as $S ) {
|
||||||
$StorageById[$S->Id()] = $S;
|
$StorageById[$S->Id()] = $S;
|
||||||
}
|
}
|
||||||
|
@ -194,6 +194,7 @@ $groupSql = Group::get_group_sql( $group_id );
|
||||||
$monitors_dropdown[$monitors[$i]['Id']] = $monitors[$i]['Name'];
|
$monitors_dropdown[$monitors[$i]['Id']] = $monitors[$i]['Name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
echo htmlSelect( 'monitor_id', $monitors_dropdown, $monitor_id, array('onchange'=>'changeMonitor(this);') );
|
echo htmlSelect( 'monitor_id', $monitors_dropdown, $monitor_id, array('onchange'=>'changeMonitor(this);') );
|
||||||
|
|
||||||
$cycleWidth = $maxWidth;
|
$cycleWidth = $maxWidth;
|
||||||
|
@ -224,24 +225,23 @@ for( $i = 0; $i < count($displayMonitors); $i += 1 ) {
|
||||||
?>
|
?>
|
||||||
</span>
|
</span>
|
||||||
<?php if ( count($ServersById) > 0 ) { ?>
|
<?php if ( count($ServersById) > 0 ) { ?>
|
||||||
<span id="ServerFilter"><label><?php echo translate('Server')?>:</label>
|
<span class="ServerFilter"><label><?php echo translate('Server')?>:</label>
|
||||||
<?php
|
<?php
|
||||||
echo htmlSelect( 'ServerFilter', $ServersById, (isset($_SESSION['ServerFilter'])?$_SESSION['ServerFilter']:''), array('onchange'=>'changeFilter(this);') );
|
echo htmlSelect( 'ServerFilter', array(''=>'All')+$ServersById, (isset($_SESSION['ServerFilter'])?$_SESSION['ServerFilter']:''), array('onchange'=>'changeFilter(this);') );
|
||||||
?>
|
?>
|
||||||
</span>
|
</span>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
if ( count($StorageById) > 0 ) { ?>
|
if ( count($StorageById) > 0 ) { ?>
|
||||||
<span id="StorageFilter"><label><?php echo translate('Storage')?>:</label>
|
<span class="StorageFilter"><label><?php echo translate('Storage')?>:</label>
|
||||||
<?php
|
<?php
|
||||||
echo htmlSelect( 'StorageFilter', $StorageById, (isset($_SESSION['StorageFilter'])?$_SESSION['StorageFilter']:''), array('onchange'=>'changeFilter(this);') );
|
echo htmlSelect( 'StorageFilter', array(''=>'All')+$StorageById, (isset($_SESSION['StorageFilter'])?$_SESSION['StorageFilter']:''), array('onchange'=>'changeFilter(this);') );
|
||||||
?>
|
?>
|
||||||
</span>
|
</span>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<table class="table table-striped table-hover table-condensed" id="consoleTable">
|
<table class="table table-striped table-hover table-condensed" id="consoleTable">
|
||||||
|
|
|
@ -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="<+" id="prevBtn" title="<?php echo translate('Prev') ?>" class="inactive" onclick="streamPrev( true );"/>
|
<input type="button" value="<+" 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-->
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ?>;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,10 @@ function Monitor( monitorData ) {
|
||||||
this.alarmState = STATE_IDLE;
|
this.alarmState = STATE_IDLE;
|
||||||
this.lastAlarmState = STATE_IDLE;
|
this.lastAlarmState = STATE_IDLE;
|
||||||
this.streamCmdParms = "view=request&request=stream&connkey="+this.connKey;
|
this.streamCmdParms = "view=request&request=stream&connkey="+this.connKey;
|
||||||
|
if ( auth_hash )
|
||||||
|
this.streamCmdParms += '&auth='+auth_hash;
|
||||||
|
else
|
||||||
|
console.log("No auth_hash");
|
||||||
this.streamCmdTimer = null;
|
this.streamCmdTimer = null;
|
||||||
|
|
||||||
this.start = function( delay ) {
|
this.start = function( delay ) {
|
||||||
|
@ -30,7 +34,7 @@ function Monitor( monitorData ) {
|
||||||
if ( this.streamCmdTimer )
|
if ( this.streamCmdTimer )
|
||||||
this.streamCmdTimer = clearTimeout( this.streamCmdTimer );
|
this.streamCmdTimer = clearTimeout( this.streamCmdTimer );
|
||||||
|
|
||||||
var stream = $j('#liveStream'+this.id );
|
var stream = $j('#liveStream'+this.id )[0];
|
||||||
if ( respObj.result == 'Ok' ) {
|
if ( respObj.result == 'Ok' ) {
|
||||||
this.status = respObj.status;
|
this.status = respObj.status;
|
||||||
this.alarmState = this.status.state;
|
this.alarmState = this.status.state;
|
||||||
|
@ -75,10 +79,12 @@ function Monitor( monitorData ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( this.status.auth ) {
|
if ( this.status.auth ) {
|
||||||
// Try to reload the image stream.
|
if ( this.status.auth != auth_hash ) {
|
||||||
if ( stream )
|
// Try to reload the image stream.
|
||||||
stream.src = stream.src.replace( /auth=\w+/i, 'auth='+this.status.auth );
|
if ( stream )
|
||||||
console.log("Changed auth to " + this.status.auth );
|
stream.src = stream.src.replace( /auth=\w+/i, 'auth='+this.status.auth );
|
||||||
|
console.log("Changed auth to " + this.status.auth );
|
||||||
|
}
|
||||||
} // end if haev a new auth hash
|
} // end if haev a new auth hash
|
||||||
} else {
|
} else {
|
||||||
console.error( respObj.message );
|
console.error( respObj.message );
|
||||||
|
|
Loading…
Reference in New Issue