UNPKG

@werk1/w1-system-videoblock

Version:

Universal video player supporting YouTube, Vimeo, HLS, DASH with coordination and GSAP integration for W1 System

132 lines (131 loc) 4.82 kB
import React from "react"; import { StateCreator } from "zustand"; export interface W1VideoPlayerState { isPlaying: boolean; isBuffering: boolean; currentTime: number; duration: number; volume: number; isMuted: boolean; playbackRate: number; isFullscreen: boolean; isPictureInPicture: boolean; isMobileFullscreen: boolean; bufferedRanges: TimeRanges | []; error: MediaError | null; isLoading: boolean; hasError: boolean; buffered: TimeRanges | null; } export interface W1VideoPlayerMethods { play: () => Promise<void>; pause: () => Promise<void>; seek: (time: number) => void; setVolume: (volume: number) => void; setMuted: (muted: boolean) => void; toggleFullscreen: () => void; toggleMobileFullscreen: () => void; togglePictureInPicture: () => void; setPlaybackRate: (rate: number) => void; getVideoElement: () => HTMLVideoElement | null; getWrapperElement: () => HTMLDivElement | null; pauseForCoordination?: () => Promise<void>; } export interface W1VideoPlayerProps { src: string; objectFit?: "cover" | "contain" | "fill" | "scale-down" | "none"; muted?: boolean; loop?: boolean; preload?: "none" | "metadata" | "auto"; playsInline?: boolean; autoplay?: boolean; poster?: string; className?: string; style?: React.CSSProperties; onStateChange?: (state: W1VideoPlayerState) => void; onReady?: (video: HTMLVideoElement) => void; onError?: (error: MediaError | null) => void; onPictureInPictureChange?: (isPictureInPicture: boolean) => void; onProgress?: (progress: number) => void; onTimeUpdate?: (currentTime: number) => void; playbackRates?: number[]; skipIntervals?: number; enableStreamingLibs?: boolean; enableKeyboardControls?: boolean; ref?: React.Ref<W1VideoPlayerMethods>; } export interface W1VideoControlsMethods { showControls: () => void; } export interface W1VideoControlsProps { playerState: W1VideoPlayerState; playerMethods: W1VideoPlayerMethods | null; className?: string; showVolumeControl?: boolean; showPlaybackRate?: boolean; showFullscreen?: boolean; showPictureInPicture?: boolean; showTimeDisplay?: boolean; showProgressBar?: boolean; autoHide?: boolean; autoHideDelay?: number; initiallyVisible?: boolean; showOnInteraction?: boolean; customButtons?: React.ReactNode; theme?: "dark" | "light" | "transparent"; position?: "bottom" | "top" | "overlay"; compact?: boolean; playbackRates?: number[]; skipIntervals?: number; videoBlockId?: string; videoCoordinationStore?: () => VideoCoordinationSlice; enableKeyboardControls?: boolean; isMobileDevice: boolean; ref?: React.Ref<W1VideoControlsMethods>; } export interface W1VideoBlockProps extends Omit<W1VideoPlayerProps, "onStateChange" | "isActiveDebounced" | "priority" | "videoCoordinationStore" | "externalVideoBlockId" | "ref"> { showControls?: boolean; isActiveDebounced?: boolean; priority?: number; videoCoordinationStore?: () => VideoCoordinationSlice; onVisibilityChange?: (isActiveDebounced: boolean) => void; onVideoStateChange?: (state: W1VideoPlayerState) => void; allowPipOverride?: boolean; isMobileDevice: boolean; ref?: React.Ref<HTMLDivElement>; } export interface VideoBlockInfo { id: string; priority: number; playerRef?: React.RefObject<W1VideoPlayerMethods | null>; autoplay: boolean; isActiveDebounced: boolean; allowPipOverride?: boolean; isExternalPlatform?: boolean; viewportData?: { intersectionRatio?: number; distanceFromCenter?: number; progress?: number; velocity?: number; }; } export interface VideoCoordinationSlice { currentlyPlayingVideoBlock: VideoBlockInfo | null; registeredVideoBlocks: Map<string, VideoBlockInfo>; singleVideoMode: boolean; allowManualOverride: boolean; pipVideoBlocks: Set<string>; registerVideoBlock: (id: string, info: VideoBlockInfo) => void; unregisterVideoBlock: (id: string) => void; updateVideoState: (id: string, updates: Partial<Pick<VideoBlockInfo, "autoplay" | "isActiveDebounced" | "viewportData">>) => void; calculateWhoShouldPlay: () => string | null; shouldVideoPlay: (videoId: string) => boolean; recalculateDecisions: () => void; setCurrentlyPlaying: (id: string, info: VideoBlockInfo) => void; clearCurrentlyPlaying: (id?: string) => void; setSingleVideoMode: (enabled: boolean) => void; pauseAllVideos: () => void; pauseAllExcept: (videoBlockId: string) => void; setPipStatus: (videoId: string, isPip: boolean) => void; } export type VideoCoordinationSliceCreator = StateCreator<VideoCoordinationSlice>;