zoneminder/web/skins/classic/views/event.php

320 lines
14 KiB
PHP
Raw Normal View History

<?php
//
// ZoneMinder web event view file, $Date$, $Revision$
// Copyright (C) 2001-2008 Philip Coombes
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
2018-01-18 04:20:15 +08:00
if ( !canView('Events') ) {
2017-05-19 02:55:53 +08:00
$view = 'error';
return;
}
require_once('includes/Event.php');
require_once('includes/Filter.php');
$eid = validInt($_REQUEST['eid']);
2020-04-17 21:46:10 +08:00
$fid = !empty($_REQUEST['fid']) ? validInt($_REQUEST['fid']) : 1;
$Event = new ZM\Event($eid);
if ( $user['MonitorIds'] ) {
$monitor_ids = explode(',', $user['MonitorIds']);
if ( count($monitor_ids) and ! in_array($Event->MonitorId(), $monitor_ids) ) {
2016-10-12 21:17:57 +08:00
$view = 'error';
return;
}
}
2017-05-20 00:24:59 +08:00
$Monitor = $Event->Monitor();
2019-02-25 23:21:43 +08:00
if ( isset($_REQUEST['rate']) ) {
2017-05-19 02:55:53 +08:00
$rate = validInt($_REQUEST['rate']);
} else if ( isset($_COOKIE['zmEventRate']) ) {
$rate = $_COOKIE['zmEventRate'];
2017-10-22 08:22:05 +08:00
} else {
$rate = reScale(RATE_BASE, $Monitor->DefaultRate(), ZM_WEB_DEFAULT_RATE);
}
2019-02-25 23:21:43 +08:00
if ( isset($_REQUEST['scale']) ) {
$scale = validInt($_REQUEST['scale']);
} else if ( isset($_COOKIE['zmEventScale'.$Event->MonitorId()]) ) {
2016-10-12 21:17:57 +08:00
$scale = $_COOKIE['zmEventScale'.$Event->MonitorId()];
} else {
$scale = $Monitor->DefaultScale();
}
$codec = 'auto';
2019-02-25 23:21:43 +08:00
if ( isset($_REQUEST['codec']) ) {
$codec = $_REQUEST['codec'];
2020-08-25 23:27:25 +08:00
zm_session_start();
2018-09-11 03:09:08 +08:00
$_SESSION['zmEventCodec'.$Event->MonitorId()] = $codec;
session_write_close();
2019-02-25 23:21:43 +08:00
} else if ( isset($_SESSION['zmEventCodec'.$Event->MonitorId()]) ) {
$codec = $_SESSION['zmEventCodec'.$Event->MonitorId()];
} else {
$codec = $Monitor->DefaultCodec();
}
$codecs = array(
'auto' => translate('Auto'),
'MP4' => translate('MP4'),
'MJPEG' => translate('MJPEG'),
);
$replayModes = array(
'none' => translate('None'),
'single' => translate('ReplaySingle'),
'all' => translate('ReplayAll'),
'gapless' => translate('ReplayGapless'),
);
2020-04-17 21:46:10 +08:00
if ( isset($_REQUEST['streamMode']) )
2017-05-19 02:55:53 +08:00
$streamMode = validHtmlStr($_REQUEST['streamMode']);
else
2017-05-19 02:55:53 +08:00
$streamMode = 'video';
$replayMode = '';
2020-02-26 00:17:46 +08:00
if ( isset($_REQUEST['replayMode']) )
2017-05-19 02:55:53 +08:00
$replayMode = validHtmlStr($_REQUEST['replayMode']);
2020-02-26 00:17:46 +08:00
if ( isset($_COOKIE['replayMode']) && preg_match('#^[a-z]+$#', $_COOKIE['replayMode']) )
2017-05-19 02:55:53 +08:00
$replayMode = validHtmlStr($_COOKIE['replayMode']);
2019-02-25 23:21:43 +08:00
if ( ( !$replayMode ) or ( !$replayModes[$replayMode] ) ) {
$replayMode = 'none';
}
2017-11-14 14:59:15 +08:00
$video_tag = false;
2020-12-16 04:59:02 +08:00
if ( $Event->DefaultVideo() and ( $codec == 'MP4' or $codec == 'auto' ) ) {
2017-11-14 14:59:15 +08:00
$video_tag = true;
}
// videojs zoomrotate only when direct recording
$Zoom = 1;
$Rotation = 0;
2016-10-12 21:17:57 +08:00
if ( $Monitor->VideoWriter() == '2' ) {
# Passthrough
$Rotation = $Event->Orientation();
if ( in_array($Event->Orientation(),array('90','270')) )
$Zoom = $Event->Height()/$Event->Width();
}
2020-04-17 21:46:10 +08:00
// These are here to figure out the next/prev event, however if there is no filter, then default to one that specifies the Monitor
if ( !isset($_REQUEST['filter']) ) {
2020-04-17 21:46:10 +08:00
$_REQUEST['filter'] = array(
'Query'=>array(
'terms'=>array(
array('attr'=>'MonitorId', 'op'=>'=', 'val'=>$Event->MonitorId())
)
)
);
}
parseSort();
$filter = ZM\Filter::parse($_REQUEST['filter']);
$filterQuery = $filter->querystring();
$connkey = generateConnKey();
2020-12-01 23:07:42 +08:00
xhtmlHeaders(__FILE__, translate('Event').' '.$Event->Id());
?>
<body>
<div id="page">
2020-12-01 23:07:42 +08:00
<?php echo getNavBarHTML() ?>
<?php
2020-02-26 00:17:46 +08:00
if ( !$Event->Id() ) {
echo 'Event was not found.';
} else {
2020-12-01 23:07:42 +08:00
if ( !file_exists($Event->Path()) )
echo '<div class="error">Event was not found at '.$Event->Path().'. It is unlikely that playback will be possible.</div>';
?>
2020-12-01 23:07:42 +08:00
<!-- BEGIN HEADER -->
<div class="d-flex flex-row justify-content-between px-3 py-1">
<div id="toolbar" >
<button id="backBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Back') ?>" disabled><i class="fa fa-arrow-left"></i></button>
<button id="refreshBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Refresh') ?>" ><i class="fa fa-refresh"></i></button>
<button id="renameBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Rename') ?>" disabled><i class="fa fa-font"></i></button>
<button id="archiveBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Archive') ?>" disabled><i class="fa fa-archive"></i></button>
<button id="unarchiveBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Unarchive') ?>" disabled><i class="fa fa-file-archive-o"></i></button>
<button id="editBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Edit') ?>" disabled><i class="fa fa-pencil"></i></button>
<button id="exportBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Export') ?>"><i class="fa fa-external-link"></i></button>
<div id="Frames"><a class="btn-primary" href="?view=frames&eid=<?php echo $Event->Id() ?>">Frames</i></a></div>
<?php
2020-12-16 04:59:02 +08:00
if ( $Event->DefaultVideo() ) {
?>
<div id="downloadEventFile"><a class="btn-primary" href="<?php echo $Event->getStreamSrc(array('mode'=>'mp4'),'&amp;')?>" download><i class="fa fa-download"></i></a></div>
<?php
2020-12-16 04:59:02 +08:00
}
?>
2020-12-16 04:59:02 +08:00
<button id="statsBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Stats') ?>" ><i class="fa fa-info"></i></button>
<button id="deleteBtn" class="btn btn-danger" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Delete') ?>"><i class="fa fa-trash"></i></button>
</div>
<h2><?php echo translate('Event').' '.$Event->Id() ?></h2>
<div class="d-flex flex-row">
<div id="replayControl">
<label for="replayMode"><?php echo translate('Replay') ?></label>
<?php echo htmlSelect('replayMode', $replayModes, $replayMode, array('data-on-change'=>'changeReplayMode','id'=>'replayMode')); ?>
</div>
<div id="scaleControl">
<label for="scale"><?php echo translate('Scale') ?></label>
<?php echo htmlSelect('scale', $scales, $scale, array('data-on-change'=>'changeScale','id'=>'scale')); ?>
</div>
<div id="codecControl">
<label for="codec"><?php echo translate('Codec') ?></label>
<?php echo htmlSelect('codec', $codecs, $codec, array('data-on-change'=>'changeCodec','id'=>'codec')); ?>
</div>
</div>
</div>
2020-12-01 23:07:42 +08:00
<!-- BEGIN VIDEO CONTENT ROW -->
<div id="content" class="d-flex flex-row justify-content-center">
<div class="">
<!-- VIDEO STATISTICS TABLE -->
<table id="eventStatsTable" class="table-sm table-borderless">
2020-12-14 20:55:45 +08:00
<!-- EVENT STATISTICS POPULATED BY JAVASCRIPT -->
2020-12-01 23:07:42 +08:00
</table>
</div>
<div class="">
<div id="eventVideo">
2020-12-01 23:07:42 +08:00
<!-- VIDEO CONTENT -->
<?php
2017-11-14 14:59:15 +08:00
if ( $video_tag ) {
?>
<div id="videoFeed">
2019-12-03 04:34:31 +08:00
<video id="videoobj" class="video-js vjs-default-skin"
2020-02-26 00:17:46 +08:00
style="transform: matrix(1, 0, 0, 1, 0, 0);"
<?php echo $scale ? 'width="'.reScale($Event->Width(), $scale).'"' : '' ?>
<?php echo $scale ? 'height="'.reScale($Event->Height(), $scale).'"' : '' ?>
data-setup='{ "controls": true, "autoplay": true, "preload": "auto", "playbackRates": [ <?php echo implode(',',
array_map(function($r){return $r/100;},
array_filter(
array_keys($rates),
2020-10-19 21:08:25 +08:00
function($r){return $r >= 0 ? true : false;}
))) ?>], "plugins": { "zoomrotate": { "zoom": "<?php echo $Zoom ?>"}}}'
2019-12-03 04:34:31 +08:00
>
<source src="<?php echo $Event->getStreamSrc(array('mode'=>'mpeg','format'=>'h264'),'&amp;'); ?>" 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.
</video>
</div><!--videoFeed-->
<?php
} else {
2015-02-16 16:43:13 +08:00
?>
2017-10-05 23:20:42 +08:00
<div id="imageFeed">
2015-02-16 16:43:13 +08:00
<?php
2020-02-26 00:17:46 +08:00
if ( (ZM_WEB_STREAM_METHOD == 'mpeg') && ZM_MPEG_LIVE_FORMAT ) {
2019-12-03 04:34:31 +08:00
$streamSrc = $Event->getStreamSrc(array('mode'=>'mpeg', 'scale'=>$scale, 'rate'=>$rate, 'bitrate'=>ZM_WEB_VIDEO_BITRATE, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'format'=>ZM_MPEG_REPLAY_FORMAT, 'replay'=>$replayMode),'&amp;');
outputVideoStream('evtStream', $streamSrc, reScale( $Event->Width(), $scale ).'px', reScale( $Event->Height(), $scale ).'px', ZM_MPEG_LIVE_FORMAT );
2016-09-29 21:28:48 +08:00
} else {
2019-12-03 04:34:31 +08:00
$streamSrc = $Event->getStreamSrc(array('mode'=>'jpeg', 'frame'=>$fid, 'scale'=>$scale, 'rate'=>$rate, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>$replayMode),'&amp;');
2017-05-19 02:55:53 +08:00
if ( canStreamNative() ) {
outputImageStream('evtStream', $streamSrc, reScale($Event->Width(), $scale).'px', reScale($Event->Height(), $scale).'px', validHtmlStr($Event->Name()));
2017-05-19 02:55:53 +08:00
} else {
outputHelperStream('evtStream', $streamSrc, reScale($Event->Width(), $scale).'px', reScale($Event->Height(), $scale).'px' );
2017-05-19 02:55:53 +08:00
}
2016-10-12 21:17:57 +08:00
} // end if stream method
?>
<div id="alarmCue" class="alarmCue"></div>
<div id="progressBar" style="width: <?php echo reScale($Event->Width(), $scale);?>px;">
<div class="progressBox" id="progressBox" title="" style="width: 0%;"></div>
</div><!--progressBar-->
</div><!--imageFeed-->
2019-02-25 23:21:43 +08:00
<?php
} /*end if !DefaultVideo*/
?>
<p id="dvrControls">
2019-09-27 04:26:37 +08:00
<button type="button" id="prevBtn" title="<?php echo translate('Prev') ?>" class="inactive" data-on-click-true="streamPrev">
<i class="material-icons md-18">skip_previous</i>
</button>
<button type="button" id="fastRevBtn" title="<?php echo translate('Rewind') ?>" class="inactive" data-on-click-true="streamFastRev">
<i class="material-icons md-18">fast_rewind</i>
</button>
<button type="button" id="slowRevBtn" title="<?php echo translate('StepBack') ?>" class="unavail" disabled="disabled" data-on-click-true="streamSlowRev">
<i class="material-icons md-18">chevron_left</i>
</button>
<button type="button" id="pauseBtn" title="<?php echo translate('Pause') ?>" class="inactive" data-on-click="pauseClicked">
<i class="material-icons md-18">pause</i>
</button>
<button type="button" id="playBtn" title="<?php echo translate('Play') ?>" class="active" disabled="disabled" data-on-click="playClicked">
<i class="material-icons md-18">play_arrow</i>
</button>
<button type="button" id="slowFwdBtn" title="<?php echo translate('StepForward') ?>" class="unavail" disabled="disabled" data-on-click-true="streamSlowFwd">
<i class="material-icons md-18">chevron_right</i>
</button>
<button type="button" id="fastFwdBtn" title="<?php echo translate('FastForward') ?>" class="inactive" data-on-click-true="streamFastFwd">
<i class="material-icons md-18">fast_forward</i>
</button>
<button type="button" id="zoomOutBtn" title="<?php echo translate('ZoomOut') ?>" class="unavail" disabled="disabled" data-on-click="streamZoomOut">
<i class="material-icons md-18">zoom_out</i>
</button>
<button type="button" id="nextBtn" title="<?php echo translate('Next') ?>" class="inactive" data-on-click-true="streamNext">
<i class="material-icons md-18">skip_next</i>
</button>
</p>
<div id="replayStatus">
2017-11-11 23:53:36 +08:00
<span id="mode"><?php echo translate('Mode') ?>: <span id="modeValue">Replay</span></span>
<span id="rate"><?php echo translate('Rate') ?>:
<?php
#rates are defined in skins/classic/includes/config.php
echo htmlSelect('rate', $rates, intval($rate), array('id'=>'rateValue'));
?>
<!--<span id="rateValue"><?php echo $rate/100 ?></span>x</span>-->
<span id="progress"><?php echo translate('Progress') ?>: <span id="progressValue">0</span>s</span>
2017-11-11 23:53:36 +08:00
<span id="zoom"><?php echo translate('Zoom') ?>: <span id="zoomValue">1</span>x</span>
</div>
</div><!--eventVideo-->
<div id="eventStills" class="hidden">
<div id="eventThumbsPanel">
<div id="eventThumbs">
</div>
</div>
<div id="eventImagePanel">
<div id="eventImageFrame">
<img id="eventImage" src="graphics/transparent.png" alt=""/>
<div id="eventImageBar">
<div id="eventImageClose"><button type="button" data-on-click="hideEventImage"><?php echo translate('Close') ?></button></div>
<div id="eventImageStats" class="hidden"><button type="button" data-on-click="showFrameStats"><?php echo translate('Stats') ?></button></div>
2015-05-10 21:10:30 +08:00
<div id="eventImageData"><?php echo translate('Frame') ?> <span id="eventImageNo"></span></div>
</div>
</div>
</div>
<div id="eventImageNav">
<div id="thumbsSliderPanel">
<div id="alarmCue" class="alarmCue"></div>
<div id="thumbsSlider">
<div id="thumbsKnob">
</div>
</div>
</div>
<div id="eventImageButtons">
<div id="prevButtonsPanel">
2019-09-27 04:26:37 +08:00
<button id="prevEventBtn" type="button" data-on-click="prevEvent" disabled="disabled">&lt;E</button>
<button id="prevThumbsBtn" type="button" data-on-click="prevThumbs" disabled="disabled">&lt;&lt;</button>
<button id="prevImageBtn" type="button" data-on-click="prevImage" disabled="disabled">&lt;</button>
<button id="nextImageBtn" type="button" data-on-click="nextImage" disabled="disabled">&gt;</button>
<button id="nextThumbsBtn" type="button" data-on-click="nextThumbs" disabled="disabled">&gt;&gt;</button>
<button id="nextEventBtn" type="button" data-on-click="nextEvent" disabled="disabled">E&gt;</button>
</div>
</div>
</div>
</div>
<?php
} // end if Event exists
?>
2020-12-01 23:07:42 +08:00
</div>
</div><!--content-->
2020-12-01 23:07:42 +08:00
</div><!--page-->
<?php xhtmlFooter() ?>