@@ -38,6 +38,7 @@ import {
38
38
OperatorFunction ,
39
39
pipe ,
40
40
Subject ,
41
+ of ,
41
42
} from 'rxjs' ;
42
43
43
44
import {
@@ -210,7 +211,7 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
210
211
const endSecondsObs = this . _endSeconds . pipe ( startWith ( undefined ) ) ;
211
212
const suggestedQualityObs = this . _suggestedQuality . pipe ( startWith ( undefined ) ) ;
212
213
213
- /** An observable of the currently loaded player. */
214
+ // An observable of the currently loaded player.
214
215
const playerObs =
215
216
createPlayerObservable (
216
217
this . _youtubeContainer ,
@@ -219,6 +220,7 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
219
220
widthObs ,
220
221
heightObs ,
221
222
this . createEventsBoundInZone ( ) ,
223
+ this . _ngZone
222
224
) . pipe ( waitUntilReady ( ) , takeUntil ( this . _destroyed ) , publish ( ) ) ;
223
225
224
226
// Set up side effects to bind inputs to the player.
@@ -480,6 +482,7 @@ function createPlayerObservable(
480
482
widthObs : Observable < number > ,
481
483
heightObs : Observable < number > ,
482
484
events : YT . Events ,
485
+ ngZone : NgZone
483
486
) : Observable < UninitializedPlayer | undefined > {
484
487
485
488
const playerOptions =
@@ -489,7 +492,7 @@ function createPlayerObservable(
489
492
map ( ( [ videoId , [ width , height ] ] ) => videoId ? ( { videoId, width, height, events} ) : undefined ) ,
490
493
) ;
491
494
492
- return combineLatest ( [ youtubeContainer , playerOptions ] )
495
+ return combineLatest ( [ youtubeContainer , playerOptions , of ( ngZone ) ] )
493
496
. pipe (
494
497
skipUntilRememberLatest ( iframeApiAvailableObs ) ,
495
498
scan ( syncPlayerState , undefined ) ,
@@ -507,7 +510,7 @@ function skipUntilRememberLatest<T>(notifier: Observable<boolean>): MonoTypeOper
507
510
/** Destroy the player if there are no options, or create the player if there are options. */
508
511
function syncPlayerState (
509
512
player : UninitializedPlayer | undefined ,
510
- [ container , videoOptions ] : [ HTMLElement , YT . PlayerOptions | undefined ] ,
513
+ [ container , videoOptions , ngZone ] : [ HTMLElement , YT . PlayerOptions | undefined , NgZone ] ,
511
514
) : UninitializedPlayer | undefined {
512
515
if ( ! videoOptions ) {
513
516
if ( player ) {
@@ -519,7 +522,10 @@ function syncPlayerState(
519
522
return player ;
520
523
}
521
524
522
- const newPlayer : UninitializedPlayer = new YT . Player ( container , videoOptions ) ;
525
+ // Important! We need to create the Player object outside of the `NgZone`, because it kicks
526
+ // off a 250ms setInterval which will continually trigger change detection if we don't.
527
+ const newPlayer : UninitializedPlayer =
528
+ ngZone . runOutsideAngular ( ( ) => new YT . Player ( container , videoOptions ) ) ;
523
529
// Bind videoId for future use.
524
530
newPlayer . videoId = videoOptions . videoId ;
525
531
return newPlayer ;
0 commit comments