@@ -39,6 +39,9 @@ declare global {
3939 interface Window { YT : typeof YT | undefined ; }
4040}
4141
42+ export const DEFAULT_PLAYER_WIDTH = 640 ;
43+ export const DEFAULT_PLAYER_HEIGHT = 390 ;
44+
4245// The native YT.Player doesn't expose the set videoId, but we need it for
4346// convenience.
4447interface Player extends YT . Player {
@@ -62,17 +65,33 @@ type UninitializedPlayer = Pick<Player, 'videoId' | 'destroy' | 'addEventListene
6265} )
6366export class YouTubePlayer implements AfterViewInit , OnDestroy {
6467 /** YouTube Video ID to view */
65- get videoId ( ) : string | undefined {
66- return this . _player && this . _player . videoId ;
67- }
68-
6968 @Input ( )
69+ get videoId ( ) : string | undefined { return this . _player && this . _player . videoId ; }
7070 set videoId ( videoId : string | undefined ) {
7171 this . _videoId . emit ( videoId ) ;
7272 }
73-
7473 private _videoId = new EventEmitter < string | undefined > ( ) ;
7574
75+ /** Height of video player */
76+ @Input ( )
77+ get height ( ) : number | undefined { return this . _height ; }
78+ set height ( height : number | undefined ) {
79+ this . _height = height || DEFAULT_PLAYER_HEIGHT ;
80+ this . _heightObs . emit ( this . _height ) ;
81+ }
82+ private _height = DEFAULT_PLAYER_HEIGHT ;
83+ private _heightObs = new EventEmitter < number > ( ) ;
84+
85+ /** Width of video player */
86+ @Input ( )
87+ get width ( ) : number | undefined { return this . _width ; }
88+ set width ( width : number | undefined ) {
89+ this . _width = width || DEFAULT_PLAYER_WIDTH ;
90+ this . _widthObs . emit ( this . _width ) ;
91+ }
92+ private _width = DEFAULT_PLAYER_WIDTH ;
93+ private _widthObs = new EventEmitter < number > ( ) ;
94+
7695 /** Outputs are direct proxies from the player itself. */
7796 @Output ( ) ready = new EventEmitter < YT . PlayerEvent > ( ) ;
7897 @Output ( ) stateChange = new EventEmitter < YT . OnStateChangeEvent > ( ) ;
@@ -94,17 +113,25 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy {
94113 'Please install the YouTube Player API Reference for iframe Embeds: ' +
95114 'https://developers.google.com/youtube/iframe_api_reference' ) ;
96115 }
116+ // Add initial values to all of the inputs.
117+ const widthObs = this . _widthObs . pipe ( startWith ( this . _width ) ) ;
118+ const heightObs = this . _heightObs . pipe ( startWith ( this . _height ) ) ;
119+
97120 /** An observable of the currently loaded player. */
98121 const playerObs =
99122 createPlayerObservable (
100123 this . _youtubeContainer ,
101124 this . _videoId ,
125+ widthObs ,
126+ heightObs ,
102127 this . createEventsBoundInZone ( ) ,
103128 ) . pipe ( waitUntilReady ( ) , takeUntil ( this . _destroyed ) , publish ( ) ) ;
104129
105130 /** Set up side effects to bind inputs to the player. */
106131 playerObs . subscribe ( player => this . _player = player ) ;
107132
133+ bindSizeToPlayer ( playerObs , widthObs , heightObs ) ;
134+
108135 bindCueVideoCall ( playerObs , this . _videoId , this . _destroyed ) ;
109136
110137 // After all of the subscriptions are set up, connect the observable.
@@ -146,6 +173,16 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy {
146173 }
147174}
148175
176+ /** Listens to changes to the given width and height and sets it on the player. */
177+ function bindSizeToPlayer (
178+ playerObs : Observable < YT . Player | undefined > ,
179+ widthObs : Observable < number > ,
180+ heightObs : Observable < number >
181+ ) {
182+ return combineLatest ( playerObs , widthObs , heightObs )
183+ . subscribe ( ( [ player , width , height ] ) => player && player . setSize ( width , height ) ) ;
184+ }
185+
149186/**
150187 * Returns an observable that emits the loaded player once it's ready. Certain properties/methods
151188 * won't be available until the iframe finishes loading.
@@ -190,13 +227,16 @@ function fromPlayerOnReady(player: UninitializedPlayer): Observable<Player> {
190227function createPlayerObservable (
191228 youtubeContainer : Observable < HTMLElement > ,
192229 videoIdObs : Observable < string | undefined > ,
230+ widthObs : Observable < number > ,
231+ heightObs : Observable < number > ,
193232 events : YT . Events ,
194233) : Observable < UninitializedPlayer | undefined > {
195234
196235 const playerOptions =
197236 videoIdObs
198237 . pipe (
199- map ( ( videoId ) => videoId ? ( { videoId, events} ) : undefined ) ,
238+ withLatestFrom ( combineLatest ( widthObs , heightObs ) ) ,
239+ map ( ( [ videoId , [ width , height ] ] ) => videoId ? ( { videoId, width, height, events} ) : undefined ) ,
200240 ) ;
201241
202242 return combineLatest ( youtubeContainer , playerOptions )
0 commit comments