@@ -69,6 +69,9 @@ interface Player extends YT.Player {
69
69
// The only field available is destroy and addEventListener.
70
70
type UninitializedPlayer = Pick < Player , 'videoId' | 'destroy' | 'addEventListener' > ;
71
71
72
+ /** Whether we're currently rendering inside a browser. */
73
+ const isBrowser = typeof window === 'object' && ! ! window ;
74
+
72
75
/**
73
76
* Angular component that renders a YouTube player via the YouTube player
74
77
* iframe API.
@@ -80,7 +83,7 @@ type UninitializedPlayer = Pick<Player, 'videoId' | 'destroy' | 'addEventListene
80
83
changeDetection : ChangeDetectionStrategy . OnPush ,
81
84
encapsulation : ViewEncapsulation . None ,
82
85
// This div is *replaced* by the YouTube player embed.
83
- template : '<div #youtube_container ></div>' ,
86
+ template : '<div #youtubeContainer ></div>' ,
84
87
} )
85
88
export class YouTubePlayer implements AfterViewInit , OnDestroy , OnInit {
86
89
/** YouTube Video ID to view */
@@ -147,15 +150,21 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
147
150
@Output ( ) playbackRateChange = new EventEmitter < YT . OnPlaybackRateChangeEvent > ( ) ;
148
151
149
152
/** The element that will be replaced by the iframe. */
150
- @ViewChild ( 'youtube_container' , { static : false } ) youtubeContainer : ElementRef | undefined ;
153
+ @ViewChild ( 'youtubeContainer' , { static : false } )
154
+ youtubeContainer : ElementRef < HTMLElement > ;
155
+
151
156
private _youtubeContainer = new EventEmitter < HTMLElement > ( ) ;
152
157
private _destroyed = new EventEmitter < undefined > ( ) ;
153
-
154
158
private _player : Player | undefined ;
155
159
156
160
constructor ( private _ngZone : NgZone ) { }
157
161
158
162
ngOnInit ( ) {
163
+ // Don't do anything if we're not in a browser environment.
164
+ if ( ! isBrowser ) {
165
+ return ;
166
+ }
167
+
159
168
let iframeApiAvailableObs : Observable < boolean > = observableOf ( true ) ;
160
169
if ( ! window . YT ) {
161
170
if ( this . showBeforeIframeApiLoads ) {
@@ -223,19 +232,15 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
223
232
}
224
233
225
234
ngAfterViewInit ( ) {
226
- if ( ! this . youtubeContainer ) {
227
- return ;
228
- }
229
235
this . _youtubeContainer . emit ( this . youtubeContainer . nativeElement ) ;
230
236
}
231
237
232
238
ngOnDestroy ( ) {
233
- if ( ! this . _player ) {
234
- return ;
239
+ if ( this . _player ) {
240
+ this . _player . destroy ( ) ;
241
+ window . onYouTubeIframeAPIReady = undefined ;
242
+ this . _destroyed . emit ( ) ;
235
243
}
236
- this . _player . destroy ( ) ;
237
- window . onYouTubeIframeAPIReady = undefined ;
238
- this . _destroyed . emit ( ) ;
239
244
}
240
245
241
246
private _runInZone < T extends ( ...args : any [ ] ) => void > ( callback : T ) :
@@ -249,166 +254,122 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
249
254
250
255
/** See https://developers.google.com/youtube/iframe_api_reference#playVideo */
251
256
playVideo ( ) {
252
- if ( ! this . _player ) {
253
- return ;
257
+ if ( this . _player ) {
258
+ this . _player . playVideo ( ) ;
254
259
}
255
- this . _player . playVideo ( ) ;
256
260
}
257
261
258
262
/** See https://developers.google.com/youtube/iframe_api_reference#pauseVideo */
259
263
pauseVideo ( ) {
260
- if ( ! this . _player ) {
261
- return ;
264
+ if ( this . _player ) {
265
+ this . _player . pauseVideo ( ) ;
262
266
}
263
- this . _player . pauseVideo ( ) ;
264
267
}
265
268
266
269
/** See https://developers.google.com/youtube/iframe_api_reference#stopVideo */
267
270
stopVideo ( ) {
268
- if ( ! this . _player ) {
269
- return ;
271
+ if ( this . _player ) {
272
+ this . _player . stopVideo ( ) ;
270
273
}
271
- this . _player . stopVideo ( ) ;
272
274
}
273
275
274
276
/** See https://developers.google.com/youtube/iframe_api_reference#seekTo */
275
277
seekTo ( seconds : number , allowSeekAhead : boolean ) {
276
- if ( ! this . _player ) {
277
- return ;
278
+ if ( this . _player ) {
279
+ this . _player . seekTo ( seconds , allowSeekAhead ) ;
278
280
}
279
- this . _player . seekTo ( seconds , allowSeekAhead ) ;
280
281
}
281
282
282
283
/** See https://developers.google.com/youtube/iframe_api_reference#mute */
283
284
mute ( ) {
284
- if ( ! this . _player ) {
285
- return ;
285
+ if ( this . _player ) {
286
+ this . _player . mute ( ) ;
286
287
}
287
- this . _player . mute ( ) ;
288
288
}
289
289
290
290
/** See https://developers.google.com/youtube/iframe_api_reference#unMute */
291
291
unMute ( ) {
292
- if ( ! this . _player ) {
293
- return ;
292
+ if ( this . _player ) {
293
+ this . _player . unMute ( ) ;
294
294
}
295
- this . _player . unMute ( ) ;
296
295
}
297
296
298
297
/** See https://developers.google.com/youtube/iframe_api_reference#isMuted */
299
298
isMuted ( ) : boolean {
300
- if ( ! this . _player ) {
301
- return false ;
302
- }
303
- return this . _player . isMuted ( ) ;
299
+ return ! this . _player || this . _player . isMuted ( ) ;
304
300
}
305
301
306
302
/** See https://developers.google.com/youtube/iframe_api_reference#setVolume */
307
303
setVolume ( volume : number ) {
308
- if ( ! this . _player ) {
309
- return ;
304
+ if ( this . _player ) {
305
+ this . _player . setVolume ( volume ) ;
310
306
}
311
- this . _player . setVolume ( volume ) ;
312
307
}
313
308
314
309
/** See https://developers.google.com/youtube/iframe_api_reference#getVolume */
315
310
getVolume ( ) : number {
316
- if ( ! this . _player ) {
317
- return 0 ;
318
- }
319
- return this . _player . getVolume ( ) ;
311
+ return this . _player ? this . _player . getVolume ( ) : 0 ;
320
312
}
321
313
322
314
/** See https://developers.google.com/youtube/iframe_api_reference#setPlaybackRate */
323
315
setPlaybackRate ( playbackRate : number ) {
324
- if ( ! this . _player ) {
325
- return ;
316
+ if ( this . _player ) {
317
+ return this . _player . setPlaybackRate ( playbackRate ) ;
326
318
}
327
- return this . _player . setPlaybackRate ( playbackRate ) ;
328
319
}
329
320
330
321
/** See https://developers.google.com/youtube/iframe_api_reference#getPlaybackRate */
331
322
getPlaybackRate ( ) : number {
332
- if ( ! this . _player ) {
333
- return 0 ;
334
- }
335
- return this . _player . getPlaybackRate ( ) ;
323
+ return this . _player ? this . _player . getPlaybackRate ( ) : 0 ;
336
324
}
337
325
338
326
/** See https://developers.google.com/youtube/iframe_api_reference#getAvailablePlaybackRates */
339
327
getAvailablePlaybackRates ( ) : number [ ] {
340
- if ( ! this . _player ) {
341
- return [ ] ;
342
- }
343
- return this . _player . getAvailablePlaybackRates ( ) ;
328
+ return this . _player ? this . _player . getAvailablePlaybackRates ( ) : [ ] ;
344
329
}
345
330
346
331
/** See https://developers.google.com/youtube/iframe_api_reference#getVideoLoadedFraction */
347
332
getVideoLoadedFraction ( ) : number {
348
- if ( ! this . _player ) {
349
- return 0 ;
350
- }
351
- return this . _player . getVideoLoadedFraction ( ) ;
333
+ return this . _player ? this . _player . getVideoLoadedFraction ( ) : 0 ;
352
334
}
353
335
354
336
/** See https://developers.google.com/youtube/iframe_api_reference#getPlayerState */
355
337
getPlayerState ( ) : YT . PlayerState | undefined {
356
- if ( ! window . YT ) {
338
+ if ( isBrowser && ! window . YT ) {
357
339
return undefined ;
358
340
}
359
341
360
- if ( ! this . _player ) {
361
- return YT . PlayerState . UNSTARTED ;
362
- }
363
- return this . _player . getPlayerState ( ) ;
342
+ return this . _player ? this . _player . getPlayerState ( ) : YT . PlayerState . UNSTARTED ;
364
343
}
365
344
366
345
/** See https://developers.google.com/youtube/iframe_api_reference#getCurrentTime */
367
346
getCurrentTime ( ) : number {
368
- if ( ! this . _player ) {
369
- return 0 ;
370
- }
371
- return this . _player . getCurrentTime ( ) ;
347
+ return this . _player ? this . _player . getCurrentTime ( ) : 0 ;
372
348
}
373
349
374
350
/** See https://developers.google.com/youtube/iframe_api_reference#getPlaybackQuality */
375
351
getPlaybackQuality ( ) : YT . SuggestedVideoQuality {
376
- if ( ! this . _player ) {
377
- return 'default' ;
378
- }
379
- return this . _player . getPlaybackQuality ( ) ;
352
+ return this . _player ? this . _player . getPlaybackQuality ( ) : 'default' ;
380
353
}
381
354
382
355
/** See https://developers.google.com/youtube/iframe_api_reference#getAvailableQualityLevels */
383
356
getAvailableQualityLevels ( ) : YT . SuggestedVideoQuality [ ] {
384
- if ( ! this . _player ) {
385
- return [ ] ;
386
- }
387
- return this . _player . getAvailableQualityLevels ( ) ;
357
+ return this . _player ? this . _player . getAvailableQualityLevels ( ) : [ ] ;
388
358
}
389
359
390
360
/** See https://developers.google.com/youtube/iframe_api_reference#getDuration */
391
361
getDuration ( ) : number {
392
- if ( ! this . _player ) {
393
- return 0 ;
394
- }
395
- return this . _player . getDuration ( ) ;
362
+ return this . _player ? this . _player . getDuration ( ) : 0 ;
396
363
}
397
364
398
365
/** See https://developers.google.com/youtube/iframe_api_reference#getVideoUrl */
399
366
getVideoUrl ( ) : string {
400
- if ( ! this . _player ) {
401
- return '' ;
402
- }
403
- return this . _player . getVideoUrl ( ) ;
367
+ return this . _player ? this . _player . getVideoUrl ( ) : '' ;
404
368
}
405
369
406
370
/** See https://developers.google.com/youtube/iframe_api_reference#getVideoEmbedCode */
407
371
getVideoEmbedCode ( ) : string {
408
- if ( ! this . _player ) {
409
- return '' ;
410
- }
411
- return this . _player . getVideoEmbedCode ( ) ;
372
+ return this . _player ? this . _player . getVideoEmbedCode ( ) : '' ;
412
373
}
413
374
}
414
375
0 commit comments