@angular/youtube-player
Version:
Angular YouTube Player
1 lines • 50.8 kB
Source Map (JSON)
{"version":3,"file":"youtube-player.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/youtube-player/youtube-player-placeholder.ts","../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/youtube-player/youtube-player.ts","../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/youtube-player/youtube-module.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {Component, ViewEncapsulation, computed, input} from '@angular/core';\n\n/** Quality of the placeholder image. */\nexport type PlaceholderImageQuality = 'high' | 'standard' | 'low';\n\nconst VIDEO_ID_REGEX = /^[a-zA-Z0-9_-]+$/;\n\n@Component({\n selector: 'youtube-player-placeholder',\n encapsulation: ViewEncapsulation.None,\n template: `\n <button type=\"button\" class=\"youtube-player-placeholder-button\" [attr.aria-label]=\"buttonLabel()\">\n <svg\n height=\"100%\"\n version=\"1.1\"\n viewBox=\"0 0 68 48\"\n focusable=\"false\"\n aria-hidden=\"true\">\n <path d=\"M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z\" fill=\"#f00\"></path>\n <path d=\"M 45,24 27,14 27,34\" fill=\"#fff\"></path>\n </svg>\n </button>\n `,\n styleUrl: 'youtube-player-placeholder.css',\n host: {\n 'class': 'youtube-player-placeholder',\n '[class.youtube-player-placeholder-loading]': 'isLoading()',\n '[style.background-image]': '_backgroundImage()',\n '[style.width.px]': 'width()',\n '[style.height.px]': 'height()',\n },\n})\nexport class YouTubePlayerPlaceholder {\n /** ID of the video for which to show the placeholder. */\n readonly videoId = input.required<string>();\n\n /** Width of the video for which to show the placeholder. */\n readonly width = input.required<number>();\n\n /** Height of the video for which to show the placeholder. */\n readonly height = input.required<number>();\n\n /** Whether the video is currently being loaded. */\n readonly isLoading = input.required<boolean>();\n\n /** Accessible label for the play button. */\n readonly buttonLabel = input.required<string>();\n\n /** Quality of the placeholder image. */\n readonly quality = input.required<PlaceholderImageQuality>();\n\n /** Gets the background image showing the placeholder. */\n protected _backgroundImage = computed(() => {\n const quality = this.quality();\n const videoId = this.videoId();\n\n // Since we're interpolating the ID into a CSS value, we need\n // to ensure that it doesn't become an XSS attack vector.\n if (!VIDEO_ID_REGEX.test(videoId)) {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n console.error(\n `Skipping placeholder image generation for invalid YouTube video ID: ${videoId}`,\n );\n }\n return null;\n }\n\n let url: string;\n\n if (quality === 'low') {\n url = `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;\n } else if (quality === 'high') {\n url = `https://i.ytimg.com/vi/${videoId}/maxresdefault.jpg`;\n } else {\n url = `https://i.ytimg.com/vi_webp/${videoId}/sddefault.webp`;\n }\n\n return `url(${url})`;\n });\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n// Workaround for: https://github.com/bazelbuild/rules_nodejs/issues/1265\n/// <reference types=\"youtube\" preserve=\"true\" />\n\nimport {\n Component,\n ElementRef,\n Input,\n NgZone,\n OnDestroy,\n Output,\n ViewChild,\n ViewEncapsulation,\n PLATFORM_ID,\n OnChanges,\n SimpleChanges,\n booleanAttribute,\n numberAttribute,\n InjectionToken,\n inject,\n CSP_NONCE,\n ChangeDetectorRef,\n AfterViewInit,\n EventEmitter,\n} from '@angular/core';\nimport {isPlatformBrowser} from '@angular/common';\nimport {trustedResourceUrl} from 'safevalues';\nimport {setScriptSrc} from 'safevalues/dom';\nimport {Observable, of as observableOf, Subject, BehaviorSubject, fromEventPattern} from 'rxjs';\nimport {takeUntil, switchMap} from 'rxjs/operators';\nimport {PlaceholderImageQuality, YouTubePlayerPlaceholder} from './youtube-player-placeholder';\n\ntype YoutubeWindow = {\n onYouTubeIframeAPIReady?: (() => void) | undefined;\n};\n\n/** Injection token used to configure the `YouTubePlayer`. */\nexport const YOUTUBE_PLAYER_CONFIG = new InjectionToken<YouTubePlayerConfig>(\n 'YOUTUBE_PLAYER_CONFIG',\n);\n\n/** Object that can be used to configure the `YouTubePlayer`. */\nexport interface YouTubePlayerConfig {\n /** Whether to load the YouTube iframe API automatically. Defaults to `true`. */\n loadApi?: boolean;\n\n /**\n * By default the player shows a placeholder image instead of loading the YouTube API which\n * improves the initial page load performance. Use this option to disable the placeholder loading\n * behavior globally. Defaults to `false`.\n */\n disablePlaceholder?: boolean;\n\n /** Accessible label for the play button inside of the placeholder. */\n placeholderButtonLabel?: string;\n\n /**\n * Quality of the displayed placeholder image. Defaults to `standard`,\n * because not all video have a high-quality placeholder.\n */\n placeholderImageQuality?: PlaceholderImageQuality;\n}\n\nexport const DEFAULT_PLAYER_WIDTH = 640;\nexport const DEFAULT_PLAYER_HEIGHT = 390;\n\n/**\n * Object used to store the state of the player if the\n * user tries to interact with the API before it has been loaded.\n */\ninterface PendingPlayerState {\n playbackState?: PlayerState.PLAYING | PlayerState.PAUSED | PlayerState.CUED;\n playbackRate?: number;\n volume?: number;\n muted?: boolean;\n seek?: {seconds: number; allowSeekAhead: boolean};\n}\n\n/** Coercion function for time values. */\nfunction coerceTime(value: number | undefined): number | undefined {\n return value == null ? value : numberAttribute(value, 0);\n}\n\n/**\n * Equivalent of `YT.PlayerState` which we can't use, because it's meant to\n * be read off the `window` which we can't do before the API has been loaded.\n */\nenum PlayerState {\n UNSTARTED = -1,\n ENDED = 0,\n PLAYING = 1,\n PAUSED = 2,\n BUFFERING = 3,\n CUED = 5,\n}\n\n/**\n * Angular component that renders a YouTube player via the YouTube player\n * iframe API.\n * @see https://developers.google.com/youtube/iframe_api_reference\n */\n@Component({\n selector: 'youtube-player',\n encapsulation: ViewEncapsulation.None,\n imports: [YouTubePlayerPlaceholder],\n styleUrl: 'youtube-player.css',\n template: `\n @if (_shouldShowPlaceholder()) {\n <youtube-player-placeholder\n [videoId]=\"videoId!\"\n [width]=\"width\"\n [height]=\"height\"\n [isLoading]=\"_isLoading\"\n [buttonLabel]=\"placeholderButtonLabel\"\n [quality]=\"placeholderImageQuality\"\n (click)=\"_load(true)\"/>\n }\n <div [style.display]=\"_shouldShowPlaceholder() ? 'none' : ''\">\n <div #youtubeContainer></div>\n </div>\n `,\n})\nexport class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {\n private _ngZone = inject(NgZone);\n private readonly _nonce = inject(CSP_NONCE, {optional: true});\n private readonly _changeDetectorRef = inject(ChangeDetectorRef);\n private readonly _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private _player: YT.Player | undefined;\n private _pendingPlayer: YT.Player | undefined;\n private _existingApiReadyCallback: (() => void) | undefined;\n private _pendingPlayerState: PendingPlayerState | undefined;\n private readonly _destroyed = new Subject<void>();\n private readonly _playerChanges = new BehaviorSubject<YT.Player | undefined>(undefined);\n protected _isLoading = false;\n protected _hasPlaceholder = true;\n\n /** Whether we're currently rendering inside a browser. */\n private readonly _isBrowser: boolean;\n\n /** YouTube Video ID to view */\n @Input()\n videoId: string | undefined;\n\n /** Height of video player */\n @Input({transform: numberAttribute})\n get height(): number {\n return this._height;\n }\n set height(height: number | undefined) {\n this._height = height == null || isNaN(height) ? DEFAULT_PLAYER_HEIGHT : height;\n }\n private _height = DEFAULT_PLAYER_HEIGHT;\n\n /** Width of video player */\n @Input({transform: numberAttribute})\n get width(): number {\n return this._width;\n }\n set width(width: number | undefined) {\n this._width = width == null || isNaN(width) ? DEFAULT_PLAYER_WIDTH : width;\n }\n private _width = DEFAULT_PLAYER_WIDTH;\n\n /** The moment when the player is supposed to start playing */\n @Input({transform: coerceTime})\n startSeconds: number | undefined;\n\n /** The moment when the player is supposed to stop playing */\n @Input({transform: coerceTime})\n endSeconds: number | undefined;\n\n /** The suggested quality of the player */\n @Input()\n suggestedQuality: YT.SuggestedVideoQuality | undefined;\n\n /**\n * Extra parameters used to configure the player. See:\n * https://developers.google.com/youtube/player_parameters.html?playerVersion=HTML5#Parameters\n */\n @Input()\n playerVars: YT.PlayerVars | undefined;\n\n /** Whether cookies inside the player have been disabled. */\n @Input({transform: booleanAttribute})\n disableCookies: boolean = false;\n\n /** Whether to automatically load the YouTube iframe API. Defaults to `true`. */\n @Input({transform: booleanAttribute})\n loadApi: boolean;\n\n /**\n * By default the player shows a placeholder image instead of loading the YouTube API which\n * improves the initial page load performance. This input allows for the behavior to be disabled.\n */\n @Input({transform: booleanAttribute})\n disablePlaceholder: boolean = false;\n\n /**\n * Whether the iframe will attempt to load regardless of the status of the api on the\n * page. Set this to true if you don't want the `onYouTubeIframeAPIReady` field to be\n * set on the global window.\n */\n @Input({transform: booleanAttribute}) showBeforeIframeApiLoads: boolean = false;\n\n /** Accessible label for the play button inside of the placeholder. */\n @Input() placeholderButtonLabel: string;\n\n /**\n * Quality of the displayed placeholder image. Defaults to `standard`,\n * because not all video have a high-quality placeholder.\n */\n @Input() placeholderImageQuality: PlaceholderImageQuality;\n\n // Note: ready event can't go through the lazy emitter, because it\n // happens before the `_playerChanges` stream emits the new player.\n\n /** Emits when the player is initialized. */\n @Output() readonly ready: Observable<YT.PlayerEvent> = new EventEmitter<YT.PlayerEvent>();\n\n /** Emits when the state of the player has changed. */\n @Output() readonly stateChange: Observable<YT.OnStateChangeEvent> =\n this._getLazyEmitter<YT.OnStateChangeEvent>('onStateChange');\n\n /** Emits when there's an error while initializing the player. */\n @Output() readonly error: Observable<YT.OnErrorEvent> =\n this._getLazyEmitter<YT.OnErrorEvent>('onError');\n\n /** Emits when the underlying API of the player has changed. */\n @Output() readonly apiChange: Observable<YT.PlayerEvent> =\n this._getLazyEmitter<YT.PlayerEvent>('onApiChange');\n\n /** Emits when the playback quality has changed. */\n @Output() readonly playbackQualityChange: Observable<YT.OnPlaybackQualityChangeEvent> =\n this._getLazyEmitter<YT.OnPlaybackQualityChangeEvent>('onPlaybackQualityChange');\n\n /** Emits when the playback rate has changed. */\n @Output() readonly playbackRateChange: Observable<YT.OnPlaybackRateChangeEvent> =\n this._getLazyEmitter<YT.OnPlaybackRateChangeEvent>('onPlaybackRateChange');\n\n /** The element that will be replaced by the iframe. */\n @ViewChild('youtubeContainer', {static: true})\n youtubeContainer!: ElementRef<HTMLElement>;\n\n constructor() {\n const platformId = inject<Object>(PLATFORM_ID);\n const config = inject(YOUTUBE_PLAYER_CONFIG, {optional: true});\n this.loadApi = config?.loadApi ?? true;\n this.disablePlaceholder = !!config?.disablePlaceholder;\n this.placeholderButtonLabel = config?.placeholderButtonLabel || 'Play video';\n this.placeholderImageQuality = config?.placeholderImageQuality || 'standard';\n this._isBrowser = isPlatformBrowser(platformId);\n }\n\n ngAfterViewInit() {\n this._conditionallyLoad();\n }\n\n ngOnChanges(changes: SimpleChanges<this>): void {\n if (this._shouldRecreatePlayer(changes)) {\n this._conditionallyLoad();\n } else if (this._player) {\n if (changes['width'] || changes['height']) {\n this._setSize();\n }\n\n if (changes['suggestedQuality']) {\n this._setQuality();\n }\n\n if (changes['startSeconds'] || changes['endSeconds'] || changes['suggestedQuality']) {\n this._cuePlayer();\n }\n }\n }\n\n ngOnDestroy() {\n this._pendingPlayer?.destroy();\n\n if (this._player) {\n this._player.destroy();\n (window as YoutubeWindow).onYouTubeIframeAPIReady = this._existingApiReadyCallback;\n }\n\n this._playerChanges.complete();\n this._destroyed.next();\n this._destroyed.complete();\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#playVideo */\n playVideo() {\n if (this._player) {\n this._player.playVideo();\n } else {\n this._getPendingState().playbackState = PlayerState.PLAYING;\n this._load(true);\n }\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#pauseVideo */\n pauseVideo() {\n if (this._player) {\n this._player.pauseVideo();\n } else {\n this._getPendingState().playbackState = PlayerState.PAUSED;\n }\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#stopVideo */\n stopVideo() {\n if (this._player) {\n this._player.stopVideo();\n } else {\n // It seems like YouTube sets the player to CUED when it's stopped.\n this._getPendingState().playbackState = PlayerState.CUED;\n }\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#seekTo */\n seekTo(seconds: number, allowSeekAhead: boolean) {\n if (this._player) {\n this._player.seekTo(seconds, allowSeekAhead);\n } else {\n this._getPendingState().seek = {seconds, allowSeekAhead};\n }\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#mute */\n mute() {\n if (this._player) {\n this._player.mute();\n } else {\n this._getPendingState().muted = true;\n }\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#unMute */\n unMute() {\n if (this._player) {\n this._player.unMute();\n } else {\n this._getPendingState().muted = false;\n }\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#isMuted */\n isMuted(): boolean {\n if (this._player) {\n return this._player.isMuted();\n }\n\n if (this._pendingPlayerState) {\n return !!this._pendingPlayerState.muted;\n }\n\n return false;\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#setVolume */\n setVolume(volume: number) {\n if (this._player) {\n this._player.setVolume(volume);\n } else {\n this._getPendingState().volume = volume;\n }\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#getVolume */\n getVolume(): number {\n if (this._player) {\n return this._player.getVolume();\n }\n\n if (this._pendingPlayerState && this._pendingPlayerState.volume != null) {\n return this._pendingPlayerState.volume;\n }\n\n return 0;\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#setPlaybackRate */\n setPlaybackRate(playbackRate: number) {\n if (this._player) {\n return this._player.setPlaybackRate(playbackRate);\n } else {\n this._getPendingState().playbackRate = playbackRate;\n }\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#getPlaybackRate */\n getPlaybackRate(): number {\n if (this._player) {\n return this._player.getPlaybackRate();\n }\n\n if (this._pendingPlayerState && this._pendingPlayerState.playbackRate != null) {\n return this._pendingPlayerState.playbackRate;\n }\n\n return 0;\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#getAvailablePlaybackRates */\n getAvailablePlaybackRates(): number[] {\n return this._player ? this._player.getAvailablePlaybackRates() : [];\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#getVideoLoadedFraction */\n getVideoLoadedFraction(): number {\n return this._player ? this._player.getVideoLoadedFraction() : 0;\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#getPlayerState */\n getPlayerState(): YT.PlayerState | undefined {\n if (!this._isBrowser || !window.YT) {\n return undefined;\n }\n\n if (this._player) {\n return this._player.getPlayerState();\n }\n\n if (this._pendingPlayerState && this._pendingPlayerState.playbackState != null) {\n return this._pendingPlayerState.playbackState;\n }\n\n return PlayerState.UNSTARTED;\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#getCurrentTime */\n getCurrentTime(): number {\n if (this._player) {\n return this._player.getCurrentTime();\n }\n\n if (this._pendingPlayerState && this._pendingPlayerState.seek) {\n return this._pendingPlayerState.seek.seconds;\n }\n\n return 0;\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#getPlaybackQuality */\n getPlaybackQuality(): YT.SuggestedVideoQuality {\n return this._player ? this._player.getPlaybackQuality() : 'default';\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#getAvailableQualityLevels */\n getAvailableQualityLevels(): YT.SuggestedVideoQuality[] {\n return this._player ? this._player.getAvailableQualityLevels() : [];\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#getDuration */\n getDuration(): number {\n return this._player ? this._player.getDuration() : 0;\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#getVideoUrl */\n getVideoUrl(): string {\n return this._player ? this._player.getVideoUrl() : '';\n }\n\n /** See https://developers.google.com/youtube/iframe_api_reference#getVideoEmbedCode */\n getVideoEmbedCode(): string {\n return this._player ? this._player.getVideoEmbedCode() : '';\n }\n\n /**\n * Attempts to put the player into fullscreen mode, depending on browser support.\n * @param options Options controlling how the element behaves in fullscreen mode.\n */\n async requestFullscreen(options?: FullscreenOptions): Promise<void> {\n // Note that we do this on the host, rather than the iframe, because it allows us to handle the\n // placeholder in fullscreen mode. Null check the method since it's not supported everywhere.\n const element = this._elementRef.nativeElement;\n return element.requestFullscreen\n ? element.requestFullscreen(options)\n : Promise.reject(new Error('Fullscreen API not supported by browser.'));\n }\n\n /**\n * Loads the YouTube API and sets up the player.\n * @param playVideo Whether to automatically play the video once the player is loaded.\n */\n protected _load(playVideo: boolean) {\n // Don't do anything if we're not in a browser environment.\n if (!this._isBrowser) {\n return;\n }\n\n // Might be clobbered by something like `<form id=\"YT\"><input name=\"Player\"></form>`.\n if (\n typeof window.YT !== 'object' ||\n !window.YT ||\n !window.YT.Player ||\n typeof window.YT.Player !== 'function'\n ) {\n if (this.loadApi) {\n this._isLoading = true;\n loadApi(this._nonce);\n } else if (this.showBeforeIframeApiLoads && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw new Error(\n 'Namespace YT not found, cannot construct embedded youtube player. ' +\n 'Please install the YouTube Player API Reference for iframe Embeds: ' +\n 'https://developers.google.com/youtube/iframe_api_reference',\n );\n }\n\n const existingCallback = (window as YoutubeWindow).onYouTubeIframeAPIReady;\n\n // The callback might be clobbered by an element with an ID of `onYouTubeIframeAPIReady`.\n if (typeof existingCallback === 'function') {\n this._existingApiReadyCallback = (window as YoutubeWindow).onYouTubeIframeAPIReady;\n }\n\n (window as YoutubeWindow).onYouTubeIframeAPIReady = () => {\n this._existingApiReadyCallback?.();\n this._ngZone.run(() => this._createPlayer(playVideo));\n };\n } else {\n this._createPlayer(playVideo);\n }\n }\n\n /** Loads the player depending on the internal state of the component. */\n private _conditionallyLoad() {\n // If the placeholder isn't shown anymore, we have to trigger a load.\n if (!this._shouldShowPlaceholder()) {\n this._load(false);\n } else if (this.playerVars?.autoplay === 1) {\n // If it's an autoplaying video, we have to hide the placeholder and start playing.\n this._load(true);\n }\n }\n\n /** Whether to show the placeholder element. */\n protected _shouldShowPlaceholder(): boolean {\n if (this.disablePlaceholder) {\n return false;\n }\n\n // Since we don't load the API on the server, we show the placeholder permanently.\n if (!this._isBrowser) {\n return true;\n }\n\n return this._hasPlaceholder && !!this.videoId && !this._player;\n }\n\n /** Gets an object that should be used to store the temporary API state. */\n private _getPendingState(): PendingPlayerState {\n if (!this._pendingPlayerState) {\n this._pendingPlayerState = {};\n }\n\n return this._pendingPlayerState;\n }\n\n /**\n * Determines whether a change in the component state\n * requires the YouTube player to be recreated.\n */\n private _shouldRecreatePlayer(changes: SimpleChanges): boolean {\n const change =\n changes['videoId'] ||\n changes['playerVars'] ||\n changes['disableCookies'] ||\n changes['disablePlaceholder'];\n return !!change && !change.isFirstChange();\n }\n\n /**\n * Creates a new YouTube player and destroys the existing one.\n * @param playVideo Whether to play the video once it loads.\n */\n private _createPlayer(playVideo: boolean) {\n this._player?.destroy();\n this._pendingPlayer?.destroy();\n\n // A player can't be created if the API isn't loaded,\n // or there isn't a video or playlist to be played.\n if (\n typeof (window as Window & {YT?: typeof YT}).YT === 'undefined' ||\n (!this.videoId && !this.playerVars?.list)\n ) {\n return;\n }\n\n // Important! We need to create the Player object outside of the `NgZone`, because it kicks\n // off a 250ms setInterval which will continually trigger change detection if we don't.\n const params: YT.PlayerOptions = {\n host: this.disableCookies ? 'https://www.youtube-nocookie.com' : undefined,\n width: this.width,\n height: this.height,\n // Calling `playVideo` on load doesn't appear to actually play\n // the video so we need to trigger it through `playerVars` instead.\n playerVars: playVideo ? {...(this.playerVars || {}), autoplay: 1} : this.playerVars,\n };\n // We only want to injecct a videoId if one is provided, otherwise loading a playlist via\n // playerVars.list, the missing videoId will create a null value in the youtube iframe url\n // and that can trigger a JS error `Invalid video id` in widget api.\n if (this.videoId) {\n params.videoId = this.videoId;\n }\n const player = this._ngZone.runOutsideAngular(\n () =>\n new (window as Window & {YT?: typeof YT}).YT!.Player(\n this.youtubeContainer.nativeElement,\n params,\n ),\n );\n\n const whenReady = (event: YT.PlayerEvent) => {\n // Only assign the player once it's ready, otherwise YouTube doesn't expose some APIs.\n this._ngZone.run(() => {\n this._isLoading = false;\n this._hasPlaceholder = false;\n this._player = player;\n this._pendingPlayer = undefined;\n player.removeEventListener('onReady', whenReady);\n this._playerChanges.next(player);\n (this.ready as EventEmitter<YT.PlayerEvent>).emit(event);\n this._setSize();\n this._setQuality();\n\n if (this._pendingPlayerState) {\n this._applyPendingPlayerState(player, this._pendingPlayerState);\n this._pendingPlayerState = undefined;\n }\n\n // Only cue the player when it either hasn't started yet or it's cued,\n // otherwise cuing it can interrupt a player with autoplay enabled.\n const state = player.getPlayerState();\n if (state === PlayerState.UNSTARTED || state === PlayerState.CUED || state == null) {\n this._cuePlayer();\n } else if (\n (playVideo || this.playerVars?.autoplay === 1) &&\n this.startSeconds &&\n this.startSeconds > 0\n ) {\n // We have to use `seekTo` when `startSeconds` are specified with a playing video\n // (either from user interaction or autoplay). The \"proper\" way to do it would be to\n // either go through `cueVideoById` or `playerVars.start`, but at the time of writing\n // both end up resetting the video to the state as if the user hasn't interacted with it.\n player.seekTo(this.startSeconds, true);\n }\n\n this._changeDetectorRef.markForCheck();\n });\n };\n\n this._pendingPlayer = player;\n player.addEventListener('onReady', whenReady);\n }\n\n /** Applies any state that changed before the player was initialized. */\n private _applyPendingPlayerState(player: YT.Player, pendingState: PendingPlayerState): void {\n const {playbackState, playbackRate, volume, muted, seek} = pendingState;\n\n switch (playbackState) {\n case PlayerState.PLAYING:\n player.playVideo();\n break;\n case PlayerState.PAUSED:\n player.pauseVideo();\n break;\n case PlayerState.CUED:\n player.stopVideo();\n break;\n }\n\n if (playbackRate != null) {\n player.setPlaybackRate(playbackRate);\n }\n\n if (volume != null) {\n player.setVolume(volume);\n }\n\n if (muted != null) {\n muted ? player.mute() : player.unMute();\n }\n\n if (seek != null) {\n player.seekTo(seek.seconds, seek.allowSeekAhead);\n }\n }\n\n /** Cues the player based on the current component state. */\n private _cuePlayer() {\n if (this._player && this.videoId) {\n this._player.cueVideoById({\n videoId: this.videoId,\n startSeconds: this.startSeconds,\n endSeconds: this.endSeconds,\n suggestedQuality: this.suggestedQuality,\n });\n }\n }\n\n /** Sets the player's size based on the current input values. */\n private _setSize() {\n this._player?.setSize(this.width, this.height);\n }\n\n /** Sets the player's quality based on the current input values. */\n private _setQuality() {\n if (this._player && this.suggestedQuality) {\n this._player.setPlaybackQuality(this.suggestedQuality);\n }\n }\n\n /** Gets an observable that adds an event listener to the player when a user subscribes to it. */\n private _getLazyEmitter<T extends YT.PlayerEvent>(name: keyof YT.Events): Observable<T> {\n // Start with the stream of players. This way the events will be transferred\n // over to the new player if it gets swapped out under-the-hood.\n return this._playerChanges.pipe(\n // Switch to the bound event. `switchMap` ensures that the old event is removed when the\n // player is changed. If there's no player, return an observable that never emits.\n switchMap(player => {\n return player\n ? fromEventPattern<T>(\n listener => {\n player.addEventListener(name, listener);\n },\n listener => {\n // The API seems to throw when we try to unbind from a destroyed player and it\n // doesn'texpose whether the player has been destroyed so we have to wrap it in a\n // try/catch to prevent the entire stream from erroring out.\n try {\n player?.removeEventListener?.(name, listener);\n } catch {}\n },\n )\n : observableOf<T>();\n }),\n // By default we run all the API interactions outside the zone\n // so we have to bring the events back in manually when they emit.\n source =>\n new Observable<T>(observer =>\n source.subscribe({\n next: value => this._ngZone.run(() => observer.next(value)),\n error: error => observer.error(error),\n complete: () => observer.complete(),\n }),\n ),\n // Ensures that everything is cleared out on destroy.\n takeUntil(this._destroyed),\n );\n }\n}\n\nlet apiLoaded = false;\n\n/** Loads the YouTube API from a specified URL only once. */\nfunction loadApi(nonce: string | null): void {\n if (apiLoaded) {\n return;\n }\n\n // We can use `document` directly here, because this logic doesn't run outside the browser.\n const url = trustedResourceUrl`https://www.youtube.com/iframe_api`;\n const script = document.createElement('script');\n const callback = (event: Event) => {\n script.removeEventListener('load', callback);\n script.removeEventListener('error', callback);\n\n if (event.type === 'error') {\n apiLoaded = false;\n\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n console.error(`Failed to load YouTube API from ${url}`);\n }\n }\n };\n script.addEventListener('load', callback);\n script.addEventListener('error', callback);\n setScriptSrc(script, url);\n script.async = true;\n\n if (nonce) {\n script.setAttribute('nonce', nonce);\n }\n\n // Set this immediately to true so we don't start loading another script\n // while this one is pending. If loading fails, we'll flip it back to false.\n apiLoaded = true;\n document.body.appendChild(script);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {NgModule} from '@angular/core';\nimport {YouTubePlayer} from './youtube-player';\n\n@NgModule({\n imports: [YouTubePlayer],\n exports: [YouTubePlayer],\n})\nexport class YouTubePlayerModule {}\n"],"names":["observableOf"],"mappings":"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