use webvvt to overlay timestamp (honoring Monitor.LabelFormat) to videos in timeline and event

also fixed bug which prevented seeking in timeline video preview
pull/1166/head
Heng Liu 2015-11-18 21:21:56 -08:00
parent 1e5c82937c
commit 5ea11a8bfe
5 changed files with 70 additions and 16 deletions

View File

@ -261,3 +261,38 @@ if ( focusWindow )
}
window.addEvent( 'domready', checkSize);
function convertLabelFormat(LabelFormat, monitorName){
//convert label format from strftime to moment's format (modified from
//https://raw.githubusercontent.com/benjaminoakes/moment-strftime/master/lib/moment-strftime.js
//added %f and %N below (TODO: add %Q)
var replacements = { a: 'ddd', A: 'dddd', b: 'MMM', B: 'MMMM', d: 'DD', e: 'D', F: 'YYYY-MM-DD', H: 'HH', I: 'hh', j: 'DDDD', k: 'H', l: 'h', m: 'MM', M: 'mm', p: 'A', S: 'ss', u: 'E', w: 'd', W: 'WW', y: 'YY', Y: 'YYYY', z: 'ZZ', Z: 'z', 'f': 'SS', 'N': "["+monitorName+"]", '%': '%' };
var momentLabelFormat = Object.keys(replacements).reduce(function (momentFormat, key) {
var value = replacements[key];
return momentFormat.replace("%" + key, value);
}, LabelFormat);
return momentLabelFormat;
}
function addVideoTimingTrack(video, LabelFormat, monitorName, duration, startTime){
var labelFormat = convertLabelFormat(LabelFormat, monitorName);
var webvttformat = 'HH:mm:ss.SSS', webvttdata="WEBVTT\n\n";
startTime = moment(startTime);
var seconds = moment({s:0}), endduration = moment({s:duration});
while(seconds.isBefore(endduration)){
webvttdata += seconds.format(webvttformat) + " --> ";
seconds.add(1,'s');
webvttdata += seconds.format(webvttformat) + "\n";
webvttdata += startTime.format(labelFormat) + "\n\n";
startTime.add(1, 's');
}
var track = document.createElement('track');
track.kind = "captions";
track.srclang = "en";
track.label = "English";
track['default'] = true;
track.src = 'data:plain/text;charset=utf-8,'+encodeURIComponent(webvttdata);
video.appendChild(track);
}

View File

@ -27,7 +27,7 @@ if ( !canView( 'Events' ) )
$eid = validInt( $_REQUEST['eid'] );
$fid = !empty($_REQUEST['fid'])?validInt($_REQUEST['fid']):1;
$sql = 'SELECT E.*,M.Name AS MonitorName,M.Width,M.Height,M.DefaultRate,M.DefaultScale,M.VideoWriter,M.SaveJPEGs,M.Orientation FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE E.Id = ?';
$sql = 'SELECT E.*,M.Name AS MonitorName,M.Width,M.Height,M.DefaultRate,M.DefaultScale,M.VideoWriter,M.SaveJPEGs,M.Orientation,M.LabelFormat FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE E.Id = ?';
$sql_values = array( $eid );
if ( $user['MonitorIds'] ) {
@ -141,15 +141,24 @@ if ( $event['SaveJPEGs'] & 3 )
if ( $event['DefaultVideo'] )
{
?>
<link href="//vjs.zencdn.net/4.11/video-js.css" rel="stylesheet">
<script src="//vjs.zencdn.net/4.11/video.js"></script>
<script src='./js/videojs.zoomrotate.js'></script>
<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": { "rotate": "<?php echo $Rotation ?>", "zoom": "<?php echo $Zoom ?>"}}}'>
<source src="<?php echo getEventDefaultVideoPath($event) ?>" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
<!--script>includeVideoJs();</script-->
<link href="//vjs.zencdn.net/4.11/video-js.css" rel="stylesheet">
<script src="//vjs.zencdn.net/4.11/video.js"></script>
<script src="./js/videojs.zoomrotate.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<script>
var LabelFormat = "<?php echo validJsStr($event['LabelFormat'])?>";
var monitorName = "<?php echo validJsStr($event['MonitorName'])?>";
var duration = <?php echo $event['Length'] ?>, startTime = '<?php echo $event['StartTime'] ?>';
addVideoTimingTrack(document.getElementById('videoobj'), LabelFormat, monitorName, duration, startTime);
</script>
<?php
}

View File

@ -105,14 +105,15 @@ function previewEvent( eventId, frameId )
if ( events[eventId] )
{
if ( events[eventId]['frames'] )
var event = events[eventId];
if ( event['frames'] )
{
if ( events[eventId]['frames'][frameId] )
if ( event['frames'][frameId] )
{
showEventDetail( events[eventId]['frames'][frameId]['html'] );
var imagePath = events[eventId].frames[frameId].Image.imagePath;
var videoName = events[eventId].DefaultVideo;
loadEventImage( imagePath, eventId, frameId, events[eventId].Width, events[eventId].Height, events[eventId].Frames/events[eventId].Length, videoName);
showEventDetail( event['frames'][frameId]['html'] );
var imagePath = event.frames[frameId].Image.imagePath;
var videoName = event.DefaultVideo;
loadEventImage( imagePath, eventId, frameId, event.Width, event.Height, event.Frames/event.Length, videoName, event.Length, event.StartTime, monitors[event.MonitorId]);
return;
}
}
@ -120,7 +121,7 @@ function previewEvent( eventId, frameId )
requestFrameData( eventId, frameId );
}
function loadEventImage( imagePath, eid, fid, width, height, fps, videoName )
function loadEventImage( imagePath, eid, fid, width, height, fps, videoName, duration, startTime, Monitor )
{
var vid= $('preview');
var imageSrc = $('imageSrc');
@ -137,14 +138,18 @@ function loadEventImage( imagePath, eid, fid, width, height, fps, videoName )
//it is possible to set a long source list here will that be unworkable?
var sources = vid.getElementsByTagName('source');
sources[0].src=newsource;
var tracks = vid.getElementsByTagName('track');
if(tracks.length){
tracks[0].parentNode.removeChild(tracks[0]);
}
vid.load();
vid.oncanplay=function(){ vid.currentTime=fid/fps;} //25.0
addVideoTimingTrack(vid, Monitor.LabelFormat, Monitor.Name, duration, startTime)
vid.currentTime = fid/fps;
}
else
{
vid.oncanplay=null;//console.log("canplay");}
if(!vid.seeking)
vid.currentTime=fid/fps;//25.0;
vid.currentTime=fid/fps;
}
}
else

View File

@ -2,7 +2,7 @@ var filterQuery = '<?php echo validJsStr($filterQuery) ?>';
<?php
$jsMonitors = array();
$fields = array('Name', 'SaveJPEGs', 'VideoWriter');
$fields = array('Name', 'LabelFormat', 'SaveJPEGs', 'VideoWriter');
foreach ( $monitors as $monitor )
{
if ( !empty($monitorIds[$monitor['Id']]) )

View File

@ -813,7 +813,11 @@ xhtmlHeaders(__FILE__, translate('Timeline') );
<div id="imagePanel">
<div id="image" class="imageHeight">
<img id="imageSrc" class="imageWidth" src="graphics/transparent.gif" alt="<?php echo translate('ViewEvent') ?>" title="<?php echo translate('ViewEvent') ?>"/>
<video id="preview" width="100%" controls>
<?php
//due to chrome bug, has to enable https://code.google.com/p/chromium/issues/detail?id=472300
//crossorigin has to be added below to make caption work in chrome
?>
<video id="preview" width="100%" controls crossorigin="anonymous">
<source src="<?php echo "/events/".getEventPath($event)."/event.mp4"; ?>" type="video/mp4">
Your browser does not support the video tag.
</video>
@ -979,5 +983,6 @@ foreach( array_keys($monEventSlots) as $monitorId )
</div>
</div>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
</body>
</html>