diff --git a/src/dev-app/youtube-player/BUILD.bazel b/src/dev-app/youtube-player/BUILD.bazel
index bb06abeb2eca..956ed6cd4248 100644
--- a/src/dev-app/youtube-player/BUILD.bazel
+++ b/src/dev-app/youtube-player/BUILD.bazel
@@ -10,6 +10,7 @@ ng_module(
":youtube_player_demo_scss",
],
deps = [
+ "//src/material/button",
"//src/material/checkbox",
"//src/material/radio",
"//src/youtube-player",
diff --git a/src/dev-app/youtube-player/youtube-player-demo.html b/src/dev-app/youtube-player/youtube-player-demo.html
index 4225e9f7bd9e..209eb6ec08e6 100644
--- a/src/dev-app/youtube-player/youtube-player-demo.html
+++ b/src/dev-app/youtube-player/youtube-player-demo.html
@@ -15,14 +15,19 @@
Basic Example
Disable placeholder
Start at 30s
-
+
+
+
+
Placeholder quality comparison (high to low)
diff --git a/src/dev-app/youtube-player/youtube-player-demo.ts b/src/dev-app/youtube-player/youtube-player-demo.ts
index a70864d23b37..605fd0712def 100644
--- a/src/dev-app/youtube-player/youtube-player-demo.ts
+++ b/src/dev-app/youtube-player/youtube-player-demo.ts
@@ -17,6 +17,7 @@ import {
inject,
} from '@angular/core';
import {FormsModule} from '@angular/forms';
+import {MatButton} from '@angular/material/button';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatRadioModule} from '@angular/material/radio';
import {PlaceholderImageQuality, YouTubePlayer} from '@angular/youtube-player';
@@ -79,7 +80,7 @@ const VIDEOS: Video[] = [
selector: 'youtube-player-demo',
templateUrl: 'youtube-player-demo.html',
styleUrl: 'youtube-player-demo.css',
- imports: [FormsModule, MatRadioModule, MatCheckboxModule, YouTubePlayer],
+ imports: [FormsModule, MatRadioModule, MatCheckboxModule, MatButton, YouTubePlayer],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class YouTubePlayerDemo implements AfterViewInit, OnDestroy {
diff --git a/src/youtube-player/BUILD.bazel b/src/youtube-player/BUILD.bazel
index 27d267619979..d5d65d4e7fce 100644
--- a/src/youtube-player/BUILD.bazel
+++ b/src/youtube-player/BUILD.bazel
@@ -19,6 +19,7 @@ ng_module(
],
),
assets = [
+ ":youtube_player_scss",
":youtube_player_placeholder_scss",
],
deps = [
@@ -30,6 +31,11 @@ ng_module(
],
)
+sass_binary(
+ name = "youtube_player_scss",
+ src = "youtube-player.scss",
+)
+
sass_binary(
name = "youtube_player_placeholder_scss",
src = "youtube-player-placeholder.scss",
diff --git a/src/youtube-player/youtube-player-placeholder.scss b/src/youtube-player/youtube-player-placeholder.scss
index 69c2530afeba..a05b747a007d 100644
--- a/src/youtube-player/youtube-player-placeholder.scss
+++ b/src/youtube-player/youtube-player-placeholder.scss
@@ -14,6 +14,11 @@
// Note that they use a base64 image, likely for performance reasons. We can't use the
// image, because it can break users with a CSP that doesn't allow `data:` URLs.
box-shadow: inset 0 120px 90px -90px rgba(0, 0, 0, 0.8);
+
+ :fullscreen & {
+ min-width: 100vw;
+ min-height: 100vh;
+ }
}
.youtube-player-placeholder-button {
diff --git a/src/youtube-player/youtube-player.scss b/src/youtube-player/youtube-player.scss
new file mode 100644
index 000000000000..65152ad1811a
--- /dev/null
+++ b/src/youtube-player/youtube-player.scss
@@ -0,0 +1,6 @@
+youtube-player:fullscreen {
+ &, iframe {
+ min-width: 100vw;
+ min-height: 100vh;
+ }
+}
diff --git a/src/youtube-player/youtube-player.ts b/src/youtube-player/youtube-player.ts
index 665ae54b90f3..398b8d8711bc 100644
--- a/src/youtube-player/youtube-player.ts
+++ b/src/youtube-player/youtube-player.ts
@@ -113,6 +113,7 @@ enum PlayerState {
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
imports: [YouTubePlayerPlaceholder],
+ styleUrl: 'youtube-player.css',
template: `
@if (_shouldShowPlaceholder()) {
>(ElementRef);
private _player: YT.Player | undefined;
private _pendingPlayer: YT.Player | undefined;
private _existingApiReadyCallback: (() => void) | undefined;
@@ -474,6 +476,19 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
return this._player ? this._player.getVideoEmbedCode() : '';
}
+ /**
+ * Attempts to put the player into fullscreen mode, depending on browser support.
+ * @param options Options controlling how the element behaves in fullscreen mode.
+ */
+ async requestFullscreen(options?: FullscreenOptions): Promise {
+ // Note that we do this on the host, rather than the iframe, because it allows us to handle the
+ // placeholder in fullscreen mode. Null check the method since it's not supported everywhere.
+ const element = this._elementRef.nativeElement;
+ return element.requestFullscreen
+ ? element.requestFullscreen(options)
+ : Promise.reject(new Error('Fullscreen API not supported by browser.'));
+ }
+
/**
* Loads the YouTube API and sets up the player.
* @param playVideo Whether to automatically play the video once the player is loaded.
diff --git a/tools/public_api_guard/youtube-player/youtube-player.md b/tools/public_api_guard/youtube-player/youtube-player.md
index 236abe369746..0ef8c4112985 100644
--- a/tools/public_api_guard/youtube-player/youtube-player.md
+++ b/tools/public_api_guard/youtube-player/youtube-player.md
@@ -80,6 +80,7 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
playerVars: YT.PlayerVars | undefined;
playVideo(): void;
readonly ready: Observable;
+ requestFullscreen(options?: FullscreenOptions): Promise;
seekTo(seconds: number, allowSeekAhead: boolean): void;
setPlaybackRate(playbackRate: number): void;
setVolume(volume: number): void;