Files
streamyfin/utils/chromecast/options.ts
Uruk 7c81c0ff33 Fix: Improves Chromecast casting experience
Fixes several issues and improves the overall Chromecast casting experience:

- Implements an AbortController for fetching item data to prevent race conditions.
- Syncs live progress in the mini player more accurately using elapsed real time.
- Prevents event propagation in the mini player's play/pause button.
- Ensures the disconnect callback in the connection menu is always called.
- Retries scrolling in the episode list on failure.
- Handles unmute failures gracefully in volume controls.
- Clamps seek positions to prevent exceeding duration.
- Fixes reporting playback start multiple times
- Improves segment calculation in `useChromecastSegments`
- Prevents race condition with `isPlaying` state in `Controls` component

Also includes minor UI and timing adjustments for a smoother user experience.
2026-02-08 15:23:01 +01:00

67 lines
1.8 KiB
TypeScript

/**
* Chromecast player configuration and constants
*/
export const CHROMECAST_CONSTANTS = {
// Timing (all milliseconds for consistency)
PROGRESS_REPORT_INTERVAL_MS: 10_000,
CONTROLS_TIMEOUT_MS: 5_000,
BUFFERING_THRESHOLD_MS: 10_000,
NEXT_EPISODE_COUNTDOWN_MS: 30_000,
CONNECTION_CHECK_INTERVAL_MS: 5_000,
// UI
POSTER_WIDTH: 300,
POSTER_HEIGHT: 450,
MINI_PLAYER_HEIGHT: 80,
SKIP_FORWARD_SECS: 15, // overridden by settings
SKIP_BACKWARD_SECS: 15, // overridden by settings
// Animation
ANIMATION_DURATION_MS: 300,
BLUR_RADIUS: 10,
} as const;
export const CONNECTION_QUALITY = {
EXCELLENT: { min: 50, label: "Excellent", icon: "wifi" }, // min Mbps
GOOD: { min: 30, label: "Good", icon: "signal" }, // min Mbps
FAIR: { min: 15, label: "Fair", icon: "cellular" }, // min Mbps
POOR: { min: 0, label: "Poor", icon: "warning" }, // min Mbps
} as const;
export type ConnectionQuality = keyof typeof CONNECTION_QUALITY;
export type PlaybackState = "playing" | "paused" | "stopped" | "buffering";
export interface ChromecastPlayerState {
isConnected: boolean;
deviceName: string | null;
playbackState: PlaybackState;
progress: number; // milliseconds
duration: number; // milliseconds
volume: number; // 0-1
isMuted: boolean;
currentItemId: string | null;
connectionQuality: ConnectionQuality;
}
export interface ChromecastSegmentData {
intro: { start: number; end: number } | null;
credits: { start: number; end: number } | null;
recap: { start: number; end: number } | null;
commercial: { start: number; end: number }[];
preview: { start: number; end: number }[];
}
export const DEFAULT_CHROMECAST_STATE: ChromecastPlayerState = {
isConnected: false,
deviceName: null,
playbackState: "stopped",
progress: 0,
duration: 0,
volume: 1,
isMuted: false,
currentItemId: null,
connectionQuality: "GOOD",
};