@@ -176,11 +176,6 @@ var SubtitlesOctopus = function (options) {
176176 self . setVideo = function ( video ) {
177177 self . video = video ;
178178 if ( self . video ) {
179- if ( self . renderAhead > 0 ) {
180- console . debug ( 'starting oneshot render because new video detected' ) ;
181- window . requestAnimationFrame ( oneshotRender ) ;
182- tryRequestOneshot ( ) ;
183- }
184179 var timeupdate = function ( ) {
185180 self . setCurrentTime ( video . currentTime + self . timeOffset ) ;
186181 }
@@ -267,11 +262,10 @@ var SubtitlesOctopus = function (options) {
267262 retainedItems . push ( item ) ;
268263 }
269264 }
265+
270266 if ( seekClean && retainedItems . length > 0 ) {
271- // order items by event start time
272- retainedItems . sort ( function ( a , b ) {
273- return a . eventStart - b . eventStart ;
274- } ) ;
267+ // items are ordered by event start time when we push to self.renderedItems,
268+ // so first item is the earliest
275269 if ( currentTime < retainedItems [ 0 ] . eventStart ) {
276270 if ( retainedItems [ 0 ] . eventStart - currentTime > 60 ) {
277271 console . info ( "seeked back too far, cleaning prerender buffer" ) ;
@@ -290,14 +284,15 @@ var SubtitlesOctopus = function (options) {
290284 }
291285 }
292286 }
293- var removed = retainedItems . length != self . renderedItems . length ;
287+
288+ var removed = retainedItems . length < self . renderedItems ;
294289 self . renderedItems = retainedItems ;
295290 return removed ;
296291 }
297292
298- function tryRequestOneshot ( currentTime , postIfBusy ) {
293+ function tryRequestOneshot ( currentTime , renderNow ) {
299294 if ( ! self . renderAhead || self . renderAhead <= 0 ) return ;
300- if ( self . oneshotState . renderRequested && ! postIfBusy ) return ;
295+ if ( self . oneshotState . renderRequested && ! renderNow ) return ;
301296
302297 if ( typeof currentTime === 'undefined' ) {
303298 if ( ! self . video ) return ;
@@ -322,14 +317,14 @@ var SubtitlesOctopus = function (options) {
322317 }
323318
324319 if ( size <= self . renderAhead ) {
325- lastRendered = currentTime - 0 .001;
320+ lastRendered = currentTime - ( renderNow ? 0 : 0 .001) ;
326321 console . info ( 'requesting new frame because current prerender size is less than limit (start=' + lastRendered + ')' ) ;
327322 if ( ! self . oneshotState . renderRequested ) {
328323 self . oneshotState . renderRequested = true ;
329324 self . worker . postMessage ( {
330325 target : 'oneshot-render' ,
331326 lastRendered : lastRendered ,
332- renderNow : false ,
327+ renderNow : renderNow ,
333328 iteration : self . oneshotState . iteration
334329 } ) ;
335330 } else {
@@ -369,35 +364,47 @@ var SubtitlesOctopus = function (options) {
369364 if ( ! self . video ) return ;
370365
371366 var currentTime = self . video . currentTime + self . timeOffset ;
372- var finishTime = - 1 , eventShown = false ;
367+ var finishTime = - 1 , eventShown = false , animated = false ;
373368 for ( var i = 0 , len = self . renderedItems . length ; i < len ; i ++ ) {
374369 var item = self . renderedItems [ i ] ;
375370 if ( ! eventShown && item . eventStart <= currentTime && ( item . emptyFinish < 0 || item . emptyFinish >= currentTime ) ) {
376371 _renderSubtitleEvent ( item , currentTime ) ;
377372 eventShown = true ;
378- }
379- if ( item . emptyFinish > finishTime ) {
380373 finishTime = item . emptyFinish ;
374+ } else if ( finishTime >= 0 ) {
375+ // we've already found a known event, now find
376+ // the farthest point of consequent events
377+ // NOTE: self.renderedItems may have gaps due to seeking
378+ if ( item . eventStart - finishTime < 0.01 ) {
379+ finishTime = item . emptyFinish ;
380+ animated = item . animated ;
381+ } else {
382+ break ;
383+ }
381384 }
382385 }
383386
384387 if ( ! eventShown ) {
385- if ( Math . abs ( self . oneshotState . requestNextTimestamp - currentTime ) > 0.1 ) {
388+ if ( Math . abs ( self . oneshotState . requestNextTimestamp - currentTime ) > 0.01 ) {
386389 tryRequestOneshot ( currentTime , true ) ;
387390 }
388391 } else if ( _cleanPastRendered ( currentTime ) && finishTime >= 0 ) {
389392 console . debug ( 'some prerendered frame retired, requesting new' ) ;
390- tryRequestOneshot ( finishTime ) ;
393+ tryRequestOneshot ( finishTime , animated ) ;
391394 }
392395 }
393396
394397 function resetRenderAheadCache ( ) {
395- console . debug ( 'resetting prerender cache' ) ;
396- self . renderedItems = [ ] ;
397- self . oneshotState . eventStart = null ;
398- self . oneshotState . iteration ++ ;
399- self . oneshotState . renderRequested = false ;
400- tryRequestOneshot ( ) ;
398+ if ( self . renderAhead > 0 ) {
399+ console . debug ( 'resetting prerender cache' ) ;
400+ self . renderedItems = [ ] ;
401+ self . oneshotState . eventStart = null ;
402+ self . oneshotState . iteration ++ ;
403+ self . oneshotState . renderRequested = false ;
404+
405+ window . requestAnimationFrame ( oneshotRender ) ;
406+ tryRequestOneshot ( undefined , true ) ;
407+ }
401408 }
402409
403410 self . renderFrameData = null ;
@@ -534,9 +541,22 @@ var SubtitlesOctopus = function (options) {
534541 data . eventStart + ', empty=' + data . emptyFinish +
535542 '), render: ' + Math . round ( data . spentTime ) + ' ms' ) ;
536543 self . oneshotState . renderRequested = false ;
537- if ( data . lastRenderedTime == self . oneshotState . requestNextTimestamp ) {
544+ if ( Math . abs ( data . lastRenderedTime - self . oneshotState . requestNextTimestamp ) < 0.01 ) {
538545 self . oneshotState . requestNextTimestamp = - 1 ;
539546 }
547+ if ( data . eventStart - data . lastRenderedTime > 0.01 ) {
548+ // generate bogus empty element, so all timeline is covered anyway
549+ self . renderedItems . push ( {
550+ eventStart : data . lastRenderedTime ,
551+ eventFinish : data . lastRenderedTime - 0.001 ,
552+ emptyFinish : data . eventStart ,
553+ spentTime : 0 ,
554+ blendTime : 0 ,
555+ items : [ ] ,
556+ animated : false ,
557+ size : 0
558+ } ) ;
559+ }
540560
541561 var items = [ ] ;
542562 var size = 0 ;
@@ -551,9 +571,12 @@ var SubtitlesOctopus = function (options) {
551571 } ) ;
552572 size += item . buffer . byteLength ;
553573 }
554- if ( data . emptyFinish > 0 && data . emptyFinish - data . eventStart < 1.0 / self . targetFps ) {
555- data . emptyFinish = data . eventStart + 1.0 / self . targetFps ;
556- data . eventFinish = data . emptyFinish ;
574+ if ( ( data . emptyFinish > 0 && data . emptyFinish - data . eventStart < 1.0 / self . targetFps ) || data . animated ) {
575+ newFinish = data . eventStart + 1.0 / self . targetFps ;
576+ if ( newFinish < data . emptyFinish ) {
577+ data . emptyFinish = newFinish ;
578+ data . eventFinish = ( data . eventFinish > newFinish ) ? newFinish : data . eventFinish ;
579+ }
557580 }
558581 self . renderedItems . push ( {
559582 eventStart : data . eventStart ,
@@ -562,17 +585,22 @@ var SubtitlesOctopus = function (options) {
562585 spentTime : data . spentTime ,
563586 blendTime : data . blendTime ,
564587 items : items ,
588+ animated : data . animated ,
565589 size : size
566590 } ) ;
591+
592+ self . renderedItems . sort ( function ( a , b ) {
593+ return a . eventStart - b . eventStart ;
594+ } ) ;
567595
568596 if ( self . oneshotState . requestNextTimestamp >= 0 ) {
569597 console . debug ( "requesting out of order event at " + self . oneshotState . requestNextTimestamp ) ;
570- tryRequestOneshot ( self . oneshotState . requestNextTimestamp ) ;
598+ tryRequestOneshot ( self . oneshotState . requestNextTimestamp , true ) ;
571599 } else if ( data . eventStart < 0 ) {
572600 console . info ( 'oneshot received "end of frames" event' ) ;
573601 } else if ( data . emptyFinish >= 0 ) {
574602 console . debug ( "there's some more event to render, try requesting next event" ) ;
575- tryRequestOneshot ( data . emptyFinish ) ;
603+ tryRequestOneshot ( data . emptyFinish , data . animated ) ;
576604 } else {
577605 console . info ( 'there are no more events to prerender' ) ;
578606 }
0 commit comments