Skip to content

Commit d6fd276

Browse files
authoredFeb 19, 2025··
feat(youtube-player): add API to put the player in fullscreen mode (#30491)
Adds a method on the `YouTubePlayer` to put the element in fullscreen mode. This is a bit more involved than just calling `requestFullScreen`, because we also need to change the styles to ensure that the placeholder and the `iframe` cover the whole screen. Fixes #30485.
1 parent f0d6658 commit d6fd276

File tree

8 files changed

+49
-9
lines changed

8 files changed

+49
-9
lines changed
 

‎src/dev-app/youtube-player/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ ng_module(
1010
":youtube_player_demo_scss",
1111
],
1212
deps = [
13+
"//src/material/button",
1314
"//src/material/checkbox",
1415
"//src/material/radio",
1516
"//src/youtube-player",

‎src/dev-app/youtube-player/youtube-player-demo.html

+13-8
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,19 @@ <h2>Basic Example</h2>
1515
<mat-checkbox [(ngModel)]="disablePlaceholder">Disable placeholder</mat-checkbox>
1616
<mat-checkbox [(ngModel)]="startAt30s">Start at 30s</mat-checkbox>
1717
</div>
18-
<youtube-player [videoId]="selectedVideoId"
19-
[playerVars]="playerVars"
20-
[startSeconds]="startAt30s ? 30 : 0"
21-
[width]="videoWidth"
22-
[height]="videoHeight"
23-
[disableCookies]="disableCookies"
24-
[disablePlaceholder]="disablePlaceholder"
25-
[placeholderImageQuality]="placeholderQuality"></youtube-player>
18+
<div class="demo-video-selection">
19+
<button mat-button (click)="player.requestFullscreen()">Make fullscreen</button>
20+
</div>
21+
<youtube-player
22+
#player
23+
[videoId]="selectedVideoId"
24+
[playerVars]="playerVars"
25+
[startSeconds]="startAt30s ? 30 : 0"
26+
[width]="videoWidth"
27+
[height]="videoHeight"
28+
[disableCookies]="disableCookies"
29+
[disablePlaceholder]="disablePlaceholder"
30+
[placeholderImageQuality]="placeholderQuality"/>
2631
</section>
2732

2833
<h2>Placeholder quality comparison (high to low)</h2>

‎src/dev-app/youtube-player/youtube-player-demo.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
inject,
1818
} from '@angular/core';
1919
import {FormsModule} from '@angular/forms';
20+
import {MatButton} from '@angular/material/button';
2021
import {MatCheckboxModule} from '@angular/material/checkbox';
2122
import {MatRadioModule} from '@angular/material/radio';
2223
import {PlaceholderImageQuality, YouTubePlayer} from '@angular/youtube-player';
@@ -79,7 +80,7 @@ const VIDEOS: Video[] = [
7980
selector: 'youtube-player-demo',
8081
templateUrl: 'youtube-player-demo.html',
8182
styleUrl: 'youtube-player-demo.css',
82-
imports: [FormsModule, MatRadioModule, MatCheckboxModule, YouTubePlayer],
83+
imports: [FormsModule, MatRadioModule, MatCheckboxModule, MatButton, YouTubePlayer],
8384
changeDetection: ChangeDetectionStrategy.OnPush,
8485
})
8586
export class YouTubePlayerDemo implements AfterViewInit, OnDestroy {

‎src/youtube-player/BUILD.bazel

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ ng_module(
1919
],
2020
),
2121
assets = [
22+
":youtube_player_scss",
2223
":youtube_player_placeholder_scss",
2324
],
2425
deps = [
@@ -30,6 +31,11 @@ ng_module(
3031
],
3132
)
3233

34+
sass_binary(
35+
name = "youtube_player_scss",
36+
src = "youtube-player.scss",
37+
)
38+
3339
sass_binary(
3440
name = "youtube_player_placeholder_scss",
3541
src = "youtube-player-placeholder.scss",

‎src/youtube-player/youtube-player-placeholder.scss

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
// Note that they use a base64 image, likely for performance reasons. We can't use the
1515
// image, because it can break users with a CSP that doesn't allow `data:` URLs.
1616
box-shadow: inset 0 120px 90px -90px rgba(0, 0, 0, 0.8);
17+
18+
:fullscreen & {
19+
min-width: 100vw;
20+
min-height: 100vh;
21+
}
1722
}
1823

1924
.youtube-player-placeholder-button {
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
youtube-player:fullscreen {
2+
&, iframe {
3+
min-width: 100vw;
4+
min-height: 100vh;
5+
}
6+
}

‎src/youtube-player/youtube-player.ts

+15
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ enum PlayerState {
113113
changeDetection: ChangeDetectionStrategy.OnPush,
114114
encapsulation: ViewEncapsulation.None,
115115
imports: [YouTubePlayerPlaceholder],
116+
styleUrl: 'youtube-player.css',
116117
template: `
117118
@if (_shouldShowPlaceholder()) {
118119
<youtube-player-placeholder
@@ -133,6 +134,7 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
133134
private _ngZone = inject(NgZone);
134135
private readonly _nonce = inject(CSP_NONCE, {optional: true});
135136
private readonly _changeDetectorRef = inject(ChangeDetectorRef);
137+
private readonly _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
136138
private _player: YT.Player | undefined;
137139
private _pendingPlayer: YT.Player | undefined;
138140
private _existingApiReadyCallback: (() => void) | undefined;
@@ -474,6 +476,19 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
474476
return this._player ? this._player.getVideoEmbedCode() : '';
475477
}
476478

479+
/**
480+
* Attempts to put the player into fullscreen mode, depending on browser support.
481+
* @param options Options controlling how the element behaves in fullscreen mode.
482+
*/
483+
async requestFullscreen(options?: FullscreenOptions): Promise<void> {
484+
// Note that we do this on the host, rather than the iframe, because it allows us to handle the
485+
// placeholder in fullscreen mode. Null check the method since it's not supported everywhere.
486+
const element = this._elementRef.nativeElement;
487+
return element.requestFullscreen
488+
? element.requestFullscreen(options)
489+
: Promise.reject(new Error('Fullscreen API not supported by browser.'));
490+
}
491+
477492
/**
478493
* Loads the YouTube API and sets up the player.
479494
* @param playVideo Whether to automatically play the video once the player is loaded.

‎tools/public_api_guard/youtube-player/youtube-player.md

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
8080
playerVars: YT.PlayerVars | undefined;
8181
playVideo(): void;
8282
readonly ready: Observable<YT.PlayerEvent>;
83+
requestFullscreen(options?: FullscreenOptions): Promise<void>;
8384
seekTo(seconds: number, allowSeekAhead: boolean): void;
8485
setPlaybackRate(playbackRate: number): void;
8586
setVolume(volume: number): void;

0 commit comments

Comments
 (0)
Please sign in to comment.