@@ -54,6 +54,7 @@ function VideoModel() {
54
54
element ,
55
55
_currentTime ,
56
56
setCurrentTimeReadyStateFunction ,
57
+ resumeReadyStateFunction ,
57
58
TTMLRenderingDiv ,
58
59
vttRenderingDiv ,
59
60
previousPlaybackRate ,
@@ -80,21 +81,20 @@ function VideoModel() {
80
81
eventBus . off ( Events . PLAYBACK_PLAYING , onPlaying , this ) ;
81
82
}
82
83
83
- function onPlaybackCanPlay ( ) {
84
- if ( element ) {
85
- element . playbackRate = previousPlaybackRate || 1 ;
86
- element . removeEventListener ( 'canplay' , onPlaybackCanPlay ) ;
84
+ function setPlaybackRate ( value , ignoreReadyState = false ) {
85
+ if ( ! element ) {
86
+ return ;
87
87
}
88
- }
89
88
90
- function setPlaybackRate ( value , ignoreReadyState = false ) {
91
- if ( ! element ) return ;
92
- if ( ! ignoreReadyState && element . readyState <= 2 && value > 0 ) {
93
- // If media element hasn't loaded enough data to play yet, wait until it has
94
- element . addEventListener ( 'canplay' , onPlaybackCanPlay ) ;
95
- } else {
89
+ if ( ignoreReadyState ) {
96
90
element . playbackRate = value ;
91
+ return ;
97
92
}
93
+
94
+ // If media element hasn't loaded enough data to play yet, wait until it has
95
+ waitForReadyState ( Constants . VIDEO_ELEMENT_READY_STATES . HAVE_FUTURE_DATA , ( ) => {
96
+ element . playbackRate = value ;
97
+ } ) ;
98
98
}
99
99
100
100
//TODO Move the DVR window calculations from MediaPlayer to Here.
@@ -238,19 +238,27 @@ function VideoModel() {
238
238
}
239
239
240
240
function addStalledStream ( type ) {
241
-
242
241
if ( type === null || ! element || element . seeking || stalledStreams . indexOf ( type ) !== - 1 ) {
243
242
return ;
244
243
}
245
244
246
245
stalledStreams . push ( type ) ;
247
- if ( settings . get ( ) . streaming . buffer . emitSyntheticStallEvents && element && stalledStreams . length === 1 && element . readyState >= Constants . VIDEO_ELEMENT_READY_STATES . HAVE_FUTURE_DATA ) {
246
+
247
+ if (
248
+ settings . get ( ) . streaming . buffer . syntheticStallEvents . enabled &&
249
+ element &&
250
+ stalledStreams . length === 1 &&
251
+ ( settings . get ( ) . streaming . buffer . syntheticStallEvents . ignoreReadyState || getReadyState ( ) >= Constants . VIDEO_ELEMENT_READY_STATES . HAVE_FUTURE_DATA )
252
+ ) {
248
253
logger . debug ( `emitting synthetic waiting event and halting playback with playback rate 0` ) ;
254
+
255
+ previousPlaybackRate = element . playbackRate ;
256
+
257
+ setPlaybackRate ( 0 , true ) ;
258
+
249
259
// Halt playback until nothing is stalled.
250
260
const event = document . createEvent ( 'Event' ) ;
251
261
event . initEvent ( 'waiting' , true , false ) ;
252
- previousPlaybackRate = element . playbackRate ;
253
- setPlaybackRate ( 0 ) ;
254
262
element . dispatchEvent ( event ) ;
255
263
}
256
264
}
@@ -265,14 +273,27 @@ function VideoModel() {
265
273
stalledStreams . splice ( index , 1 ) ;
266
274
}
267
275
268
- // If nothing is stalled resume playback.
269
- if ( settings . get ( ) . streaming . buffer . emitSyntheticStallEvents && element && isStalled ( ) === false && element . playbackRate === 0 && element . readyState >= Constants . VIDEO_ELEMENT_READY_STATES . HAVE_FUTURE_DATA ) {
270
- logger . debug ( `emitting synthetic playing event (if not paused) and resuming playback with playback rate: ${ previousPlaybackRate || 1 } ` ) ;
271
- setPlaybackRate ( previousPlaybackRate || 1 ) ;
272
- if ( ! element . paused ) {
273
- const event = document . createEvent ( 'Event' ) ;
274
- event . initEvent ( 'playing' , true , false ) ;
275
- element . dispatchEvent ( event ) ;
276
+
277
+ if ( settings . get ( ) . streaming . buffer . syntheticStallEvents . enabled && element && ! isStalled ( ) && element . playbackRate === 0 ) {
278
+ const resume = ( ) => {
279
+ logger . debug ( `emitting synthetic playing event (if not paused) and resuming playback with playback rate: ${ previousPlaybackRate || 1 } ` ) ;
280
+
281
+ setPlaybackRate ( previousPlaybackRate || 1 , settings . get ( ) . streaming . buffer . syntheticStallEvents . ignoreReadyState ) ;
282
+
283
+ if ( ! element . paused ) {
284
+ const event = document . createEvent ( 'Event' ) ;
285
+ event . initEvent ( 'playing' , true , false ) ;
286
+ element . dispatchEvent ( event ) ;
287
+ }
288
+ }
289
+
290
+ if ( settings . get ( ) . streaming . buffer . syntheticStallEvents . ignoreReadyState ) {
291
+ resume ( )
292
+ } else {
293
+ if ( resumeReadyStateFunction && resumeReadyStateFunction . func && resumeReadyStateFunction . event ) {
294
+ removeEventListener ( resumeReadyStateFunction . event , resumeReadyStateFunction . func ) ;
295
+ }
296
+ resumeReadyStateFunction = waitForReadyState ( Constants . VIDEO_ELEMENT_READY_STATES . HAVE_FUTURE_DATA , resume )
276
297
}
277
298
}
278
299
}
@@ -465,15 +486,18 @@ function VideoModel() {
465
486
}
466
487
467
488
function waitForReadyState ( targetReadyState , callback ) {
468
- if ( targetReadyState === Constants . VIDEO_ELEMENT_READY_STATES . HAVE_NOTHING ||
469
- getReadyState ( ) >= targetReadyState ) {
489
+ if (
490
+ targetReadyState === Constants . VIDEO_ELEMENT_READY_STATES . HAVE_NOTHING ||
491
+ getReadyState ( ) >= targetReadyState
492
+ ) {
470
493
callback ( ) ;
471
494
return null ;
472
- } else {
473
- // wait for the appropriate callback before checking again
474
- const event = READY_STATES_TO_EVENT_NAMES [ targetReadyState ] ;
475
- _listenOnce ( event , callback ) ;
476
495
}
496
+
497
+ // wait for the appropriate callback before checking again
498
+ const event = READY_STATES_TO_EVENT_NAMES [ targetReadyState ] ;
499
+
500
+ return _listenOnce ( event , callback ) ;
477
501
}
478
502
479
503
function _listenOnce ( event , callback ) {
@@ -483,6 +507,7 @@ function VideoModel() {
483
507
// Call the original listener.
484
508
callback ( event ) ;
485
509
} ;
510
+
486
511
addEventListener ( event , func ) ;
487
512
488
513
return { func, event }
0 commit comments