Files
siftlode/frontend/src/lib/youtube.ts
T
peter edc09e3651 revert(player): drop the HD-latch resolution trick, keep the windowed fullscreen button
The large-logical-iframe + CSS-scale-down trick to force a 1080p start did not
work behind the user's work VPN (YouTube caps quality by network there regardless
of viewport size), and the two-phase native switch could downgrade a latched
1080p to 480p on some streams. Not worth the complexity for an unreliable win —
revert to the original "opens at whatever resolution YouTube picks" behaviour;
the user sets 1080p manually via fullscreen + the gear as before.

Kept: the windowed maximise (fullscreen) button added to the player meta row.
2026-08-02 02:02:31 +02:00

60 lines
1.7 KiB
TypeScript

// Minimal typings for the YouTube IFrame Player API surface this app actually uses. The API is
// loaded at runtime from youtube.com/iframe_api and ships no official npm types; rather than pull in
// @types/youtube we declare just the methods/events PlayerModal calls, so tsc flags any new call
// that isn't covered here. See [[reference-yt-iframe-api-remote-control-map]] for what's driveable.
interface YTVideoData {
title: string;
author: string;
video_id?: string;
}
export interface YTPlayer {
getPlayerState(): number;
getCurrentTime(): number;
getDuration(): number;
getVideoData(): YTVideoData;
getIframe(): HTMLIFrameElement;
getVolume(): number;
isMuted(): boolean;
setVolume(volume: number): void;
mute(): void;
unMute(): void;
playVideo(): void;
pauseVideo(): void;
loadVideoById(opts: { videoId: string; startSeconds?: number }): void;
seekTo(seconds: number, allowSeekAhead: boolean): void;
destroy(): void;
}
// The IFrame API fires events carrying a numeric `data` — a player-state code (onStateChange) or an
// error code (onError).
export interface YTPlayerEvent {
data: number;
target: YTPlayer;
}
interface YTPlayerOptions {
width?: string | number;
height?: string | number;
videoId?: string;
playerVars?: Record<string, string | number | undefined>;
events?: {
onReady?: (e: YTPlayerEvent) => void;
onStateChange?: (e: YTPlayerEvent) => void;
onError?: (e: YTPlayerEvent) => void;
};
}
export interface YTNamespace {
Player: new (el: HTMLElement, opts: YTPlayerOptions) => YTPlayer;
}
// The globals the IFrame API script installs on `window` once loaded.
declare global {
interface Window {
YT?: YTNamespace;
onYouTubeIframeAPIReady?: () => void;
}
}