@@ -38,6 +38,7 @@ import {
3838 OperatorFunction ,
3939 pipe ,
4040 Subject ,
41+ of ,
4142} from 'rxjs' ;
4243
4344import {
@@ -210,7 +211,7 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
210211 const endSecondsObs = this . _endSeconds . pipe ( startWith ( undefined ) ) ;
211212 const suggestedQualityObs = this . _suggestedQuality . pipe ( startWith ( undefined ) ) ;
212213
213- /** An observable of the currently loaded player. */
214+ // An observable of the currently loaded player.
214215 const playerObs =
215216 createPlayerObservable (
216217 this . _youtubeContainer ,
@@ -219,6 +220,7 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
219220 widthObs ,
220221 heightObs ,
221222 this . createEventsBoundInZone ( ) ,
223+ this . _ngZone
222224 ) . pipe ( waitUntilReady ( ) , takeUntil ( this . _destroyed ) , publish ( ) ) ;
223225
224226 // Set up side effects to bind inputs to the player.
@@ -480,6 +482,7 @@ function createPlayerObservable(
480482 widthObs : Observable < number > ,
481483 heightObs : Observable < number > ,
482484 events : YT . Events ,
485+ ngZone : NgZone
483486) : Observable < UninitializedPlayer | undefined > {
484487
485488 const playerOptions =
@@ -489,7 +492,7 @@ function createPlayerObservable(
489492 map ( ( [ videoId , [ width , height ] ] ) => videoId ? ( { videoId, width, height, events} ) : undefined ) ,
490493 ) ;
491494
492- return combineLatest ( [ youtubeContainer , playerOptions ] )
495+ return combineLatest ( [ youtubeContainer , playerOptions , of ( ngZone ) ] )
493496 . pipe (
494497 skipUntilRememberLatest ( iframeApiAvailableObs ) ,
495498 scan ( syncPlayerState , undefined ) ,
@@ -507,7 +510,7 @@ function skipUntilRememberLatest<T>(notifier: Observable<boolean>): MonoTypeOper
507510/** Destroy the player if there are no options, or create the player if there are options. */
508511function syncPlayerState (
509512 player : UninitializedPlayer | undefined ,
510- [ container , videoOptions ] : [ HTMLElement , YT . PlayerOptions | undefined ] ,
513+ [ container , videoOptions , ngZone ] : [ HTMLElement , YT . PlayerOptions | undefined , NgZone ] ,
511514) : UninitializedPlayer | undefined {
512515 if ( ! videoOptions ) {
513516 if ( player ) {
@@ -519,7 +522,10 @@ function syncPlayerState(
519522 return player ;
520523 }
521524
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 ) ) ;
523529 // Bind videoId for future use.
524530 newPlayer . videoId = videoOptions . videoId ;
525531 return newPlayer ;
0 commit comments