@vexor-video/player 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
ADDED
package/dist/index.cjs
CHANGED
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/VexorPlayer.tsx","../src/hooks/useVexorPlayer.ts","../src/native-token-refresh.ts","../src/components/Controls.tsx","../src/components/Watermark.tsx","../src/vanilla/player.ts"],"sourcesContent":["\"use client\";\n\nimport \"./styles/player.css\";\n\nexport { VexorPlayer } from \"./components/VexorPlayer\";\nexport { Controls } from \"./components/Controls\";\nexport { Watermark } from \"./components/Watermark\";\nexport { useVexorPlayer } from \"./hooks/useVexorPlayer\";\nexport { createVexorPlayer } from \"./vanilla/player\";\n\nexport type {\n VexorPlayerProps,\n QualityLevel,\n WatermarkConfig,\n} from \"./types\";\n\nexport type {\n UseVexorPlayerReturn,\n} from \"./hooks/useVexorPlayer\";\n\nexport type {\n VanillaPlayerInstance,\n} from \"./vanilla/player\";\n","import React, { useState, useEffect, useRef, useCallback } from \"react\";\nimport { useVexorPlayer } from \"../hooks/useVexorPlayer\";\nimport { Controls } from \"./Controls\";\nimport { Watermark } from \"./Watermark\";\nimport type { VexorPlayerProps } from \"../types\";\n\nexport const VexorPlayer: React.FC<VexorPlayerProps> = (props) => {\n const {\n poster,\n preload = \"metadata\",\n muted = false,\n loop = false,\n controls = true,\n nativeControls = false,\n watermark,\n protect = false,\n className = \"\",\n style,\n children,\n } = props;\n\n const player = useVexorPlayer(props);\n const [controlsVisible, setControlsVisible] = useState(true);\n const hideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const resetHideTimer = useCallback(() => {\n setControlsVisible(true);\n if (hideTimerRef.current) {\n clearTimeout(hideTimerRef.current);\n }\n if (player.isPlaying && !player.containerRef.current?.contains(document.activeElement)) {\n hideTimerRef.current = setTimeout(() => {\n setControlsVisible(false);\n }, 2500);\n }\n }, [player.isPlaying]);\n\n useEffect(() => {\n resetHideTimer();\n return () => {\n if (hideTimerRef.current) clearTimeout(hideTimerRef.current);\n };\n }, [player.isPlaying, resetHideTimer]);\n\n // Anti-tamper protection handlers\n const handleContextMenu = (e: React.MouseEvent) => {\n if (protect) {\n e.preventDefault();\n }\n };\n\n // Keyboard navigation & shortcuts\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Leave keystrokes to focused form controls, buttons, and custom controls.\n const target = e.target as HTMLElement;\n if (target?.closest(\"input, textarea, select, button, [contenteditable='true'], [role='slider']\")) return;\n\n const container = player.containerRef.current;\n if (!container || (!document.fullscreenElement && !container.contains(document.activeElement) && !container.matches(\":hover\"))) {\n return;\n }\n\n switch (e.key.toLowerCase()) {\n case \" \":\n case \"k\":\n e.preventDefault();\n player.togglePlay();\n resetHideTimer();\n break;\n case \"arrowleft\":\n case \"j\":\n e.preventDefault();\n player.seek(player.currentTime - 5);\n resetHideTimer();\n break;\n case \"arrowright\":\n case \"l\":\n e.preventDefault();\n player.seek(player.currentTime + 5);\n resetHideTimer();\n break;\n case \"arrowup\":\n e.preventDefault();\n player.setVolume(player.volume + 0.1);\n resetHideTimer();\n break;\n case \"arrowdown\":\n e.preventDefault();\n player.setVolume(player.volume - 0.1);\n resetHideTimer();\n break;\n case \"m\":\n e.preventDefault();\n player.toggleMute();\n resetHideTimer();\n break;\n case \"f\":\n e.preventDefault();\n player.toggleFullscreen();\n resetHideTimer();\n break;\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [player, resetHideTimer]);\n\n return (\n <div\n ref={player.containerRef}\n className={`vexor-player ${player.isFullscreen ? \"is-fullscreen\" : \"\"} ${protect ? \"is-protected\" : \"\"} ${className}`}\n style={style}\n onMouseMove={resetHideTimer}\n onMouseLeave={(event) => {\n if (player.isPlaying && !event.currentTarget.contains(document.activeElement)) {\n setControlsVisible(false);\n }\n }}\n onFocusCapture={() => {\n if (hideTimerRef.current) clearTimeout(hideTimerRef.current);\n setControlsVisible(true);\n }}\n onBlurCapture={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) resetHideTimer();\n }}\n onContextMenu={handleContextMenu}\n tabIndex={0}\n role=\"region\"\n aria-label=\"Video Player\"\n >\n <video\n ref={player.videoRef}\n className=\"vexor-video\"\n poster={poster}\n preload={preload}\n muted={muted}\n loop={loop}\n playsInline\n controls={nativeControls}\n onClick={nativeControls ? undefined : player.togglePlay}\n />\n\n {/* Watermark Overlay */}\n {watermark && <Watermark config={watermark} />}\n\n {/* Buffering Spinner */}\n {player.isBuffering && !player.error && (\n <div className=\"vexor-spinner-overlay\" aria-label=\"Buffering video\">\n <div className=\"vexor-spinner\" />\n </div>\n )}\n\n {/* Center Big Play Button (when paused, not buffering, and custom controls active) */}\n {!nativeControls && controls && !player.isPlaying && !player.isBuffering && !player.error && (\n <button type=\"button\" className=\"vexor-center-play-overlay\" onClick={player.togglePlay} aria-label=\"Play video\">\n <span className=\"vexor-center-play-button\" aria-hidden=\"true\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <polygon points=\"6,4 20,12 6,20\" />\n </svg>\n </span>\n </button>\n )}\n\n {/* Custom Controls Bar */}\n {!nativeControls && controls && !player.error && (\n <Controls\n isPlaying={player.isPlaying}\n isBuffering={player.isBuffering}\n currentTime={player.currentTime}\n duration={player.duration}\n buffered={player.buffered}\n volume={player.volume}\n isMuted={player.isMuted}\n isFullscreen={player.isFullscreen}\n qualityLevels={player.qualityLevels}\n currentQuality={player.currentQuality}\n playbackRate={player.playbackRate}\n visible={controlsVisible}\n onPlayPause={player.togglePlay}\n onSeek={player.seek}\n onVolumeChange={player.setVolume}\n onToggleMute={player.toggleMute}\n onQualityChange={player.setQuality}\n onPlaybackRateChange={player.setPlaybackRate}\n onToggleFullscreen={player.toggleFullscreen}\n onTogglePiP={player.togglePiP}\n />\n )}\n\n {/* Error Overlay */}\n {player.error && (\n <div className=\"vexor-error-overlay\">\n <div className=\"vexor-error-title\">Playback Error</div>\n <div className=\"vexor-error-message\">{player.error.message}</div>\n <button type=\"button\" className=\"vexor-retry-button\" onClick={player.retry}>\n Retry Playback\n </button>\n </div>\n )}\n\n {/* Custom Child Overlays */}\n {children}\n </div>\n );\n};\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport Hls from \"hls.js\";\nimport type { QualityLevel, VexorPlayerProps } from \"../types\";\nimport { startNativeTokenRefresh } from \"../native-token-refresh\";\n\nexport interface UseVexorPlayerReturn {\n videoRef: React.RefObject<HTMLVideoElement | null>;\n containerRef: React.RefObject<HTMLDivElement | null>;\n isPlaying: boolean;\n isBuffering: boolean;\n currentTime: number;\n duration: number;\n buffered: number;\n volume: number;\n isMuted: boolean;\n isFullscreen: boolean;\n qualityLevels: QualityLevel[];\n currentQuality: number;\n playbackRate: number;\n error: { code: string; message: string; fatal: boolean } | null;\n play: () => Promise<void>;\n pause: () => void;\n togglePlay: () => void;\n seek: (time: number) => void;\n setVolume: (vol: number) => void;\n toggleMute: () => void;\n setQuality: (levelIndex: number) => void;\n setPlaybackRate: (rate: number) => void;\n toggleFullscreen: () => void;\n togglePiP: () => void;\n retry: () => void;\n}\n\nexport function useVexorPlayer({\n src,\n assetId,\n token,\n baseUrl = \"https://api.vexor.et\",\n fallbackSrc,\n autoPlay = false,\n muted = false,\n refreshToken,\n onReady,\n onPlay,\n onPause,\n onEnded,\n onTimeUpdate,\n onError,\n onQualityChange,\n}: VexorPlayerProps): UseVexorPlayerReturn {\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const hlsRef = useRef<Hls | null>(null);\n const callbacksRef = useRef({ onReady, onPlay, onPause, onEnded, onTimeUpdate, onError, onQualityChange, refreshToken });\n callbacksRef.current = { onReady, onPlay, onPause, onEnded, onTimeUpdate, onError, onQualityChange, refreshToken };\n const activeParamsRef = useRef(\"\");\n const refreshPromiseRef = useRef<Promise<string> | null>(null);\n const resumeAfterRefreshRef = useRef<{ time: number; shouldPlay: boolean } | null>(null);\n\n const [isPlaying, setIsPlaying] = useState(false);\n const [isBuffering, setIsBuffering] = useState(true);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [buffered, setBuffered] = useState(0);\n const [volume, setVolumeState] = useState(1);\n const [isMuted, setIsMuted] = useState(muted);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [qualityLevels, setQualityLevels] = useState<QualityLevel[]>([]);\n const [currentQuality, setCurrentQuality] = useState(-1);\n const [playbackRate, setPlaybackRateState] = useState(1);\n const [error, setError] = useState<{ code: string; message: string; fatal: boolean } | null>(null);\n const [reloadTrigger, setReloadTrigger] = useState(0);\n\n // Determine effective playback manifest URL\n const activeUrl = src\n ? src\n : assetId\n ? `${baseUrl.replace(/\\/+$/, \"\")}/v1/playback/${encodeURIComponent(assetId)}/master.m3u8${token ? `?token=${encodeURIComponent(token)}` : \"\"}`\n : \"\";\n\n const destroyHls = useCallback(() => {\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n }, []);\n\n const retry = useCallback(() => {\n setError(null);\n setIsBuffering(true);\n setReloadTrigger((v) => v + 1);\n }, []);\n\n // Initialize HLS & Media Source\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n let cleanupFallback = () => {};\n const loadFallback = () => {\n if (!fallbackSrc) return false;\n destroyHls();\n setIsBuffering(true);\n video.src = fallbackSrc;\n const onLoaded = () => {\n setIsBuffering(false);\n callbacksRef.current.onReady?.();\n };\n const onError = () => {\n const errObj = {\n code: \"FALLBACK_PLAYBACK_ERROR\",\n message: \"Unable to load fallback media source\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n video.addEventListener(\"loadeddata\", onLoaded);\n video.addEventListener(\"error\", onError);\n cleanupFallback = () => {\n video.removeEventListener(\"loadeddata\", onLoaded);\n video.removeEventListener(\"error\", onError);\n };\n video.load();\n return true;\n };\n const setFatalError = (code: string, message: string) => {\n destroyHls();\n const errObj = { code, message, fatal: true };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n\n destroyHls();\n setError(null);\n setCurrentTime(0);\n setDuration(0);\n setBuffered(0);\n setQualityLevels([]);\n setCurrentQuality(-1);\n setIsBuffering(Boolean(activeUrl));\n if (!activeUrl) {\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n return;\n }\n\n const isHlsUrl = activeUrl.includes(\".m3u8\") || activeUrl.includes(\"/playback/\");\n let fatalRecoveryAttempts = 0;\n\n if (isHlsUrl && Hls.isSupported()) {\n activeParamsRef.current = activeUrl.includes(\"?\") ? activeUrl.substring(activeUrl.indexOf(\"?\")) : \"\";\n\n class VexorLoader extends Hls.DefaultConfig.loader {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n load(context: any, config: any, callbacks: any) {\n // Propagate token query params to child playlists and segments if not present\n const activeParams = activeParamsRef.current;\n if (activeParams && context?.url) {\n try {\n const sourceUrl = new URL(activeUrl, window.location.href);\n const childUrl = new URL(context.url, sourceUrl);\n if (childUrl.origin === sourceUrl.origin && !childUrl.searchParams.has(\"token\")) {\n new URLSearchParams(activeParams).forEach((value, key) => {\n if (!childUrl.searchParams.has(key)) childUrl.searchParams.set(key, value);\n });\n context.url = childUrl.toString();\n }\n } catch {\n // Leave an unparseable child URL untouched; the loader will report failures normally.\n }\n }\n super.load(context, config, callbacks);\n }\n }\n\n const hls = new Hls({\n startFragPrefetch: true,\n maxBufferLength: 30,\n maxMaxBufferLength: 60,\n enableWorker: true,\n lowLatencyMode: true,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n loader: VexorLoader as any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fLoader: VexorLoader as any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n pLoader: VexorLoader as any,\n });\n hlsRef.current = hls;\n\n hls.loadSource(activeUrl);\n hls.attachMedia(video);\n\n hls.on(Hls.Events.MANIFEST_PARSED, (_event, data) => {\n if (hlsRef.current !== hls) return;\n setIsBuffering(false);\n const levels: QualityLevel[] = data.levels.map((lvl, index) => {\n let label = `${lvl.height}p`;\n if (lvl.height === 0 || lvl.videoCodec === undefined) {\n label = \"Audio only\";\n }\n return {\n id: index,\n height: lvl.height,\n width: lvl.width,\n bitrate: lvl.bitrate,\n label,\n };\n });\n setQualityLevels(levels);\n callbacksRef.current.onReady?.();\n const resume = resumeAfterRefreshRef.current;\n if (resume) {\n resumeAfterRefreshRef.current = null;\n if (Number.isFinite(resume.time) && resume.time > 0) video.currentTime = resume.time;\n if (resume.shouldPlay) video.play().catch(() => {});\n }\n if (autoPlay) {\n video.play().catch(() => {\n // Autoplay might be blocked by browser policy; user can interact to start\n });\n }\n });\n\n hls.on(Hls.Events.LEVEL_SWITCHED, (_event, data) => {\n if (hlsRef.current !== hls) return;\n setCurrentQuality(hls.autoLevelEnabled ? -1 : data.level);\n callbacksRef.current.onQualityChange?.(hls.autoLevelEnabled ? -1 : data.level);\n });\n\n hls.on(Hls.Events.ERROR, async (_event, data) => {\n if (hlsRef.current !== hls) return;\n // Handle token expiry (HTTP 401 or 403 on key/segment)\n if (\n (data.response?.code === 401 || data.response?.code === 403) &&\n callbacksRef.current.refreshToken\n ) {\n try {\n if (!refreshPromiseRef.current) {\n refreshPromiseRef.current = callbacksRef.current.refreshToken();\n }\n const newToken = await refreshPromiseRef.current;\n refreshPromiseRef.current = null;\n if (newToken && hlsRef.current === hls) {\n resumeAfterRefreshRef.current = {\n time: video.currentTime,\n shouldPlay: !video.paused,\n };\n const url = new URL(activeUrl, window.location.href);\n url.searchParams.set(\"token\", newToken);\n activeParamsRef.current = url.search;\n hls.loadSource(url.toString());\n hls.startLoad();\n return;\n }\n } catch {\n refreshPromiseRef.current = null;\n // Fall through to standard error handling if token refresh fails\n }\n }\n\n if (hlsRef.current !== hls) return;\n\n if (data.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n if (fatalRecoveryAttempts++ < 1) {\n hls.startLoad();\n } else if (!loadFallback()) {\n setFatalError(data.details || \"NETWORK_ERROR\", `Failed to stream video: ${data.details || \"network error\"}`);\n }\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n if (fatalRecoveryAttempts++ < 1) {\n hls.recoverMediaError();\n } else if (!loadFallback()) {\n setFatalError(data.details || \"MEDIA_ERROR\", `Failed to stream video: ${data.details || \"media error\"}`);\n }\n break;\n default:\n if (!loadFallback()) {\n setFatalError(data.details || \"MEDIA_PLAYBACK_ERROR\", `Failed to stream video: ${data.details || \"network error\"}`);\n }\n break;\n }\n }\n });\n } else if (isHlsUrl && video.canPlayType(\"application/vnd.apple.mpegurl\")) {\n // Safari / iOS Native HLS\n video.src = activeUrl;\n const nativeTokenRefresh = startNativeTokenRefresh(\n video,\n activeUrl,\n callbacksRef.current.refreshToken,\n );\n const onLoaded = () => {\n setIsBuffering(false);\n callbacksRef.current.onReady?.();\n if (autoPlay) {\n video.play().catch(() => {});\n }\n };\n const onNativeError = () => {\n void nativeTokenRefresh.refreshNow().then((refreshed) => {\n if (refreshed || hlsRef.current) return;\n if (loadFallback()) {\n video.removeEventListener(\"error\", onNativeError);\n return;\n }\n setFatalError(\"NATIVE_HLS_ERROR\", \"Failed to play native HLS stream\");\n });\n };\n video.addEventListener(\"loadedmetadata\", onLoaded);\n video.addEventListener(\"error\", onNativeError);\n return () => {\n nativeTokenRefresh.stop();\n video.removeEventListener(\"loadedmetadata\", onLoaded);\n video.removeEventListener(\"error\", onNativeError);\n };\n } else if (!isHlsUrl) {\n // Standard MP4 progressive playback\n video.src = activeUrl;\n const onLoaded = () => {\n setIsBuffering(false);\n onReady?.();\n };\n const onErr = () => {\n const errObj = {\n code: \"DIRECT_PLAYBACK_ERROR\",\n message: \"Unable to load media source\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n video.addEventListener(\"loadeddata\", onLoaded);\n video.addEventListener(\"error\", onErr);\n return () => {\n video.removeEventListener(\"loadeddata\", onLoaded);\n video.removeEventListener(\"error\", onErr);\n };\n } else if (fallbackSrc) {\n // HLS unsupported: use the configured progressive fallback.\n loadFallback();\n } else {\n const errObj = {\n code: \"HLS_UNSUPPORTED\",\n message: \"This browser does not support HLS playback and no fallback source was provided\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n }\n\n return () => {\n cleanupFallback();\n destroyHls();\n };\n }, [activeUrl, fallbackSrc, autoPlay, reloadTrigger, destroyHls]);\n\n // Video Element Event Listeners\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n const onPlayEvent = () => {\n setIsPlaying(true);\n callbacksRef.current.onPlay?.();\n };\n\n const onPauseEvent = () => {\n setIsPlaying(false);\n callbacksRef.current.onPause?.();\n };\n\n const onEndedEvent = () => {\n setIsPlaying(false);\n callbacksRef.current.onEnded?.();\n };\n\n const onWaiting = () => setIsBuffering(true);\n const onPlaying = () => setIsBuffering(false);\n\n const onTimeUpdateEvent = () => {\n setCurrentTime(video.currentTime);\n callbacksRef.current.onTimeUpdate?.(video.currentTime, video.duration);\n\n // Calculate buffer progress\n if (video.buffered.length > 0 && video.duration > 0) {\n for (let i = video.buffered.length - 1; i >= 0; i--) {\n if (video.buffered.start(i) <= video.currentTime) {\n setBuffered((video.buffered.end(i) / video.duration) * 100);\n break;\n }\n }\n }\n };\n\n const onDurationChange = () => setDuration(video.duration || 0);\n const onVolumeChangeEvent = () => {\n setVolumeState(video.volume);\n setIsMuted(video.muted);\n };\n\n video.addEventListener(\"play\", onPlayEvent);\n video.addEventListener(\"pause\", onPauseEvent);\n video.addEventListener(\"ended\", onEndedEvent);\n video.addEventListener(\"waiting\", onWaiting);\n video.addEventListener(\"playing\", onPlaying);\n video.addEventListener(\"timeupdate\", onTimeUpdateEvent);\n video.addEventListener(\"durationchange\", onDurationChange);\n video.addEventListener(\"volumechange\", onVolumeChangeEvent);\n\n return () => {\n video.removeEventListener(\"play\", onPlayEvent);\n video.removeEventListener(\"pause\", onPauseEvent);\n video.removeEventListener(\"ended\", onEndedEvent);\n video.removeEventListener(\"waiting\", onWaiting);\n video.removeEventListener(\"playing\", onPlaying);\n video.removeEventListener(\"timeupdate\", onTimeUpdateEvent);\n video.removeEventListener(\"durationchange\", onDurationChange);\n video.removeEventListener(\"volumechange\", onVolumeChangeEvent);\n };\n }, []);\n\n // Fullscreen change listener\n useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen(Boolean(document.fullscreenElement));\n };\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, []);\n\n // Player Actions\n const play = useCallback(async () => {\n if (videoRef.current) {\n await videoRef.current.play();\n }\n }, []);\n\n const pause = useCallback(() => {\n if (videoRef.current) {\n videoRef.current.pause();\n }\n }, []);\n\n const togglePlay = useCallback(() => {\n if (!videoRef.current) return;\n if (videoRef.current.paused) {\n videoRef.current.play().catch(() => {});\n } else {\n videoRef.current.pause();\n }\n }, []);\n\n const seek = useCallback((time: number) => {\n if (videoRef.current) {\n videoRef.current.currentTime = Math.max(0, Math.min(time, videoRef.current.duration || time));\n }\n }, []);\n\n const setVolume = useCallback((vol: number) => {\n if (videoRef.current) {\n const clamped = Math.max(0, Math.min(1, vol));\n videoRef.current.volume = clamped;\n videoRef.current.muted = clamped === 0;\n }\n }, []);\n\n const toggleMute = useCallback(() => {\n if (videoRef.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n }, []);\n\n const setQuality = useCallback((levelIndex: number) => {\n if (hlsRef.current) {\n if (levelIndex === -1) {\n hlsRef.current.currentLevel = -1; // Auto\n } else {\n hlsRef.current.currentLevel = levelIndex;\n }\n setCurrentQuality(levelIndex);\n }\n }, []);\n\n const setPlaybackRate = useCallback((rate: number) => {\n if (videoRef.current) {\n videoRef.current.playbackRate = rate;\n setPlaybackRateState(rate);\n }\n }, []);\n\n const toggleFullscreen = useCallback(() => {\n const container = containerRef.current || videoRef.current;\n if (!container) return;\n\n if (!document.fullscreenElement) {\n container.requestFullscreen().catch(() => {});\n } else {\n document.exitFullscreen().catch(() => {});\n }\n }, []);\n\n const togglePiP = useCallback(async () => {\n const video = videoRef.current;\n if (!video) return;\n\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else if (document.pictureInPictureEnabled) {\n await video.requestPictureInPicture();\n }\n } catch {\n // Ignored\n }\n }, []);\n\n return {\n videoRef,\n containerRef,\n isPlaying,\n isBuffering,\n currentTime,\n duration,\n buffered,\n volume,\n isMuted,\n isFullscreen,\n qualityLevels,\n currentQuality,\n playbackRate,\n error,\n play,\n pause,\n togglePlay,\n seek,\n setVolume,\n toggleMute,\n setQuality,\n setPlaybackRate,\n toggleFullscreen,\n togglePiP,\n retry,\n };\n}\n","const TOKEN_REFRESH_INTERVAL_MS = 4 * 60 * 1000;\nconst TOKEN_REFRESH_RETRY_MS = 30 * 1000;\n\n/**\n * Refresh native-HLS playback before Vexor's five-minute token expires.\n * Browsers do not expose the native HLS request status to JavaScript, so this\n * timer complements the reactive 401/403 handling used by hls.js.\n */\nexport function startNativeTokenRefresh(\n video: HTMLVideoElement,\n initialUrl: string,\n refreshToken?: () => Promise<string>,\n): { refreshNow: () => Promise<boolean>; stop: () => void } {\n let currentUrl = initialUrl;\n let disposed = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let refreshInFlight: Promise<boolean> | null = null;\n let restoreListener: (() => void) | undefined;\n\n const schedule = (delay = TOKEN_REFRESH_INTERVAL_MS) => {\n if (!refreshToken || disposed) return;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => void refreshNow(), delay);\n };\n\n const refreshNow = (): Promise<boolean> => {\n if (!refreshToken || disposed) return Promise.resolve(false);\n if (refreshInFlight) return refreshInFlight;\n\n refreshInFlight = (async () => {\n try {\n const token = await refreshToken();\n if (disposed || !token) return false;\n\n const nextUrl = new URL(currentUrl, document.baseURI);\n nextUrl.searchParams.set(\"token\", token);\n currentUrl = nextUrl.toString();\n\n const resumeTime = video.currentTime;\n const shouldResume = !video.paused;\n restoreListener = () => {\n restoreListener = undefined;\n if (disposed) return;\n if (Number.isFinite(resumeTime) && resumeTime > 0) {\n try {\n video.currentTime = resumeTime;\n } catch {\n // The new manifest may not have loaded enough media to seek yet.\n }\n }\n if (shouldResume) video.play().catch(() => {});\n };\n video.addEventListener(\"loadedmetadata\", restoreListener, { once: true });\n video.src = currentUrl;\n video.load();\n schedule();\n return true;\n } catch {\n // Retry soon; do not keep using a token that is about to expire.\n schedule(TOKEN_REFRESH_RETRY_MS);\n return false;\n } finally {\n refreshInFlight = null;\n }\n })();\n\n return refreshInFlight;\n };\n\n schedule();\n\n return {\n refreshNow,\n stop: () => {\n disposed = true;\n if (timer) clearTimeout(timer);\n if (restoreListener) video.removeEventListener(\"loadedmetadata\", restoreListener);\n },\n };\n}\n","import React, { useState, useRef, useEffect, useCallback } from \"react\";\nimport type { QualityLevel } from \"../types\";\n\ninterface ControlsProps {\n isPlaying: boolean;\n isBuffering: boolean;\n currentTime: number;\n duration: number;\n buffered: number;\n volume: number;\n isMuted: boolean;\n isFullscreen: boolean;\n qualityLevels: QualityLevel[];\n currentQuality: number;\n playbackRate: number;\n visible: boolean;\n onPlayPause: () => void;\n onSeek: (time: number) => void;\n onVolumeChange: (volume: number) => void;\n onToggleMute: () => void;\n onQualityChange: (levelIndex: number) => void;\n onPlaybackRateChange: (rate: number) => void;\n onToggleFullscreen: () => void;\n onTogglePiP: () => void;\n}\n\nfunction formatTime(seconds: number): string {\n if (isNaN(seconds) || seconds < 0) return \"0:00\";\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = Math.floor(seconds % 60);\n if (h > 0) {\n return `${h}:${m.toString().padStart(2, \"0\")}:${s.toString().padStart(2, \"0\")}`;\n }\n return `${m}:${s.toString().padStart(2, \"0\")}`;\n}\n\nexport const Controls: React.FC<ControlsProps> = ({\n isPlaying,\n currentTime,\n duration,\n buffered,\n volume,\n isMuted,\n isFullscreen,\n qualityLevels,\n currentQuality,\n playbackRate,\n visible,\n onPlayPause,\n onSeek,\n onVolumeChange,\n onToggleMute,\n onQualityChange,\n onPlaybackRateChange,\n onToggleFullscreen,\n onTogglePiP,\n}) => {\n const [showQualityMenu, setShowQualityMenu] = useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = useState(false);\n const progressRef = useRef<HTMLDivElement>(null);\n const [isScrubbing, setIsScrubbing] = useState(false);\n const [pictureInPictureSupported, setPictureInPictureSupported] = useState(false);\n\n useEffect(() => {\n setPictureInPictureSupported(\n typeof document !== \"undefined\" && document.pictureInPictureEnabled\n );\n }, []);\n\n const playedPercent = duration > 0 ? (currentTime / duration) * 100 : 0;\n const speedOptions = [0.5, 0.75, 1, 1.25, 1.5, 2];\n\n const handleScrub = useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n if (!progressRef.current || duration <= 0) return;\n const rect = progressRef.current.getBoundingClientRect();\n const pos = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n onSeek(pos * duration);\n },\n [duration, onSeek]\n );\n\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n if (e.button !== 0) return;\n e.currentTarget.setPointerCapture(e.pointerId);\n setIsScrubbing(true);\n handleScrub(e);\n };\n\n const handleTimelineKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (duration <= 0) return;\n const step = e.shiftKey ? 30 : 5;\n let nextTime: number | undefined;\n if (e.key === \"ArrowLeft\") nextTime = currentTime - step;\n if (e.key === \"ArrowRight\") nextTime = currentTime + step;\n if (e.key === \"Home\") nextTime = 0;\n if (e.key === \"End\") nextTime = duration;\n if (nextTime !== undefined) {\n e.preventDefault();\n onSeek(Math.max(0, Math.min(duration, nextTime)));\n }\n };\n\n return (\n <div className={`vexor-controls ${visible ? \"\" : \"is-hidden\"}`}>\n {/* Timeline Scrubber */}\n <div\n className=\"vexor-progress-container\"\n ref={progressRef}\n onPointerDown={handlePointerDown}\n onPointerMove={(event) => { if (isScrubbing) handleScrub(event); }}\n onPointerUp={(event) => {\n if (progressRef.current?.hasPointerCapture(event.pointerId)) {\n progressRef.current.releasePointerCapture(event.pointerId);\n }\n setIsScrubbing(false);\n }}\n onPointerCancel={() => setIsScrubbing(false)}\n onKeyDown={handleTimelineKeyDown}\n tabIndex={0}\n role=\"slider\"\n aria-label=\"Video timeline\"\n aria-valuemin={0}\n aria-valuemax={duration}\n aria-valuenow={Math.min(currentTime, duration || 0)}\n aria-valuetext={`${formatTime(currentTime)} of ${formatTime(duration)}`}\n >\n <div className=\"vexor-progress-track\">\n <div className=\"vexor-progress-buffer\" style={{ width: `${buffered}%` }} />\n <div className=\"vexor-progress-played\" style={{ width: `${playedPercent}%` }} />\n <div className=\"vexor-progress-thumb\" style={{ left: `${playedPercent}%` }} />\n </div>\n </div>\n\n {/* Control Buttons Row */}\n <div className=\"vexor-controls-row\">\n {/* Left Side: Play/Pause, Volume, Time */}\n <div className=\"vexor-controls-group\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onPlayPause}\n aria-label={isPlaying ? \"Pause\" : \"Play\"}\n >\n {isPlaying ? (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <polygon points=\"5,3 19,12 5,21\" />\n </svg>\n )}\n </button>\n\n <div className=\"vexor-volume-wrapper\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onToggleMute}\n aria-label={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\" />\n <line x1=\"17\" y1=\"9\" x2=\"23\" y2=\"15\" />\n </svg>\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\" />\n </svg>\n )}\n </button>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n value={isMuted ? 0 : volume}\n onChange={(e) => onVolumeChange(parseFloat(e.target.value))}\n className=\"vexor-volume-slider\"\n aria-label=\"Volume slider\"\n />\n </div>\n\n <span className=\"vexor-time-display\">\n {formatTime(currentTime)} / {formatTime(duration)}\n </span>\n </div>\n\n {/* Right Side: Speed, Quality, PiP, Fullscreen */}\n <div className=\"vexor-controls-group\">\n {/* Speed Selector */}\n <div className=\"vexor-menu-anchor\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={() => {\n setShowSpeedMenu(!showSpeedMenu);\n setShowQualityMenu(false);\n }}\n aria-label=\"Playback speed\"\n style={{ fontSize: \"11px\", fontWeight: 600, padding: \"4px 8px\" }}\n >\n {playbackRate === 1 ? \"1x\" : `${playbackRate}x`}\n </button>\n\n {showSpeedMenu && (\n <div className=\"vexor-menu-dropdown\">\n {speedOptions.map((rate) => (\n <button\n key={rate}\n type=\"button\"\n className={`vexor-menu-item ${playbackRate === rate ? \"is-active\" : \"\"}`}\n onClick={() => {\n onPlaybackRateChange(rate);\n setShowSpeedMenu(false);\n }}\n >\n <span>{rate}x</span>\n {playbackRate === rate && <span>✓</span>}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Quality Levels Selector */}\n {qualityLevels.length > 0 && (\n <div className=\"vexor-menu-anchor\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={() => {\n setShowQualityMenu(!showQualityMenu);\n setShowSpeedMenu(false);\n }}\n aria-label=\"Video quality\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\" />\n </svg>\n </button>\n\n {showQualityMenu && (\n <div className=\"vexor-menu-dropdown\">\n <button\n type=\"button\"\n className={`vexor-menu-item ${currentQuality === -1 ? \"is-active\" : \"\"}`}\n onClick={() => {\n onQualityChange(-1);\n setShowQualityMenu(false);\n }}\n >\n <span>Auto</span>\n {currentQuality === -1 && <span>✓</span>}\n </button>\n {qualityLevels.map((lvl) => (\n <button\n key={lvl.id}\n type=\"button\"\n className={`vexor-menu-item ${currentQuality === lvl.id ? \"is-active\" : \"\"}`}\n onClick={() => {\n onQualityChange(lvl.id);\n setShowQualityMenu(false);\n }}\n >\n <span>{lvl.label}</span>\n {currentQuality === lvl.id && <span>✓</span>}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Picture in Picture */}\n {pictureInPictureSupported && (\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onTogglePiP}\n aria-label=\"Picture in picture\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" />\n <rect x=\"12\" y=\"9\" width=\"8\" height=\"6\" rx=\"1\" fill=\"currentColor\" fillOpacity=\"0.4\" />\n </svg>\n </button>\n )}\n\n {/* Fullscreen Toggle */}\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onToggleFullscreen}\n aria-label={isFullscreen ? \"Exit fullscreen\" : \"Enter fullscreen\"}\n >\n {isFullscreen ? (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3\" />\n </svg>\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\" />\n </svg>\n )}\n </button>\n </div>\n </div>\n </div>\n );\n};\n","import React, { useEffect, useState, useMemo } from \"react\";\nimport type { WatermarkConfig } from \"../types\";\n\ninterface WatermarkProps {\n config?: string | WatermarkConfig;\n}\n\nexport const Watermark: React.FC<WatermarkProps> = ({ config }) => {\n const parsedConfig: WatermarkConfig | null = useMemo(() => {\n if (!config) return null;\n if (typeof config === \"string\") {\n return { text: config, position: \"dynamic\", intervalSeconds: 15, opacity: 0.35 };\n }\n return {\n position: \"dynamic\",\n intervalSeconds: 15,\n opacity: 0.35,\n ...config,\n };\n }, [config]);\n\n const [coords, setCoords] = useState<{ top: string; left: string }>({ top: \"15%\", left: \"15%\" });\n\n useEffect(() => {\n if (!parsedConfig || parsedConfig.position !== \"dynamic\") return;\n\n const intervalMs = Math.max(2, parsedConfig.intervalSeconds || 15) * 1000;\n const updatePosition = () => {\n // Keep watermark inside 10% - 80% range so it doesn't clip\n const top = Math.floor(10 + Math.random() * 70);\n const left = Math.floor(10 + Math.random() * 70);\n setCoords({ top: `${top}%`, left: `${left}%` });\n };\n\n updatePosition();\n const timer = setInterval(updatePosition, intervalMs);\n return () => clearInterval(timer);\n }, [parsedConfig?.position, parsedConfig?.intervalSeconds]);\n\n const getPositionStyles = (): React.CSSProperties => {\n switch (parsedConfig?.position) {\n case \"top-left\":\n return { top: \"16px\", left: \"16px\" };\n case \"top-right\":\n return { top: \"16px\", right: \"16px\" };\n case \"bottom-left\":\n return { bottom: \"48px\", left: \"16px\" };\n case \"bottom-right\":\n return { bottom: \"48px\", right: \"16px\" };\n case \"center\":\n return { top: \"50%\", left: \"50%\", transform: \"translate(-50%, -50%)\" };\n case \"dynamic\":\n default:\n return { top: coords.top, left: coords.left };\n }\n };\n\n if (!parsedConfig) return null;\n\n return (\n <div\n className=\"vexor-watermark\"\n style={{\n ...getPositionStyles(),\n opacity: Math.max(0, Math.min(1, parsedConfig.opacity ?? 0.35)),\n fontSize: parsedConfig.fontSize ?? \"12px\",\n color: parsedConfig.color ?? \"#ffffff\",\n }}\n aria-hidden=\"true\"\n >\n {parsedConfig.text}\n </div>\n );\n};\n","import Hls from \"hls.js\";\nimport type { VexorVanillaPlayerOptions } from \"./types\";\nimport { startNativeTokenRefresh } from \"../native-token-refresh\";\n\nexport interface VanillaPlayerInstance {\n play: () => Promise<void>;\n pause: () => void;\n seek: (seconds: number) => void;\n destroy: () => void;\n getElement: () => HTMLVideoElement;\n}\n\n/** Mount the Vexor player into an element without requiring React. */\nexport function createVexorPlayer(\n target: HTMLElement | string,\n options: VexorVanillaPlayerOptions\n): VanillaPlayerInstance {\n const container = typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!container) throw new Error(`Target container not found: ${String(target)}`);\n const initialUrl = options.src ?? (options.assetId\n ? `${(options.baseUrl || \"https://api.vexor.et\").replace(/\\/+$/, \"\")}/v1/playback/${encodeURIComponent(options.assetId)}/master.m3u8${options.token ? `?token=${encodeURIComponent(options.token)}` : \"\"}`\n : \"\");\n if (!initialUrl) throw new Error(\"Provide either src or assetId to create the Vexor player.\");\n\n const hadPlayerClass = container.classList.contains(\"vexor-player\");\n const hadProtectedClass = container.classList.contains(\"is-protected\");\n container.classList.add(\"vexor-player\");\n\n const video = document.createElement(\"video\");\n video.className = \"vexor-video\";\n video.controls = options.controls ?? true;\n video.playsInline = true;\n video.preload = options.preload ?? \"metadata\";\n if (options.poster) video.poster = options.poster;\n if (options.autoPlay) video.autoplay = true;\n if (options.muted) video.muted = true;\n if (options.loop) video.loop = true;\n container.appendChild(video);\n\n let watermarkElement: HTMLDivElement | null = null;\n let watermarkTimer: ReturnType<typeof setInterval> | undefined;\n if (options.watermark) {\n const watermark = typeof options.watermark === \"string\"\n ? { text: options.watermark, position: \"dynamic\" as const, intervalSeconds: 15, opacity: 0.35 }\n : { position: \"dynamic\" as const, intervalSeconds: 15, opacity: 0.35, ...options.watermark };\n watermarkElement = document.createElement(\"div\");\n watermarkElement.className = \"vexor-watermark\";\n watermarkElement.textContent = watermark.text;\n watermarkElement.style.opacity = String(Math.max(0, Math.min(1, watermark.opacity ?? 0.35)));\n watermarkElement.style.fontSize = typeof watermark.fontSize === \"number\" ? `${watermark.fontSize}px` : watermark.fontSize ?? \"12px\";\n watermarkElement.style.color = watermark.color ?? \"#ffffff\";\n\n const placeWatermark = () => {\n watermarkElement!.style.removeProperty(\"top\");\n watermarkElement!.style.removeProperty(\"right\");\n watermarkElement!.style.removeProperty(\"bottom\");\n watermarkElement!.style.removeProperty(\"left\");\n watermarkElement!.style.removeProperty(\"transform\");\n switch (watermark.position) {\n case \"top-left\": watermarkElement!.style.cssText += \";top:16px;left:16px\"; break;\n case \"top-right\": watermarkElement!.style.cssText += \";top:16px;right:16px\"; break;\n case \"bottom-left\": watermarkElement!.style.cssText += \";bottom:48px;left:16px\"; break;\n case \"bottom-right\": watermarkElement!.style.cssText += \";bottom:48px;right:16px\"; break;\n case \"center\": watermarkElement!.style.cssText += \";top:50%;left:50%;transform:translate(-50%,-50%)\"; break;\n default:\n watermarkElement!.style.top = `${10 + Math.floor(Math.random() * 70)}%`;\n watermarkElement!.style.left = `${10 + Math.floor(Math.random() * 70)}%`;\n }\n };\n placeWatermark();\n if (watermark.position === \"dynamic\") {\n watermarkTimer = setInterval(placeWatermark, Math.max(2, watermark.intervalSeconds || 15) * 1000);\n }\n container.appendChild(watermarkElement);\n }\n\n const onContextMenu = (event: Event) => event.preventDefault();\n const onDragStart = (event: Event) => event.preventDefault();\n if (options.protect) {\n container.classList.add(\"is-protected\");\n container.addEventListener(\"contextmenu\", onContextMenu);\n video.addEventListener(\"contextmenu\", onContextMenu);\n video.addEventListener(\"dragstart\", onDragStart);\n }\n\n let activeUrl = initialUrl;\n\n let hls: Hls | null = null;\n let nativeTokenRefresh: ReturnType<typeof startNativeTokenRefresh> | null = null;\n let nativeErrorListener: (() => void) | undefined;\n let destroyed = false;\n let refreshPromise: Promise<string> | null = null;\n let resumeAfterRefresh: { time: number; shouldPlay: boolean } | null = null;\n let hasSignaledReady = false;\n let activeParams = new URL(activeUrl, document.baseURI).search;\n const useFallback = (error?: { code: string; message: string; fatal: boolean }) => {\n if (options.fallbackSrc) {\n if (hls) hls.destroy();\n hls = null;\n video.src = options.fallbackSrc;\n video.load();\n } else if (error) options.onError?.(error);\n };\n const signalReady = () => {\n if (hasSignaledReady) return;\n hasSignaledReady = true;\n options.onReady?.();\n };\n const onLoaded = () => {\n signalReady();\n const resume = resumeAfterRefresh;\n resumeAfterRefresh = null;\n if (resume && Number.isFinite(resume.time)) video.currentTime = resume.time;\n if ((resume?.shouldPlay || options.autoPlay) && !destroyed) video.play().catch(() => {});\n };\n\n video.addEventListener(\"loadedmetadata\", onLoaded);\n video.addEventListener(\"loadeddata\", onLoaded);\n const onPlay = () => options.onPlay?.();\n const onPause = () => options.onPause?.();\n const onEnded = () => options.onEnded?.();\n video.addEventListener(\"play\", onPlay);\n video.addEventListener(\"pause\", onPause);\n video.addEventListener(\"ended\", onEnded);\n const onTimeUpdate = () => options.onTimeUpdate?.(video.currentTime, video.duration);\n video.addEventListener(\"timeupdate\", onTimeUpdate);\n\n const isHlsUrl = activeUrl.includes(\".m3u8\") || activeUrl.includes(\"/playback/\");\n if (isHlsUrl && Hls.isSupported()) {\n class TokenAwareLoader extends Hls.DefaultConfig.loader {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n load(context: any, config: any, callbacks: any) {\n if (activeParams && context?.url) {\n try {\n const sourceUrl = new URL(activeUrl, document.baseURI);\n const childUrl = new URL(context.url, sourceUrl);\n if (childUrl.origin === sourceUrl.origin && !childUrl.searchParams.has(\"token\")) {\n new URLSearchParams(activeParams).forEach((value, key) => {\n if (!childUrl.searchParams.has(key)) childUrl.searchParams.set(key, value);\n });\n context.url = childUrl.toString();\n }\n } catch {\n // Leave an unparseable child URL unchanged.\n }\n }\n super.load(context, config, callbacks);\n }\n }\n hls = new Hls({ enableWorker: true, loader: TokenAwareLoader as any, fLoader: TokenAwareLoader as any, pLoader: TokenAwareLoader as any });\n const activeHls = hls;\n activeHls.on(Hls.Events.MANIFEST_PARSED, () => {\n if (hls !== activeHls || destroyed) return;\n const resume = resumeAfterRefresh;\n resumeAfterRefresh = null;\n signalReady();\n if (resume && Number.isFinite(resume.time)) video.currentTime = resume.time;\n if ((resume?.shouldPlay || options.autoPlay) && !destroyed) video.play().catch(() => {});\n });\n activeHls.on(Hls.Events.ERROR, async (_event, data) => {\n if (hls !== activeHls || destroyed) return;\n if ((data.response?.code === 401 || data.response?.code === 403) && options.refreshToken) {\n try {\n refreshPromise ??= options.refreshToken();\n const newToken = await refreshPromise;\n refreshPromise = null;\n if (newToken && hls === activeHls && !destroyed) {\n resumeAfterRefresh = { time: video.currentTime, shouldPlay: !video.paused };\n const url = new URL(activeUrl, document.baseURI);\n url.searchParams.set(\"token\", newToken);\n activeUrl = url.toString();\n activeParams = url.search;\n activeHls.loadSource(activeUrl);\n activeHls.startLoad();\n return;\n }\n } catch {\n refreshPromise = null;\n }\n }\n if (hls !== activeHls || destroyed) return;\n if (data.fatal) useFallback({ code: data.details || \"MEDIA_PLAYBACK_ERROR\", message: `Failed to stream video: ${data.details || \"network error\"}`, fatal: true });\n });\n activeHls.loadSource(activeUrl);\n activeHls.attachMedia(video);\n } else if (isHlsUrl && video.canPlayType(\"application/vnd.apple.mpegurl\")) {\n video.src = activeUrl;\n nativeTokenRefresh = startNativeTokenRefresh(video, activeUrl, options.refreshToken);\n nativeErrorListener = () => {\n void nativeTokenRefresh?.refreshNow().then((refreshed) => {\n if (refreshed || destroyed) return;\n video.removeEventListener(\"error\", nativeErrorListener!);\n useFallback({ code: \"NATIVE_HLS_ERROR\", message: \"Failed to play native HLS stream\", fatal: true });\n });\n };\n video.addEventListener(\"error\", nativeErrorListener);\n } else if (!isHlsUrl || options.fallbackSrc) {\n video.src = isHlsUrl ? options.fallbackSrc! : activeUrl;\n } else {\n useFallback({ code: \"HLS_UNSUPPORTED\", message: \"This browser does not support HLS playback.\", fatal: true });\n }\n\n return {\n play: () => video.play(),\n pause: () => video.pause(),\n seek: (seconds) => { video.currentTime = Math.max(0, Math.min(seconds, video.duration || seconds)); },\n destroy: () => {\n if (destroyed) return;\n destroyed = true;\n nativeTokenRefresh?.stop();\n if (hls) hls.destroy();\n hls = null;\n if (watermarkTimer) clearInterval(watermarkTimer);\n container.removeEventListener(\"contextmenu\", onContextMenu);\n video.removeEventListener(\"contextmenu\", onContextMenu);\n video.removeEventListener(\"dragstart\", onDragStart);\n video.removeEventListener(\"loadedmetadata\", onLoaded);\n video.removeEventListener(\"loadeddata\", onLoaded);\n video.removeEventListener(\"play\", onPlay);\n video.removeEventListener(\"pause\", onPause);\n video.removeEventListener(\"ended\", onEnded);\n video.removeEventListener(\"timeupdate\", onTimeUpdate);\n if (nativeErrorListener) video.removeEventListener(\"error\", nativeErrorListener);\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n video.remove();\n watermarkElement?.remove();\n if (!hadPlayerClass) container.classList.remove(\"vexor-player\");\n if (options.protect && !hadProtectedClass) container.classList.remove(\"is-protected\");\n },\n getElement: () => video,\n };\n}\n"],"mappings":"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","names":["import_react","onError","Hls","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_hls","Hls"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/VexorPlayer.tsx","../src/hooks/useVexorPlayer.ts","../src/native-token-refresh.ts","../src/components/Controls.tsx","../src/components/Watermark.tsx","../src/vanilla/player.ts"],"sourcesContent":["\"use client\";\n\nimport \"./styles/player.css\";\n\nexport { VexorPlayer } from \"./components/VexorPlayer\";\nexport { Controls } from \"./components/Controls\";\nexport { Watermark } from \"./components/Watermark\";\nexport { useVexorPlayer } from \"./hooks/useVexorPlayer\";\nexport { createVexorPlayer } from \"./vanilla/player\";\n\nexport type {\n VexorPlayerProps,\n QualityLevel,\n WatermarkConfig,\n} from \"./types\";\n\nexport type {\n UseVexorPlayerReturn,\n} from \"./hooks/useVexorPlayer\";\n\nexport type {\n VanillaPlayerInstance,\n} from \"./vanilla/player\";\n","import React, { useState, useEffect, useRef, useCallback } from \"react\";\nimport { useVexorPlayer } from \"../hooks/useVexorPlayer\";\nimport { Controls } from \"./Controls\";\nimport { Watermark } from \"./Watermark\";\nimport type { VexorPlayerProps } from \"../types\";\n\nexport const VexorPlayer: React.FC<VexorPlayerProps> = (props) => {\n const {\n poster,\n preload = \"metadata\",\n muted = false,\n loop = false,\n controls = true,\n nativeControls = false,\n watermark,\n protect = false,\n className = \"\",\n style,\n children,\n } = props;\n\n const player = useVexorPlayer(props);\n const [controlsVisible, setControlsVisible] = useState(true);\n const hideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const resetHideTimer = useCallback(() => {\n setControlsVisible(true);\n if (hideTimerRef.current) {\n clearTimeout(hideTimerRef.current);\n }\n if (player.isPlaying && !player.containerRef.current?.contains(document.activeElement)) {\n hideTimerRef.current = setTimeout(() => {\n setControlsVisible(false);\n }, 2500);\n }\n }, [player.isPlaying]);\n\n useEffect(() => {\n resetHideTimer();\n return () => {\n if (hideTimerRef.current) clearTimeout(hideTimerRef.current);\n };\n }, [player.isPlaying, resetHideTimer]);\n\n // Anti-tamper protection handlers\n const handleContextMenu = (e: React.MouseEvent) => {\n if (protect) {\n e.preventDefault();\n }\n };\n\n // Keyboard navigation & shortcuts\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Leave keystrokes to focused form controls, buttons, and custom controls.\n const target = e.target as HTMLElement;\n if (target?.closest(\"input, textarea, select, button, [contenteditable='true'], [role='slider']\")) return;\n\n const container = player.containerRef.current;\n if (!container || (!document.fullscreenElement && !container.contains(document.activeElement) && !container.matches(\":hover\"))) {\n return;\n }\n\n switch (e.key.toLowerCase()) {\n case \" \":\n case \"k\":\n e.preventDefault();\n player.togglePlay();\n resetHideTimer();\n break;\n case \"arrowleft\":\n case \"j\":\n e.preventDefault();\n player.seek(player.currentTime - 5);\n resetHideTimer();\n break;\n case \"arrowright\":\n case \"l\":\n e.preventDefault();\n player.seek(player.currentTime + 5);\n resetHideTimer();\n break;\n case \"arrowup\":\n e.preventDefault();\n player.setVolume(player.volume + 0.1);\n resetHideTimer();\n break;\n case \"arrowdown\":\n e.preventDefault();\n player.setVolume(player.volume - 0.1);\n resetHideTimer();\n break;\n case \"m\":\n e.preventDefault();\n player.toggleMute();\n resetHideTimer();\n break;\n case \"f\":\n e.preventDefault();\n player.toggleFullscreen();\n resetHideTimer();\n break;\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [player, resetHideTimer]);\n\n return (\n <div\n ref={player.containerRef}\n className={`vexor-player ${player.isFullscreen ? \"is-fullscreen\" : \"\"} ${protect ? \"is-protected\" : \"\"} ${className}`}\n style={style}\n onMouseMove={resetHideTimer}\n onMouseLeave={(event) => {\n if (player.isPlaying && !event.currentTarget.contains(document.activeElement)) {\n setControlsVisible(false);\n }\n }}\n onFocusCapture={() => {\n if (hideTimerRef.current) clearTimeout(hideTimerRef.current);\n setControlsVisible(true);\n }}\n onBlurCapture={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) resetHideTimer();\n }}\n onContextMenu={handleContextMenu}\n tabIndex={0}\n role=\"region\"\n aria-label=\"Video Player\"\n >\n <video\n ref={player.videoRef}\n className=\"vexor-video\"\n poster={poster}\n preload={preload}\n muted={muted}\n loop={loop}\n playsInline\n controls={nativeControls}\n onClick={nativeControls ? undefined : player.togglePlay}\n />\n\n {/* Watermark Overlay */}\n {watermark && <Watermark config={watermark} />}\n\n {/* Buffering Spinner */}\n {player.isBuffering && !player.error && (\n <div className=\"vexor-spinner-overlay\" aria-label=\"Buffering video\">\n <div className=\"vexor-spinner\" />\n </div>\n )}\n\n {/* Center Big Play Button (when paused, not buffering, and custom controls active) */}\n {!nativeControls && controls && !player.isPlaying && !player.isBuffering && !player.error && (\n <button type=\"button\" className=\"vexor-center-play-overlay\" onClick={player.togglePlay} aria-label=\"Play video\">\n <span className=\"vexor-center-play-button\" aria-hidden=\"true\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <polygon points=\"6,4 20,12 6,20\" />\n </svg>\n </span>\n </button>\n )}\n\n {/* Custom Controls Bar */}\n {!nativeControls && controls && !player.error && (\n <Controls\n isPlaying={player.isPlaying}\n isBuffering={player.isBuffering}\n currentTime={player.currentTime}\n duration={player.duration}\n buffered={player.buffered}\n volume={player.volume}\n isMuted={player.isMuted}\n isFullscreen={player.isFullscreen}\n qualityLevels={player.qualityLevels}\n currentQuality={player.currentQuality}\n playbackRate={player.playbackRate}\n visible={controlsVisible}\n onPlayPause={player.togglePlay}\n onSeek={player.seek}\n onVolumeChange={player.setVolume}\n onToggleMute={player.toggleMute}\n onQualityChange={player.setQuality}\n onPlaybackRateChange={player.setPlaybackRate}\n onToggleFullscreen={player.toggleFullscreen}\n onTogglePiP={player.togglePiP}\n />\n )}\n\n {/* Error Overlay */}\n {player.error && (\n <div className=\"vexor-error-overlay\">\n <div className=\"vexor-error-title\">Playback Error</div>\n <div className=\"vexor-error-message\">{player.error.message}</div>\n <button type=\"button\" className=\"vexor-retry-button\" onClick={player.retry}>\n Retry Playback\n </button>\n </div>\n )}\n\n {/* Custom Child Overlays */}\n {children}\n </div>\n );\n};\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport Hls from \"hls.js\";\nimport type { QualityLevel, VexorPlayerProps } from \"../types\";\nimport { startNativeTokenRefresh } from \"../native-token-refresh\";\n\nexport interface UseVexorPlayerReturn {\n videoRef: React.RefObject<HTMLVideoElement | null>;\n containerRef: React.RefObject<HTMLDivElement | null>;\n isPlaying: boolean;\n isBuffering: boolean;\n currentTime: number;\n duration: number;\n buffered: number;\n volume: number;\n isMuted: boolean;\n isFullscreen: boolean;\n qualityLevels: QualityLevel[];\n currentQuality: number;\n playbackRate: number;\n error: { code: string; message: string; fatal: boolean } | null;\n play: () => Promise<void>;\n pause: () => void;\n togglePlay: () => void;\n seek: (time: number) => void;\n setVolume: (vol: number) => void;\n toggleMute: () => void;\n setQuality: (levelIndex: number) => void;\n setPlaybackRate: (rate: number) => void;\n toggleFullscreen: () => void;\n togglePiP: () => void;\n retry: () => void;\n}\n\nexport function useVexorPlayer({\n src,\n assetId,\n token,\n baseUrl = \"https://api.vexor.et\",\n fallbackSrc,\n autoPlay = false,\n muted = false,\n refreshToken,\n onReady,\n onPlay,\n onPause,\n onEnded,\n onTimeUpdate,\n onError,\n onQualityChange,\n}: VexorPlayerProps): UseVexorPlayerReturn {\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const hlsRef = useRef<Hls | null>(null);\n const callbacksRef = useRef({ onReady, onPlay, onPause, onEnded, onTimeUpdate, onError, onQualityChange, refreshToken });\n callbacksRef.current = { onReady, onPlay, onPause, onEnded, onTimeUpdate, onError, onQualityChange, refreshToken };\n const activeParamsRef = useRef(\"\");\n const refreshPromiseRef = useRef<Promise<string> | null>(null);\n const resumeAfterRefreshRef = useRef<{ time: number; shouldPlay: boolean } | null>(null);\n\n const [isPlaying, setIsPlaying] = useState(false);\n const [isBuffering, setIsBuffering] = useState(true);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [buffered, setBuffered] = useState(0);\n const [volume, setVolumeState] = useState(1);\n const [isMuted, setIsMuted] = useState(muted);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [qualityLevels, setQualityLevels] = useState<QualityLevel[]>([]);\n const [currentQuality, setCurrentQuality] = useState(-1);\n const [playbackRate, setPlaybackRateState] = useState(1);\n const [error, setError] = useState<{ code: string; message: string; fatal: boolean } | null>(null);\n const [reloadTrigger, setReloadTrigger] = useState(0);\n\n // Determine effective playback manifest URL\n const activeUrl = src\n ? src\n : assetId\n ? `${baseUrl.replace(/\\/+$/, \"\")}/v1/playback/${encodeURIComponent(assetId)}/master.m3u8${token ? `?token=${encodeURIComponent(token)}` : \"\"}`\n : \"\";\n\n const destroyHls = useCallback(() => {\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n }, []);\n\n const retry = useCallback(() => {\n setError(null);\n setIsBuffering(true);\n setReloadTrigger((v) => v + 1);\n }, []);\n\n // Initialize HLS & Media Source\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n let cleanupFallback = () => {};\n const loadFallback = () => {\n if (!fallbackSrc) return false;\n destroyHls();\n setIsBuffering(true);\n video.src = fallbackSrc;\n const onLoaded = () => {\n setIsBuffering(false);\n callbacksRef.current.onReady?.();\n };\n const onError = () => {\n const errObj = {\n code: \"FALLBACK_PLAYBACK_ERROR\",\n message: \"Unable to load fallback media source\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n video.addEventListener(\"loadeddata\", onLoaded);\n video.addEventListener(\"error\", onError);\n cleanupFallback = () => {\n video.removeEventListener(\"loadeddata\", onLoaded);\n video.removeEventListener(\"error\", onError);\n };\n video.load();\n return true;\n };\n const setFatalError = (code: string, message: string) => {\n destroyHls();\n const errObj = { code, message, fatal: true };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n\n destroyHls();\n setError(null);\n setCurrentTime(0);\n setDuration(0);\n setBuffered(0);\n setQualityLevels([]);\n setCurrentQuality(-1);\n setIsBuffering(Boolean(activeUrl));\n if (!activeUrl) {\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n return;\n }\n\n const isHlsUrl = activeUrl.includes(\".m3u8\") || activeUrl.includes(\"/playback/\");\n let fatalRecoveryAttempts = 0;\n\n if (isHlsUrl && Hls.isSupported()) {\n activeParamsRef.current = activeUrl.includes(\"?\") ? activeUrl.substring(activeUrl.indexOf(\"?\")) : \"\";\n\n class VexorLoader extends Hls.DefaultConfig.loader {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n load(context: any, config: any, callbacks: any) {\n // Propagate token query params to child playlists and segments if not present\n const activeParams = activeParamsRef.current;\n if (activeParams && context?.url) {\n try {\n const sourceUrl = new URL(activeUrl, window.location.href);\n const childUrl = new URL(context.url, sourceUrl);\n if (childUrl.origin === sourceUrl.origin && !childUrl.searchParams.has(\"token\")) {\n new URLSearchParams(activeParams).forEach((value, key) => {\n if (!childUrl.searchParams.has(key)) childUrl.searchParams.set(key, value);\n });\n context.url = childUrl.toString();\n }\n } catch {\n // Leave an unparseable child URL untouched; the loader will report failures normally.\n }\n }\n super.load(context, config, callbacks);\n }\n }\n\n const hls = new Hls({\n startFragPrefetch: true,\n maxBufferLength: 30,\n maxMaxBufferLength: 60,\n enableWorker: true,\n lowLatencyMode: true,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n loader: VexorLoader as any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fLoader: VexorLoader as any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n pLoader: VexorLoader as any,\n });\n hlsRef.current = hls;\n\n hls.loadSource(activeUrl);\n hls.attachMedia(video);\n\n hls.on(Hls.Events.MANIFEST_PARSED, (_event, data) => {\n if (hlsRef.current !== hls) return;\n setIsBuffering(false);\n const levels: QualityLevel[] = data.levels.map((lvl, index) => {\n let label = `${lvl.height}p`;\n if (lvl.height === 0 || lvl.videoCodec === undefined) {\n label = \"Audio only\";\n }\n return {\n id: index,\n height: lvl.height,\n width: lvl.width,\n bitrate: lvl.bitrate,\n label,\n };\n });\n setQualityLevels(levels);\n callbacksRef.current.onReady?.();\n const resume = resumeAfterRefreshRef.current;\n if (resume) {\n resumeAfterRefreshRef.current = null;\n if (Number.isFinite(resume.time) && resume.time > 0) video.currentTime = resume.time;\n if (resume.shouldPlay) video.play().catch(() => {});\n }\n if (autoPlay) {\n video.play().catch(() => {\n // Autoplay might be blocked by browser policy; user can interact to start\n });\n }\n });\n\n hls.on(Hls.Events.LEVEL_SWITCHED, (_event, data) => {\n if (hlsRef.current !== hls) return;\n setCurrentQuality(hls.autoLevelEnabled ? -1 : data.level);\n callbacksRef.current.onQualityChange?.(hls.autoLevelEnabled ? -1 : data.level);\n });\n\n hls.on(Hls.Events.ERROR, async (_event, data) => {\n if (hlsRef.current !== hls) return;\n // Handle token expiry (HTTP 401 or 403 on key/segment)\n if (\n (data.response?.code === 401 || data.response?.code === 403) &&\n callbacksRef.current.refreshToken\n ) {\n try {\n if (!refreshPromiseRef.current) {\n refreshPromiseRef.current = callbacksRef.current.refreshToken();\n }\n const newToken = await refreshPromiseRef.current;\n refreshPromiseRef.current = null;\n if (newToken && hlsRef.current === hls) {\n resumeAfterRefreshRef.current = {\n time: video.currentTime,\n shouldPlay: !video.paused,\n };\n const url = new URL(activeUrl, window.location.href);\n url.searchParams.set(\"token\", newToken);\n activeParamsRef.current = url.search;\n hls.loadSource(url.toString());\n hls.startLoad();\n return;\n }\n } catch {\n refreshPromiseRef.current = null;\n // Fall through to standard error handling if token refresh fails\n }\n }\n\n if (hlsRef.current !== hls) return;\n\n if (data.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n if (fatalRecoveryAttempts++ < 1) {\n hls.startLoad();\n } else if (!loadFallback()) {\n setFatalError(data.details || \"NETWORK_ERROR\", `Failed to stream video: ${data.details || \"network error\"}`);\n }\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n if (fatalRecoveryAttempts++ < 1) {\n hls.recoverMediaError();\n } else if (!loadFallback()) {\n setFatalError(data.details || \"MEDIA_ERROR\", `Failed to stream video: ${data.details || \"media error\"}`);\n }\n break;\n default:\n if (!loadFallback()) {\n setFatalError(data.details || \"MEDIA_PLAYBACK_ERROR\", `Failed to stream video: ${data.details || \"network error\"}`);\n }\n break;\n }\n }\n });\n } else if (isHlsUrl && video.canPlayType(\"application/vnd.apple.mpegurl\")) {\n // Safari / iOS Native HLS\n video.src = activeUrl;\n const nativeTokenRefresh = startNativeTokenRefresh(\n video,\n activeUrl,\n callbacksRef.current.refreshToken,\n );\n const onLoaded = () => {\n setIsBuffering(false);\n callbacksRef.current.onReady?.();\n if (autoPlay) {\n video.play().catch(() => {});\n }\n };\n const onNativeError = () => {\n void nativeTokenRefresh.refreshNow().then((refreshed) => {\n if (refreshed || hlsRef.current) return;\n if (loadFallback()) {\n video.removeEventListener(\"error\", onNativeError);\n return;\n }\n setFatalError(\"NATIVE_HLS_ERROR\", \"Failed to play native HLS stream\");\n });\n };\n video.addEventListener(\"loadedmetadata\", onLoaded);\n video.addEventListener(\"error\", onNativeError);\n return () => {\n nativeTokenRefresh.stop();\n video.removeEventListener(\"loadedmetadata\", onLoaded);\n video.removeEventListener(\"error\", onNativeError);\n };\n } else if (!isHlsUrl) {\n // Standard MP4 progressive playback\n video.src = activeUrl;\n const onLoaded = () => {\n setIsBuffering(false);\n callbacksRef.current.onReady?.();\n };\n const onErr = () => {\n const errObj = {\n code: \"DIRECT_PLAYBACK_ERROR\",\n message: \"Unable to load media source\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n video.addEventListener(\"loadeddata\", onLoaded);\n video.addEventListener(\"error\", onErr);\n return () => {\n video.removeEventListener(\"loadeddata\", onLoaded);\n video.removeEventListener(\"error\", onErr);\n };\n } else if (fallbackSrc) {\n // HLS unsupported: use the configured progressive fallback.\n loadFallback();\n } else {\n const errObj = {\n code: \"HLS_UNSUPPORTED\",\n message: \"This browser does not support HLS playback and no fallback source was provided\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n }\n\n return () => {\n cleanupFallback();\n destroyHls();\n };\n }, [activeUrl, fallbackSrc, autoPlay, reloadTrigger, destroyHls]);\n\n // Video Element Event Listeners\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n const onPlayEvent = () => {\n setIsPlaying(true);\n callbacksRef.current.onPlay?.();\n };\n\n const onPauseEvent = () => {\n setIsPlaying(false);\n callbacksRef.current.onPause?.();\n };\n\n const onEndedEvent = () => {\n setIsPlaying(false);\n callbacksRef.current.onEnded?.();\n };\n\n const onWaiting = () => setIsBuffering(true);\n const onPlaying = () => setIsBuffering(false);\n\n const onTimeUpdateEvent = () => {\n setCurrentTime(video.currentTime);\n callbacksRef.current.onTimeUpdate?.(video.currentTime, video.duration);\n\n // Calculate buffer progress\n if (video.buffered.length > 0 && video.duration > 0) {\n for (let i = video.buffered.length - 1; i >= 0; i--) {\n if (video.buffered.start(i) <= video.currentTime) {\n setBuffered((video.buffered.end(i) / video.duration) * 100);\n break;\n }\n }\n }\n };\n\n const onDurationChange = () => setDuration(video.duration || 0);\n const onVolumeChangeEvent = () => {\n setVolumeState(video.volume);\n setIsMuted(video.muted);\n };\n\n video.addEventListener(\"play\", onPlayEvent);\n video.addEventListener(\"pause\", onPauseEvent);\n video.addEventListener(\"ended\", onEndedEvent);\n video.addEventListener(\"waiting\", onWaiting);\n video.addEventListener(\"playing\", onPlaying);\n video.addEventListener(\"timeupdate\", onTimeUpdateEvent);\n video.addEventListener(\"durationchange\", onDurationChange);\n video.addEventListener(\"volumechange\", onVolumeChangeEvent);\n\n return () => {\n video.removeEventListener(\"play\", onPlayEvent);\n video.removeEventListener(\"pause\", onPauseEvent);\n video.removeEventListener(\"ended\", onEndedEvent);\n video.removeEventListener(\"waiting\", onWaiting);\n video.removeEventListener(\"playing\", onPlaying);\n video.removeEventListener(\"timeupdate\", onTimeUpdateEvent);\n video.removeEventListener(\"durationchange\", onDurationChange);\n video.removeEventListener(\"volumechange\", onVolumeChangeEvent);\n };\n }, []);\n\n // Fullscreen change listener\n useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen(Boolean(document.fullscreenElement));\n };\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, []);\n\n // Player Actions\n const play = useCallback(async () => {\n if (videoRef.current) {\n await videoRef.current.play();\n }\n }, []);\n\n const pause = useCallback(() => {\n if (videoRef.current) {\n videoRef.current.pause();\n }\n }, []);\n\n const togglePlay = useCallback(() => {\n if (!videoRef.current) return;\n if (videoRef.current.paused) {\n videoRef.current.play().catch(() => {});\n } else {\n videoRef.current.pause();\n }\n }, []);\n\n const seek = useCallback((time: number) => {\n if (videoRef.current) {\n videoRef.current.currentTime = Math.max(0, Math.min(time, videoRef.current.duration || time));\n }\n }, []);\n\n const setVolume = useCallback((vol: number) => {\n if (videoRef.current) {\n const clamped = Math.max(0, Math.min(1, vol));\n videoRef.current.volume = clamped;\n videoRef.current.muted = clamped === 0;\n }\n }, []);\n\n const toggleMute = useCallback(() => {\n if (videoRef.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n }, []);\n\n const setQuality = useCallback((levelIndex: number) => {\n if (hlsRef.current) {\n if (levelIndex === -1) {\n hlsRef.current.currentLevel = -1; // Auto\n } else {\n hlsRef.current.currentLevel = levelIndex;\n }\n setCurrentQuality(levelIndex);\n }\n }, []);\n\n const setPlaybackRate = useCallback((rate: number) => {\n if (videoRef.current) {\n videoRef.current.playbackRate = rate;\n setPlaybackRateState(rate);\n }\n }, []);\n\n const toggleFullscreen = useCallback(() => {\n const container = containerRef.current || videoRef.current;\n if (!container) return;\n\n if (!document.fullscreenElement) {\n container.requestFullscreen().catch(() => {});\n } else {\n document.exitFullscreen().catch(() => {});\n }\n }, []);\n\n const togglePiP = useCallback(async () => {\n const video = videoRef.current;\n if (!video) return;\n\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else if (document.pictureInPictureEnabled) {\n await video.requestPictureInPicture();\n }\n } catch {\n // Ignored\n }\n }, []);\n\n return {\n videoRef,\n containerRef,\n isPlaying,\n isBuffering,\n currentTime,\n duration,\n buffered,\n volume,\n isMuted,\n isFullscreen,\n qualityLevels,\n currentQuality,\n playbackRate,\n error,\n play,\n pause,\n togglePlay,\n seek,\n setVolume,\n toggleMute,\n setQuality,\n setPlaybackRate,\n toggleFullscreen,\n togglePiP,\n retry,\n };\n}\n","const TOKEN_REFRESH_INTERVAL_MS = 4 * 60 * 1000;\nconst TOKEN_REFRESH_RETRY_MS = 30 * 1000;\n\n/**\n * Refresh native-HLS playback before Vexor's five-minute token expires.\n * Browsers do not expose the native HLS request status to JavaScript, so this\n * timer complements the reactive 401/403 handling used by hls.js.\n */\nexport function startNativeTokenRefresh(\n video: HTMLVideoElement,\n initialUrl: string,\n refreshToken?: () => Promise<string>,\n): { refreshNow: () => Promise<boolean>; stop: () => void } {\n let currentUrl = initialUrl;\n let disposed = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let refreshInFlight: Promise<boolean> | null = null;\n let restoreListener: (() => void) | undefined;\n\n const schedule = (delay = TOKEN_REFRESH_INTERVAL_MS) => {\n if (!refreshToken || disposed) return;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => void refreshNow(), delay);\n };\n\n const refreshNow = (): Promise<boolean> => {\n if (!refreshToken || disposed) return Promise.resolve(false);\n if (refreshInFlight) return refreshInFlight;\n\n refreshInFlight = (async () => {\n try {\n const token = await refreshToken();\n if (disposed || !token) return false;\n\n const nextUrl = new URL(currentUrl, document.baseURI);\n nextUrl.searchParams.set(\"token\", token);\n currentUrl = nextUrl.toString();\n\n const resumeTime = video.currentTime;\n const shouldResume = !video.paused;\n restoreListener = () => {\n restoreListener = undefined;\n if (disposed) return;\n if (Number.isFinite(resumeTime) && resumeTime > 0) {\n try {\n video.currentTime = resumeTime;\n } catch {\n // The new manifest may not have loaded enough media to seek yet.\n }\n }\n if (shouldResume) video.play().catch(() => {});\n };\n video.addEventListener(\"loadedmetadata\", restoreListener, { once: true });\n video.src = currentUrl;\n video.load();\n schedule();\n return true;\n } catch {\n // Retry soon; do not keep using a token that is about to expire.\n schedule(TOKEN_REFRESH_RETRY_MS);\n return false;\n } finally {\n refreshInFlight = null;\n }\n })();\n\n return refreshInFlight;\n };\n\n schedule();\n\n return {\n refreshNow,\n stop: () => {\n disposed = true;\n if (timer) clearTimeout(timer);\n if (restoreListener) video.removeEventListener(\"loadedmetadata\", restoreListener);\n },\n };\n}\n","import React, { useState, useRef, useEffect, useCallback } from \"react\";\nimport type { QualityLevel } from \"../types\";\n\ninterface ControlsProps {\n isPlaying: boolean;\n isBuffering: boolean;\n currentTime: number;\n duration: number;\n buffered: number;\n volume: number;\n isMuted: boolean;\n isFullscreen: boolean;\n qualityLevels: QualityLevel[];\n currentQuality: number;\n playbackRate: number;\n visible: boolean;\n onPlayPause: () => void;\n onSeek: (time: number) => void;\n onVolumeChange: (volume: number) => void;\n onToggleMute: () => void;\n onQualityChange: (levelIndex: number) => void;\n onPlaybackRateChange: (rate: number) => void;\n onToggleFullscreen: () => void;\n onTogglePiP: () => void;\n}\n\nfunction formatTime(seconds: number): string {\n if (isNaN(seconds) || seconds < 0) return \"0:00\";\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = Math.floor(seconds % 60);\n if (h > 0) {\n return `${h}:${m.toString().padStart(2, \"0\")}:${s.toString().padStart(2, \"0\")}`;\n }\n return `${m}:${s.toString().padStart(2, \"0\")}`;\n}\n\nexport const Controls: React.FC<ControlsProps> = ({\n isPlaying,\n currentTime,\n duration,\n buffered,\n volume,\n isMuted,\n isFullscreen,\n qualityLevels,\n currentQuality,\n playbackRate,\n visible,\n onPlayPause,\n onSeek,\n onVolumeChange,\n onToggleMute,\n onQualityChange,\n onPlaybackRateChange,\n onToggleFullscreen,\n onTogglePiP,\n}) => {\n const [showQualityMenu, setShowQualityMenu] = useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = useState(false);\n const progressRef = useRef<HTMLDivElement>(null);\n const [isScrubbing, setIsScrubbing] = useState(false);\n const [pictureInPictureSupported, setPictureInPictureSupported] = useState(false);\n\n useEffect(() => {\n setPictureInPictureSupported(\n typeof document !== \"undefined\" && document.pictureInPictureEnabled\n );\n }, []);\n\n const playedPercent = duration > 0 ? (currentTime / duration) * 100 : 0;\n const speedOptions = [0.5, 0.75, 1, 1.25, 1.5, 2];\n\n const handleScrub = useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n if (!progressRef.current || duration <= 0) return;\n const rect = progressRef.current.getBoundingClientRect();\n const pos = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n onSeek(pos * duration);\n },\n [duration, onSeek]\n );\n\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n if (e.button !== 0) return;\n e.currentTarget.setPointerCapture(e.pointerId);\n setIsScrubbing(true);\n handleScrub(e);\n };\n\n const handleTimelineKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (duration <= 0) return;\n const step = e.shiftKey ? 30 : 5;\n let nextTime: number | undefined;\n if (e.key === \"ArrowLeft\") nextTime = currentTime - step;\n if (e.key === \"ArrowRight\") nextTime = currentTime + step;\n if (e.key === \"Home\") nextTime = 0;\n if (e.key === \"End\") nextTime = duration;\n if (nextTime !== undefined) {\n e.preventDefault();\n onSeek(Math.max(0, Math.min(duration, nextTime)));\n }\n };\n\n return (\n <div className={`vexor-controls ${visible ? \"\" : \"is-hidden\"}`}>\n {/* Timeline Scrubber */}\n <div\n className=\"vexor-progress-container\"\n ref={progressRef}\n onPointerDown={handlePointerDown}\n onPointerMove={(event) => { if (isScrubbing) handleScrub(event); }}\n onPointerUp={(event) => {\n if (progressRef.current?.hasPointerCapture(event.pointerId)) {\n progressRef.current.releasePointerCapture(event.pointerId);\n }\n setIsScrubbing(false);\n }}\n onPointerCancel={() => setIsScrubbing(false)}\n onKeyDown={handleTimelineKeyDown}\n tabIndex={0}\n role=\"slider\"\n aria-label=\"Video timeline\"\n aria-valuemin={0}\n aria-valuemax={duration}\n aria-valuenow={Math.min(currentTime, duration || 0)}\n aria-valuetext={`${formatTime(currentTime)} of ${formatTime(duration)}`}\n >\n <div className=\"vexor-progress-track\">\n <div className=\"vexor-progress-buffer\" style={{ width: `${buffered}%` }} />\n <div className=\"vexor-progress-played\" style={{ width: `${playedPercent}%` }} />\n <div className=\"vexor-progress-thumb\" style={{ left: `${playedPercent}%` }} />\n </div>\n </div>\n\n {/* Control Buttons Row */}\n <div className=\"vexor-controls-row\">\n {/* Left Side: Play/Pause, Volume, Time */}\n <div className=\"vexor-controls-group\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onPlayPause}\n aria-label={isPlaying ? \"Pause\" : \"Play\"}\n >\n {isPlaying ? (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <polygon points=\"5,3 19,12 5,21\" />\n </svg>\n )}\n </button>\n\n <div className=\"vexor-volume-wrapper\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onToggleMute}\n aria-label={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\" />\n <line x1=\"17\" y1=\"9\" x2=\"23\" y2=\"15\" />\n </svg>\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\" />\n </svg>\n )}\n </button>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n value={isMuted ? 0 : volume}\n onChange={(e) => onVolumeChange(parseFloat(e.target.value))}\n className=\"vexor-volume-slider\"\n aria-label=\"Volume slider\"\n />\n </div>\n\n <span className=\"vexor-time-display\">\n {formatTime(currentTime)} / {formatTime(duration)}\n </span>\n </div>\n\n {/* Right Side: Speed, Quality, PiP, Fullscreen */}\n <div className=\"vexor-controls-group\">\n {/* Speed Selector */}\n <div className=\"vexor-menu-anchor\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={() => {\n setShowSpeedMenu(!showSpeedMenu);\n setShowQualityMenu(false);\n }}\n aria-label=\"Playback speed\"\n style={{ fontSize: \"11px\", fontWeight: 600, padding: \"4px 8px\" }}\n >\n {playbackRate === 1 ? \"1x\" : `${playbackRate}x`}\n </button>\n\n {showSpeedMenu && (\n <div className=\"vexor-menu-dropdown\">\n {speedOptions.map((rate) => (\n <button\n key={rate}\n type=\"button\"\n className={`vexor-menu-item ${playbackRate === rate ? \"is-active\" : \"\"}`}\n onClick={() => {\n onPlaybackRateChange(rate);\n setShowSpeedMenu(false);\n }}\n >\n <span>{rate}x</span>\n {playbackRate === rate && <span>✓</span>}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Quality Levels Selector */}\n {qualityLevels.length > 0 && (\n <div className=\"vexor-menu-anchor\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={() => {\n setShowQualityMenu(!showQualityMenu);\n setShowSpeedMenu(false);\n }}\n aria-label=\"Video quality\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\" />\n </svg>\n </button>\n\n {showQualityMenu && (\n <div className=\"vexor-menu-dropdown\">\n <button\n type=\"button\"\n className={`vexor-menu-item ${currentQuality === -1 ? \"is-active\" : \"\"}`}\n onClick={() => {\n onQualityChange(-1);\n setShowQualityMenu(false);\n }}\n >\n <span>Auto</span>\n {currentQuality === -1 && <span>✓</span>}\n </button>\n {qualityLevels.map((lvl) => (\n <button\n key={lvl.id}\n type=\"button\"\n className={`vexor-menu-item ${currentQuality === lvl.id ? \"is-active\" : \"\"}`}\n onClick={() => {\n onQualityChange(lvl.id);\n setShowQualityMenu(false);\n }}\n >\n <span>{lvl.label}</span>\n {currentQuality === lvl.id && <span>✓</span>}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Picture in Picture */}\n {pictureInPictureSupported && (\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onTogglePiP}\n aria-label=\"Picture in picture\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" />\n <rect x=\"12\" y=\"9\" width=\"8\" height=\"6\" rx=\"1\" fill=\"currentColor\" fillOpacity=\"0.4\" />\n </svg>\n </button>\n )}\n\n {/* Fullscreen Toggle */}\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onToggleFullscreen}\n aria-label={isFullscreen ? \"Exit fullscreen\" : \"Enter fullscreen\"}\n >\n {isFullscreen ? (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3\" />\n </svg>\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\" />\n </svg>\n )}\n </button>\n </div>\n </div>\n </div>\n );\n};\n","import React, { useEffect, useState, useMemo } from \"react\";\nimport type { WatermarkConfig } from \"../types\";\n\ninterface WatermarkProps {\n config?: string | WatermarkConfig;\n}\n\nexport const Watermark: React.FC<WatermarkProps> = ({ config }) => {\n const parsedConfig: WatermarkConfig | null = useMemo(() => {\n if (!config) return null;\n if (typeof config === \"string\") {\n return { text: config, position: \"dynamic\", intervalSeconds: 15, opacity: 0.35 };\n }\n return {\n position: \"dynamic\",\n intervalSeconds: 15,\n opacity: 0.35,\n ...config,\n };\n }, [config]);\n\n const [coords, setCoords] = useState<{ top: string; left: string }>({ top: \"15%\", left: \"15%\" });\n\n useEffect(() => {\n if (!parsedConfig || parsedConfig.position !== \"dynamic\") return;\n\n const intervalMs = Math.max(2, parsedConfig.intervalSeconds || 15) * 1000;\n const updatePosition = () => {\n // Keep watermark inside 10% - 80% range so it doesn't clip\n const top = Math.floor(10 + Math.random() * 70);\n const left = Math.floor(10 + Math.random() * 70);\n setCoords({ top: `${top}%`, left: `${left}%` });\n };\n\n updatePosition();\n const timer = setInterval(updatePosition, intervalMs);\n return () => clearInterval(timer);\n }, [parsedConfig?.position, parsedConfig?.intervalSeconds]);\n\n const getPositionStyles = (): React.CSSProperties => {\n switch (parsedConfig?.position) {\n case \"top-left\":\n return { top: \"16px\", left: \"16px\" };\n case \"top-right\":\n return { top: \"16px\", right: \"16px\" };\n case \"bottom-left\":\n return { bottom: \"48px\", left: \"16px\" };\n case \"bottom-right\":\n return { bottom: \"48px\", right: \"16px\" };\n case \"center\":\n return { top: \"50%\", left: \"50%\", transform: \"translate(-50%, -50%)\" };\n case \"dynamic\":\n default:\n return { top: coords.top, left: coords.left };\n }\n };\n\n if (!parsedConfig) return null;\n\n return (\n <div\n className=\"vexor-watermark\"\n style={{\n ...getPositionStyles(),\n opacity: Math.max(0, Math.min(1, parsedConfig.opacity ?? 0.35)),\n fontSize: parsedConfig.fontSize ?? \"12px\",\n color: parsedConfig.color ?? \"#ffffff\",\n }}\n aria-hidden=\"true\"\n >\n {parsedConfig.text}\n </div>\n );\n};\n","import Hls from \"hls.js\";\nimport type { VexorVanillaPlayerOptions } from \"./types\";\nimport { startNativeTokenRefresh } from \"../native-token-refresh\";\n\nexport interface VanillaPlayerInstance {\n play: () => Promise<void>;\n pause: () => void;\n seek: (seconds: number) => void;\n destroy: () => void;\n getElement: () => HTMLVideoElement;\n}\n\n/** Mount the Vexor player into an element without requiring React. */\nexport function createVexorPlayer(\n target: HTMLElement | string,\n options: VexorVanillaPlayerOptions\n): VanillaPlayerInstance {\n const container = typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!container) throw new Error(`Target container not found: ${String(target)}`);\n const initialUrl = options.src ?? (options.assetId\n ? `${(options.baseUrl || \"https://api.vexor.et\").replace(/\\/+$/, \"\")}/v1/playback/${encodeURIComponent(options.assetId)}/master.m3u8${options.token ? `?token=${encodeURIComponent(options.token)}` : \"\"}`\n : \"\");\n if (!initialUrl) throw new Error(\"Provide either src or assetId to create the Vexor player.\");\n\n const hadPlayerClass = container.classList.contains(\"vexor-player\");\n const hadProtectedClass = container.classList.contains(\"is-protected\");\n container.classList.add(\"vexor-player\");\n\n const video = document.createElement(\"video\");\n video.className = \"vexor-video\";\n video.controls = options.controls ?? true;\n video.playsInline = true;\n video.preload = options.preload ?? \"metadata\";\n if (options.poster) video.poster = options.poster;\n if (options.autoPlay) video.autoplay = true;\n if (options.muted) video.muted = true;\n if (options.loop) video.loop = true;\n container.appendChild(video);\n\n let watermarkElement: HTMLDivElement | null = null;\n let watermarkTimer: ReturnType<typeof setInterval> | undefined;\n if (options.watermark) {\n const watermark = typeof options.watermark === \"string\"\n ? { text: options.watermark, position: \"dynamic\" as const, intervalSeconds: 15, opacity: 0.35 }\n : { position: \"dynamic\" as const, intervalSeconds: 15, opacity: 0.35, ...options.watermark };\n watermarkElement = document.createElement(\"div\");\n watermarkElement.className = \"vexor-watermark\";\n watermarkElement.textContent = watermark.text;\n watermarkElement.style.opacity = String(Math.max(0, Math.min(1, watermark.opacity ?? 0.35)));\n watermarkElement.style.fontSize = typeof watermark.fontSize === \"number\" ? `${watermark.fontSize}px` : watermark.fontSize ?? \"12px\";\n watermarkElement.style.color = watermark.color ?? \"#ffffff\";\n\n const placeWatermark = () => {\n watermarkElement!.style.removeProperty(\"top\");\n watermarkElement!.style.removeProperty(\"right\");\n watermarkElement!.style.removeProperty(\"bottom\");\n watermarkElement!.style.removeProperty(\"left\");\n watermarkElement!.style.removeProperty(\"transform\");\n switch (watermark.position) {\n case \"top-left\": watermarkElement!.style.cssText += \";top:16px;left:16px\"; break;\n case \"top-right\": watermarkElement!.style.cssText += \";top:16px;right:16px\"; break;\n case \"bottom-left\": watermarkElement!.style.cssText += \";bottom:48px;left:16px\"; break;\n case \"bottom-right\": watermarkElement!.style.cssText += \";bottom:48px;right:16px\"; break;\n case \"center\": watermarkElement!.style.cssText += \";top:50%;left:50%;transform:translate(-50%,-50%)\"; break;\n default:\n watermarkElement!.style.top = `${10 + Math.floor(Math.random() * 70)}%`;\n watermarkElement!.style.left = `${10 + Math.floor(Math.random() * 70)}%`;\n }\n };\n placeWatermark();\n if (watermark.position === \"dynamic\") {\n watermarkTimer = setInterval(placeWatermark, Math.max(2, watermark.intervalSeconds || 15) * 1000);\n }\n container.appendChild(watermarkElement);\n }\n\n const onContextMenu = (event: Event) => event.preventDefault();\n const onDragStart = (event: Event) => event.preventDefault();\n if (options.protect) {\n container.classList.add(\"is-protected\");\n container.addEventListener(\"contextmenu\", onContextMenu);\n video.addEventListener(\"contextmenu\", onContextMenu);\n video.addEventListener(\"dragstart\", onDragStart);\n }\n\n let activeUrl = initialUrl;\n\n let hls: Hls | null = null;\n let nativeTokenRefresh: ReturnType<typeof startNativeTokenRefresh> | null = null;\n let nativeErrorListener: (() => void) | undefined;\n let destroyed = false;\n let refreshPromise: Promise<string> | null = null;\n let resumeAfterRefresh: { time: number; shouldPlay: boolean } | null = null;\n let hasSignaledReady = false;\n let activeParams = new URL(activeUrl, document.baseURI).search;\n const useFallback = (error?: { code: string; message: string; fatal: boolean }) => {\n if (options.fallbackSrc) {\n if (hls) hls.destroy();\n hls = null;\n video.src = options.fallbackSrc;\n video.load();\n } else if (error) options.onError?.(error);\n };\n const signalReady = () => {\n if (hasSignaledReady) return;\n hasSignaledReady = true;\n options.onReady?.();\n };\n const onLoaded = () => {\n signalReady();\n const resume = resumeAfterRefresh;\n resumeAfterRefresh = null;\n if (resume && Number.isFinite(resume.time)) video.currentTime = resume.time;\n if ((resume?.shouldPlay || options.autoPlay) && !destroyed) video.play().catch(() => {});\n };\n\n video.addEventListener(\"loadedmetadata\", onLoaded);\n video.addEventListener(\"loadeddata\", onLoaded);\n const onPlay = () => options.onPlay?.();\n const onPause = () => options.onPause?.();\n const onEnded = () => options.onEnded?.();\n video.addEventListener(\"play\", onPlay);\n video.addEventListener(\"pause\", onPause);\n video.addEventListener(\"ended\", onEnded);\n const onTimeUpdate = () => options.onTimeUpdate?.(video.currentTime, video.duration);\n video.addEventListener(\"timeupdate\", onTimeUpdate);\n\n const isHlsUrl = activeUrl.includes(\".m3u8\") || activeUrl.includes(\"/playback/\");\n if (isHlsUrl && Hls.isSupported()) {\n class TokenAwareLoader extends Hls.DefaultConfig.loader {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n load(context: any, config: any, callbacks: any) {\n if (activeParams && context?.url) {\n try {\n const sourceUrl = new URL(activeUrl, document.baseURI);\n const childUrl = new URL(context.url, sourceUrl);\n if (childUrl.origin === sourceUrl.origin && !childUrl.searchParams.has(\"token\")) {\n new URLSearchParams(activeParams).forEach((value, key) => {\n if (!childUrl.searchParams.has(key)) childUrl.searchParams.set(key, value);\n });\n context.url = childUrl.toString();\n }\n } catch {\n // Leave an unparseable child URL unchanged.\n }\n }\n super.load(context, config, callbacks);\n }\n }\n hls = new Hls({ enableWorker: true, loader: TokenAwareLoader as any, fLoader: TokenAwareLoader as any, pLoader: TokenAwareLoader as any });\n const activeHls = hls;\n activeHls.on(Hls.Events.MANIFEST_PARSED, () => {\n if (hls !== activeHls || destroyed) return;\n const resume = resumeAfterRefresh;\n resumeAfterRefresh = null;\n signalReady();\n if (resume && Number.isFinite(resume.time)) video.currentTime = resume.time;\n if ((resume?.shouldPlay || options.autoPlay) && !destroyed) video.play().catch(() => {});\n });\n activeHls.on(Hls.Events.ERROR, async (_event, data) => {\n if (hls !== activeHls || destroyed) return;\n if ((data.response?.code === 401 || data.response?.code === 403) && options.refreshToken) {\n try {\n refreshPromise ??= options.refreshToken();\n const newToken = await refreshPromise;\n refreshPromise = null;\n if (newToken && hls === activeHls && !destroyed) {\n resumeAfterRefresh = { time: video.currentTime, shouldPlay: !video.paused };\n const url = new URL(activeUrl, document.baseURI);\n url.searchParams.set(\"token\", newToken);\n activeUrl = url.toString();\n activeParams = url.search;\n activeHls.loadSource(activeUrl);\n activeHls.startLoad();\n return;\n }\n } catch {\n refreshPromise = null;\n }\n }\n if (hls !== activeHls || destroyed) return;\n if (data.fatal) useFallback({ code: data.details || \"MEDIA_PLAYBACK_ERROR\", message: `Failed to stream video: ${data.details || \"network error\"}`, fatal: true });\n });\n activeHls.loadSource(activeUrl);\n activeHls.attachMedia(video);\n } else if (isHlsUrl && video.canPlayType(\"application/vnd.apple.mpegurl\")) {\n video.src = activeUrl;\n nativeTokenRefresh = startNativeTokenRefresh(video, activeUrl, options.refreshToken);\n nativeErrorListener = () => {\n void nativeTokenRefresh?.refreshNow().then((refreshed) => {\n if (refreshed || destroyed) return;\n video.removeEventListener(\"error\", nativeErrorListener!);\n useFallback({ code: \"NATIVE_HLS_ERROR\", message: \"Failed to play native HLS stream\", fatal: true });\n });\n };\n video.addEventListener(\"error\", nativeErrorListener);\n } else if (!isHlsUrl || options.fallbackSrc) {\n video.src = isHlsUrl ? options.fallbackSrc! : activeUrl;\n } else {\n useFallback({ code: \"HLS_UNSUPPORTED\", message: \"This browser does not support HLS playback.\", fatal: true });\n }\n\n return {\n play: () => video.play(),\n pause: () => video.pause(),\n seek: (seconds) => { video.currentTime = Math.max(0, Math.min(seconds, video.duration || seconds)); },\n destroy: () => {\n if (destroyed) return;\n destroyed = true;\n nativeTokenRefresh?.stop();\n if (hls) hls.destroy();\n hls = null;\n if (watermarkTimer) clearInterval(watermarkTimer);\n container.removeEventListener(\"contextmenu\", onContextMenu);\n video.removeEventListener(\"contextmenu\", onContextMenu);\n video.removeEventListener(\"dragstart\", onDragStart);\n video.removeEventListener(\"loadedmetadata\", onLoaded);\n video.removeEventListener(\"loadeddata\", onLoaded);\n video.removeEventListener(\"play\", onPlay);\n video.removeEventListener(\"pause\", onPause);\n video.removeEventListener(\"ended\", onEnded);\n video.removeEventListener(\"timeupdate\", onTimeUpdate);\n if (nativeErrorListener) video.removeEventListener(\"error\", nativeErrorListener);\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n video.remove();\n watermarkElement?.remove();\n if (!hadPlayerClass) container.classList.remove(\"vexor-player\");\n if (options.protect && !hadProtectedClass) container.classList.remove(\"is-protected\");\n },\n getElement: () => video,\n };\n}\n"],"mappings":"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","names":["import_react","onError","Hls","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_hls","Hls"]}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/VexorPlayer.tsx","../src/hooks/useVexorPlayer.ts","../src/components/Controls.tsx","../src/components/Watermark.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from \"react\";\nimport { useVexorPlayer } from \"../hooks/useVexorPlayer\";\nimport { Controls } from \"./Controls\";\nimport { Watermark } from \"./Watermark\";\nimport type { VexorPlayerProps } from \"../types\";\n\nexport const VexorPlayer: React.FC<VexorPlayerProps> = (props) => {\n const {\n poster,\n preload = \"metadata\",\n muted = false,\n loop = false,\n controls = true,\n nativeControls = false,\n watermark,\n protect = false,\n className = \"\",\n style,\n children,\n } = props;\n\n const player = useVexorPlayer(props);\n const [controlsVisible, setControlsVisible] = useState(true);\n const hideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const resetHideTimer = useCallback(() => {\n setControlsVisible(true);\n if (hideTimerRef.current) {\n clearTimeout(hideTimerRef.current);\n }\n if (player.isPlaying && !player.containerRef.current?.contains(document.activeElement)) {\n hideTimerRef.current = setTimeout(() => {\n setControlsVisible(false);\n }, 2500);\n }\n }, [player.isPlaying]);\n\n useEffect(() => {\n resetHideTimer();\n return () => {\n if (hideTimerRef.current) clearTimeout(hideTimerRef.current);\n };\n }, [player.isPlaying, resetHideTimer]);\n\n // Anti-tamper protection handlers\n const handleContextMenu = (e: React.MouseEvent) => {\n if (protect) {\n e.preventDefault();\n }\n };\n\n // Keyboard navigation & shortcuts\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Leave keystrokes to focused form controls, buttons, and custom controls.\n const target = e.target as HTMLElement;\n if (target?.closest(\"input, textarea, select, button, [contenteditable='true'], [role='slider']\")) return;\n\n const container = player.containerRef.current;\n if (!container || (!document.fullscreenElement && !container.contains(document.activeElement) && !container.matches(\":hover\"))) {\n return;\n }\n\n switch (e.key.toLowerCase()) {\n case \" \":\n case \"k\":\n e.preventDefault();\n player.togglePlay();\n resetHideTimer();\n break;\n case \"arrowleft\":\n case \"j\":\n e.preventDefault();\n player.seek(player.currentTime - 5);\n resetHideTimer();\n break;\n case \"arrowright\":\n case \"l\":\n e.preventDefault();\n player.seek(player.currentTime + 5);\n resetHideTimer();\n break;\n case \"arrowup\":\n e.preventDefault();\n player.setVolume(player.volume + 0.1);\n resetHideTimer();\n break;\n case \"arrowdown\":\n e.preventDefault();\n player.setVolume(player.volume - 0.1);\n resetHideTimer();\n break;\n case \"m\":\n e.preventDefault();\n player.toggleMute();\n resetHideTimer();\n break;\n case \"f\":\n e.preventDefault();\n player.toggleFullscreen();\n resetHideTimer();\n break;\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [player, resetHideTimer]);\n\n return (\n <div\n ref={player.containerRef}\n className={`vexor-player ${player.isFullscreen ? \"is-fullscreen\" : \"\"} ${protect ? \"is-protected\" : \"\"} ${className}`}\n style={style}\n onMouseMove={resetHideTimer}\n onMouseLeave={(event) => {\n if (player.isPlaying && !event.currentTarget.contains(document.activeElement)) {\n setControlsVisible(false);\n }\n }}\n onFocusCapture={() => {\n if (hideTimerRef.current) clearTimeout(hideTimerRef.current);\n setControlsVisible(true);\n }}\n onBlurCapture={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) resetHideTimer();\n }}\n onContextMenu={handleContextMenu}\n tabIndex={0}\n role=\"region\"\n aria-label=\"Video Player\"\n >\n <video\n ref={player.videoRef}\n className=\"vexor-video\"\n poster={poster}\n preload={preload}\n muted={muted}\n loop={loop}\n playsInline\n controls={nativeControls}\n onClick={nativeControls ? undefined : player.togglePlay}\n />\n\n {/* Watermark Overlay */}\n {watermark && <Watermark config={watermark} />}\n\n {/* Buffering Spinner */}\n {player.isBuffering && !player.error && (\n <div className=\"vexor-spinner-overlay\" aria-label=\"Buffering video\">\n <div className=\"vexor-spinner\" />\n </div>\n )}\n\n {/* Center Big Play Button (when paused, not buffering, and custom controls active) */}\n {!nativeControls && controls && !player.isPlaying && !player.isBuffering && !player.error && (\n <button type=\"button\" className=\"vexor-center-play-overlay\" onClick={player.togglePlay} aria-label=\"Play video\">\n <span className=\"vexor-center-play-button\" aria-hidden=\"true\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <polygon points=\"6,4 20,12 6,20\" />\n </svg>\n </span>\n </button>\n )}\n\n {/* Custom Controls Bar */}\n {!nativeControls && controls && !player.error && (\n <Controls\n isPlaying={player.isPlaying}\n isBuffering={player.isBuffering}\n currentTime={player.currentTime}\n duration={player.duration}\n buffered={player.buffered}\n volume={player.volume}\n isMuted={player.isMuted}\n isFullscreen={player.isFullscreen}\n qualityLevels={player.qualityLevels}\n currentQuality={player.currentQuality}\n playbackRate={player.playbackRate}\n visible={controlsVisible}\n onPlayPause={player.togglePlay}\n onSeek={player.seek}\n onVolumeChange={player.setVolume}\n onToggleMute={player.toggleMute}\n onQualityChange={player.setQuality}\n onPlaybackRateChange={player.setPlaybackRate}\n onToggleFullscreen={player.toggleFullscreen}\n onTogglePiP={player.togglePiP}\n />\n )}\n\n {/* Error Overlay */}\n {player.error && (\n <div className=\"vexor-error-overlay\">\n <div className=\"vexor-error-title\">Playback Error</div>\n <div className=\"vexor-error-message\">{player.error.message}</div>\n <button type=\"button\" className=\"vexor-retry-button\" onClick={player.retry}>\n Retry Playback\n </button>\n </div>\n )}\n\n {/* Custom Child Overlays */}\n {children}\n </div>\n );\n};\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport Hls from \"hls.js\";\nimport type { QualityLevel, VexorPlayerProps } from \"../types\";\nimport { startNativeTokenRefresh } from \"../native-token-refresh\";\n\nexport interface UseVexorPlayerReturn {\n videoRef: React.RefObject<HTMLVideoElement | null>;\n containerRef: React.RefObject<HTMLDivElement | null>;\n isPlaying: boolean;\n isBuffering: boolean;\n currentTime: number;\n duration: number;\n buffered: number;\n volume: number;\n isMuted: boolean;\n isFullscreen: boolean;\n qualityLevels: QualityLevel[];\n currentQuality: number;\n playbackRate: number;\n error: { code: string; message: string; fatal: boolean } | null;\n play: () => Promise<void>;\n pause: () => void;\n togglePlay: () => void;\n seek: (time: number) => void;\n setVolume: (vol: number) => void;\n toggleMute: () => void;\n setQuality: (levelIndex: number) => void;\n setPlaybackRate: (rate: number) => void;\n toggleFullscreen: () => void;\n togglePiP: () => void;\n retry: () => void;\n}\n\nexport function useVexorPlayer({\n src,\n assetId,\n token,\n baseUrl = \"https://api.vexor.et\",\n fallbackSrc,\n autoPlay = false,\n muted = false,\n refreshToken,\n onReady,\n onPlay,\n onPause,\n onEnded,\n onTimeUpdate,\n onError,\n onQualityChange,\n}: VexorPlayerProps): UseVexorPlayerReturn {\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const hlsRef = useRef<Hls | null>(null);\n const callbacksRef = useRef({ onReady, onPlay, onPause, onEnded, onTimeUpdate, onError, onQualityChange, refreshToken });\n callbacksRef.current = { onReady, onPlay, onPause, onEnded, onTimeUpdate, onError, onQualityChange, refreshToken };\n const activeParamsRef = useRef(\"\");\n const refreshPromiseRef = useRef<Promise<string> | null>(null);\n const resumeAfterRefreshRef = useRef<{ time: number; shouldPlay: boolean } | null>(null);\n\n const [isPlaying, setIsPlaying] = useState(false);\n const [isBuffering, setIsBuffering] = useState(true);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [buffered, setBuffered] = useState(0);\n const [volume, setVolumeState] = useState(1);\n const [isMuted, setIsMuted] = useState(muted);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [qualityLevels, setQualityLevels] = useState<QualityLevel[]>([]);\n const [currentQuality, setCurrentQuality] = useState(-1);\n const [playbackRate, setPlaybackRateState] = useState(1);\n const [error, setError] = useState<{ code: string; message: string; fatal: boolean } | null>(null);\n const [reloadTrigger, setReloadTrigger] = useState(0);\n\n // Determine effective playback manifest URL\n const activeUrl = src\n ? src\n : assetId\n ? `${baseUrl.replace(/\\/+$/, \"\")}/v1/playback/${encodeURIComponent(assetId)}/master.m3u8${token ? `?token=${encodeURIComponent(token)}` : \"\"}`\n : \"\";\n\n const destroyHls = useCallback(() => {\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n }, []);\n\n const retry = useCallback(() => {\n setError(null);\n setIsBuffering(true);\n setReloadTrigger((v) => v + 1);\n }, []);\n\n // Initialize HLS & Media Source\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n let cleanupFallback = () => {};\n const loadFallback = () => {\n if (!fallbackSrc) return false;\n destroyHls();\n setIsBuffering(true);\n video.src = fallbackSrc;\n const onLoaded = () => {\n setIsBuffering(false);\n callbacksRef.current.onReady?.();\n };\n const onError = () => {\n const errObj = {\n code: \"FALLBACK_PLAYBACK_ERROR\",\n message: \"Unable to load fallback media source\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n video.addEventListener(\"loadeddata\", onLoaded);\n video.addEventListener(\"error\", onError);\n cleanupFallback = () => {\n video.removeEventListener(\"loadeddata\", onLoaded);\n video.removeEventListener(\"error\", onError);\n };\n video.load();\n return true;\n };\n const setFatalError = (code: string, message: string) => {\n destroyHls();\n const errObj = { code, message, fatal: true };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n\n destroyHls();\n setError(null);\n setCurrentTime(0);\n setDuration(0);\n setBuffered(0);\n setQualityLevels([]);\n setCurrentQuality(-1);\n setIsBuffering(Boolean(activeUrl));\n if (!activeUrl) {\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n return;\n }\n\n const isHlsUrl = activeUrl.includes(\".m3u8\") || activeUrl.includes(\"/playback/\");\n let fatalRecoveryAttempts = 0;\n\n if (isHlsUrl && Hls.isSupported()) {\n activeParamsRef.current = activeUrl.includes(\"?\") ? activeUrl.substring(activeUrl.indexOf(\"?\")) : \"\";\n\n class VexorLoader extends Hls.DefaultConfig.loader {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n load(context: any, config: any, callbacks: any) {\n // Propagate token query params to child playlists and segments if not present\n const activeParams = activeParamsRef.current;\n if (activeParams && context?.url) {\n try {\n const sourceUrl = new URL(activeUrl, window.location.href);\n const childUrl = new URL(context.url, sourceUrl);\n if (childUrl.origin === sourceUrl.origin && !childUrl.searchParams.has(\"token\")) {\n new URLSearchParams(activeParams).forEach((value, key) => {\n if (!childUrl.searchParams.has(key)) childUrl.searchParams.set(key, value);\n });\n context.url = childUrl.toString();\n }\n } catch {\n // Leave an unparseable child URL untouched; the loader will report failures normally.\n }\n }\n super.load(context, config, callbacks);\n }\n }\n\n const hls = new Hls({\n startFragPrefetch: true,\n maxBufferLength: 30,\n maxMaxBufferLength: 60,\n enableWorker: true,\n lowLatencyMode: true,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n loader: VexorLoader as any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fLoader: VexorLoader as any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n pLoader: VexorLoader as any,\n });\n hlsRef.current = hls;\n\n hls.loadSource(activeUrl);\n hls.attachMedia(video);\n\n hls.on(Hls.Events.MANIFEST_PARSED, (_event, data) => {\n if (hlsRef.current !== hls) return;\n setIsBuffering(false);\n const levels: QualityLevel[] = data.levels.map((lvl, index) => {\n let label = `${lvl.height}p`;\n if (lvl.height === 0 || lvl.videoCodec === undefined) {\n label = \"Audio only\";\n }\n return {\n id: index,\n height: lvl.height,\n width: lvl.width,\n bitrate: lvl.bitrate,\n label,\n };\n });\n setQualityLevels(levels);\n callbacksRef.current.onReady?.();\n const resume = resumeAfterRefreshRef.current;\n if (resume) {\n resumeAfterRefreshRef.current = null;\n if (Number.isFinite(resume.time) && resume.time > 0) video.currentTime = resume.time;\n if (resume.shouldPlay) video.play().catch(() => {});\n }\n if (autoPlay) {\n video.play().catch(() => {\n // Autoplay might be blocked by browser policy; user can interact to start\n });\n }\n });\n\n hls.on(Hls.Events.LEVEL_SWITCHED, (_event, data) => {\n if (hlsRef.current !== hls) return;\n setCurrentQuality(hls.autoLevelEnabled ? -1 : data.level);\n callbacksRef.current.onQualityChange?.(hls.autoLevelEnabled ? -1 : data.level);\n });\n\n hls.on(Hls.Events.ERROR, async (_event, data) => {\n if (hlsRef.current !== hls) return;\n // Handle token expiry (HTTP 401 or 403 on key/segment)\n if (\n (data.response?.code === 401 || data.response?.code === 403) &&\n callbacksRef.current.refreshToken\n ) {\n try {\n if (!refreshPromiseRef.current) {\n refreshPromiseRef.current = callbacksRef.current.refreshToken();\n }\n const newToken = await refreshPromiseRef.current;\n refreshPromiseRef.current = null;\n if (newToken && hlsRef.current === hls) {\n resumeAfterRefreshRef.current = {\n time: video.currentTime,\n shouldPlay: !video.paused,\n };\n const url = new URL(activeUrl, window.location.href);\n url.searchParams.set(\"token\", newToken);\n activeParamsRef.current = url.search;\n hls.loadSource(url.toString());\n hls.startLoad();\n return;\n }\n } catch {\n refreshPromiseRef.current = null;\n // Fall through to standard error handling if token refresh fails\n }\n }\n\n if (hlsRef.current !== hls) return;\n\n if (data.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n if (fatalRecoveryAttempts++ < 1) {\n hls.startLoad();\n } else if (!loadFallback()) {\n setFatalError(data.details || \"NETWORK_ERROR\", `Failed to stream video: ${data.details || \"network error\"}`);\n }\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n if (fatalRecoveryAttempts++ < 1) {\n hls.recoverMediaError();\n } else if (!loadFallback()) {\n setFatalError(data.details || \"MEDIA_ERROR\", `Failed to stream video: ${data.details || \"media error\"}`);\n }\n break;\n default:\n if (!loadFallback()) {\n setFatalError(data.details || \"MEDIA_PLAYBACK_ERROR\", `Failed to stream video: ${data.details || \"network error\"}`);\n }\n break;\n }\n }\n });\n } else if (isHlsUrl && video.canPlayType(\"application/vnd.apple.mpegurl\")) {\n // Safari / iOS Native HLS\n video.src = activeUrl;\n const nativeTokenRefresh = startNativeTokenRefresh(\n video,\n activeUrl,\n callbacksRef.current.refreshToken,\n );\n const onLoaded = () => {\n setIsBuffering(false);\n callbacksRef.current.onReady?.();\n if (autoPlay) {\n video.play().catch(() => {});\n }\n };\n const onNativeError = () => {\n void nativeTokenRefresh.refreshNow().then((refreshed) => {\n if (refreshed || hlsRef.current) return;\n if (loadFallback()) {\n video.removeEventListener(\"error\", onNativeError);\n return;\n }\n setFatalError(\"NATIVE_HLS_ERROR\", \"Failed to play native HLS stream\");\n });\n };\n video.addEventListener(\"loadedmetadata\", onLoaded);\n video.addEventListener(\"error\", onNativeError);\n return () => {\n nativeTokenRefresh.stop();\n video.removeEventListener(\"loadedmetadata\", onLoaded);\n video.removeEventListener(\"error\", onNativeError);\n };\n } else if (!isHlsUrl) {\n // Standard MP4 progressive playback\n video.src = activeUrl;\n const onLoaded = () => {\n setIsBuffering(false);\n onReady?.();\n };\n const onErr = () => {\n const errObj = {\n code: \"DIRECT_PLAYBACK_ERROR\",\n message: \"Unable to load media source\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n video.addEventListener(\"loadeddata\", onLoaded);\n video.addEventListener(\"error\", onErr);\n return () => {\n video.removeEventListener(\"loadeddata\", onLoaded);\n video.removeEventListener(\"error\", onErr);\n };\n } else if (fallbackSrc) {\n // HLS unsupported: use the configured progressive fallback.\n loadFallback();\n } else {\n const errObj = {\n code: \"HLS_UNSUPPORTED\",\n message: \"This browser does not support HLS playback and no fallback source was provided\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n }\n\n return () => {\n cleanupFallback();\n destroyHls();\n };\n }, [activeUrl, fallbackSrc, autoPlay, reloadTrigger, destroyHls]);\n\n // Video Element Event Listeners\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n const onPlayEvent = () => {\n setIsPlaying(true);\n callbacksRef.current.onPlay?.();\n };\n\n const onPauseEvent = () => {\n setIsPlaying(false);\n callbacksRef.current.onPause?.();\n };\n\n const onEndedEvent = () => {\n setIsPlaying(false);\n callbacksRef.current.onEnded?.();\n };\n\n const onWaiting = () => setIsBuffering(true);\n const onPlaying = () => setIsBuffering(false);\n\n const onTimeUpdateEvent = () => {\n setCurrentTime(video.currentTime);\n callbacksRef.current.onTimeUpdate?.(video.currentTime, video.duration);\n\n // Calculate buffer progress\n if (video.buffered.length > 0 && video.duration > 0) {\n for (let i = video.buffered.length - 1; i >= 0; i--) {\n if (video.buffered.start(i) <= video.currentTime) {\n setBuffered((video.buffered.end(i) / video.duration) * 100);\n break;\n }\n }\n }\n };\n\n const onDurationChange = () => setDuration(video.duration || 0);\n const onVolumeChangeEvent = () => {\n setVolumeState(video.volume);\n setIsMuted(video.muted);\n };\n\n video.addEventListener(\"play\", onPlayEvent);\n video.addEventListener(\"pause\", onPauseEvent);\n video.addEventListener(\"ended\", onEndedEvent);\n video.addEventListener(\"waiting\", onWaiting);\n video.addEventListener(\"playing\", onPlaying);\n video.addEventListener(\"timeupdate\", onTimeUpdateEvent);\n video.addEventListener(\"durationchange\", onDurationChange);\n video.addEventListener(\"volumechange\", onVolumeChangeEvent);\n\n return () => {\n video.removeEventListener(\"play\", onPlayEvent);\n video.removeEventListener(\"pause\", onPauseEvent);\n video.removeEventListener(\"ended\", onEndedEvent);\n video.removeEventListener(\"waiting\", onWaiting);\n video.removeEventListener(\"playing\", onPlaying);\n video.removeEventListener(\"timeupdate\", onTimeUpdateEvent);\n video.removeEventListener(\"durationchange\", onDurationChange);\n video.removeEventListener(\"volumechange\", onVolumeChangeEvent);\n };\n }, []);\n\n // Fullscreen change listener\n useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen(Boolean(document.fullscreenElement));\n };\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, []);\n\n // Player Actions\n const play = useCallback(async () => {\n if (videoRef.current) {\n await videoRef.current.play();\n }\n }, []);\n\n const pause = useCallback(() => {\n if (videoRef.current) {\n videoRef.current.pause();\n }\n }, []);\n\n const togglePlay = useCallback(() => {\n if (!videoRef.current) return;\n if (videoRef.current.paused) {\n videoRef.current.play().catch(() => {});\n } else {\n videoRef.current.pause();\n }\n }, []);\n\n const seek = useCallback((time: number) => {\n if (videoRef.current) {\n videoRef.current.currentTime = Math.max(0, Math.min(time, videoRef.current.duration || time));\n }\n }, []);\n\n const setVolume = useCallback((vol: number) => {\n if (videoRef.current) {\n const clamped = Math.max(0, Math.min(1, vol));\n videoRef.current.volume = clamped;\n videoRef.current.muted = clamped === 0;\n }\n }, []);\n\n const toggleMute = useCallback(() => {\n if (videoRef.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n }, []);\n\n const setQuality = useCallback((levelIndex: number) => {\n if (hlsRef.current) {\n if (levelIndex === -1) {\n hlsRef.current.currentLevel = -1; // Auto\n } else {\n hlsRef.current.currentLevel = levelIndex;\n }\n setCurrentQuality(levelIndex);\n }\n }, []);\n\n const setPlaybackRate = useCallback((rate: number) => {\n if (videoRef.current) {\n videoRef.current.playbackRate = rate;\n setPlaybackRateState(rate);\n }\n }, []);\n\n const toggleFullscreen = useCallback(() => {\n const container = containerRef.current || videoRef.current;\n if (!container) return;\n\n if (!document.fullscreenElement) {\n container.requestFullscreen().catch(() => {});\n } else {\n document.exitFullscreen().catch(() => {});\n }\n }, []);\n\n const togglePiP = useCallback(async () => {\n const video = videoRef.current;\n if (!video) return;\n\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else if (document.pictureInPictureEnabled) {\n await video.requestPictureInPicture();\n }\n } catch {\n // Ignored\n }\n }, []);\n\n return {\n videoRef,\n containerRef,\n isPlaying,\n isBuffering,\n currentTime,\n duration,\n buffered,\n volume,\n isMuted,\n isFullscreen,\n qualityLevels,\n currentQuality,\n playbackRate,\n error,\n play,\n pause,\n togglePlay,\n seek,\n setVolume,\n toggleMute,\n setQuality,\n setPlaybackRate,\n toggleFullscreen,\n togglePiP,\n retry,\n };\n}\n","import React, { useState, useRef, useEffect, useCallback } from \"react\";\nimport type { QualityLevel } from \"../types\";\n\ninterface ControlsProps {\n isPlaying: boolean;\n isBuffering: boolean;\n currentTime: number;\n duration: number;\n buffered: number;\n volume: number;\n isMuted: boolean;\n isFullscreen: boolean;\n qualityLevels: QualityLevel[];\n currentQuality: number;\n playbackRate: number;\n visible: boolean;\n onPlayPause: () => void;\n onSeek: (time: number) => void;\n onVolumeChange: (volume: number) => void;\n onToggleMute: () => void;\n onQualityChange: (levelIndex: number) => void;\n onPlaybackRateChange: (rate: number) => void;\n onToggleFullscreen: () => void;\n onTogglePiP: () => void;\n}\n\nfunction formatTime(seconds: number): string {\n if (isNaN(seconds) || seconds < 0) return \"0:00\";\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = Math.floor(seconds % 60);\n if (h > 0) {\n return `${h}:${m.toString().padStart(2, \"0\")}:${s.toString().padStart(2, \"0\")}`;\n }\n return `${m}:${s.toString().padStart(2, \"0\")}`;\n}\n\nexport const Controls: React.FC<ControlsProps> = ({\n isPlaying,\n currentTime,\n duration,\n buffered,\n volume,\n isMuted,\n isFullscreen,\n qualityLevels,\n currentQuality,\n playbackRate,\n visible,\n onPlayPause,\n onSeek,\n onVolumeChange,\n onToggleMute,\n onQualityChange,\n onPlaybackRateChange,\n onToggleFullscreen,\n onTogglePiP,\n}) => {\n const [showQualityMenu, setShowQualityMenu] = useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = useState(false);\n const progressRef = useRef<HTMLDivElement>(null);\n const [isScrubbing, setIsScrubbing] = useState(false);\n const [pictureInPictureSupported, setPictureInPictureSupported] = useState(false);\n\n useEffect(() => {\n setPictureInPictureSupported(\n typeof document !== \"undefined\" && document.pictureInPictureEnabled\n );\n }, []);\n\n const playedPercent = duration > 0 ? (currentTime / duration) * 100 : 0;\n const speedOptions = [0.5, 0.75, 1, 1.25, 1.5, 2];\n\n const handleScrub = useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n if (!progressRef.current || duration <= 0) return;\n const rect = progressRef.current.getBoundingClientRect();\n const pos = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n onSeek(pos * duration);\n },\n [duration, onSeek]\n );\n\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n if (e.button !== 0) return;\n e.currentTarget.setPointerCapture(e.pointerId);\n setIsScrubbing(true);\n handleScrub(e);\n };\n\n const handleTimelineKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (duration <= 0) return;\n const step = e.shiftKey ? 30 : 5;\n let nextTime: number | undefined;\n if (e.key === \"ArrowLeft\") nextTime = currentTime - step;\n if (e.key === \"ArrowRight\") nextTime = currentTime + step;\n if (e.key === \"Home\") nextTime = 0;\n if (e.key === \"End\") nextTime = duration;\n if (nextTime !== undefined) {\n e.preventDefault();\n onSeek(Math.max(0, Math.min(duration, nextTime)));\n }\n };\n\n return (\n <div className={`vexor-controls ${visible ? \"\" : \"is-hidden\"}`}>\n {/* Timeline Scrubber */}\n <div\n className=\"vexor-progress-container\"\n ref={progressRef}\n onPointerDown={handlePointerDown}\n onPointerMove={(event) => { if (isScrubbing) handleScrub(event); }}\n onPointerUp={(event) => {\n if (progressRef.current?.hasPointerCapture(event.pointerId)) {\n progressRef.current.releasePointerCapture(event.pointerId);\n }\n setIsScrubbing(false);\n }}\n onPointerCancel={() => setIsScrubbing(false)}\n onKeyDown={handleTimelineKeyDown}\n tabIndex={0}\n role=\"slider\"\n aria-label=\"Video timeline\"\n aria-valuemin={0}\n aria-valuemax={duration}\n aria-valuenow={Math.min(currentTime, duration || 0)}\n aria-valuetext={`${formatTime(currentTime)} of ${formatTime(duration)}`}\n >\n <div className=\"vexor-progress-track\">\n <div className=\"vexor-progress-buffer\" style={{ width: `${buffered}%` }} />\n <div className=\"vexor-progress-played\" style={{ width: `${playedPercent}%` }} />\n <div className=\"vexor-progress-thumb\" style={{ left: `${playedPercent}%` }} />\n </div>\n </div>\n\n {/* Control Buttons Row */}\n <div className=\"vexor-controls-row\">\n {/* Left Side: Play/Pause, Volume, Time */}\n <div className=\"vexor-controls-group\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onPlayPause}\n aria-label={isPlaying ? \"Pause\" : \"Play\"}\n >\n {isPlaying ? (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <polygon points=\"5,3 19,12 5,21\" />\n </svg>\n )}\n </button>\n\n <div className=\"vexor-volume-wrapper\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onToggleMute}\n aria-label={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\" />\n <line x1=\"17\" y1=\"9\" x2=\"23\" y2=\"15\" />\n </svg>\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\" />\n </svg>\n )}\n </button>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n value={isMuted ? 0 : volume}\n onChange={(e) => onVolumeChange(parseFloat(e.target.value))}\n className=\"vexor-volume-slider\"\n aria-label=\"Volume slider\"\n />\n </div>\n\n <span className=\"vexor-time-display\">\n {formatTime(currentTime)} / {formatTime(duration)}\n </span>\n </div>\n\n {/* Right Side: Speed, Quality, PiP, Fullscreen */}\n <div className=\"vexor-controls-group\">\n {/* Speed Selector */}\n <div className=\"vexor-menu-anchor\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={() => {\n setShowSpeedMenu(!showSpeedMenu);\n setShowQualityMenu(false);\n }}\n aria-label=\"Playback speed\"\n style={{ fontSize: \"11px\", fontWeight: 600, padding: \"4px 8px\" }}\n >\n {playbackRate === 1 ? \"1x\" : `${playbackRate}x`}\n </button>\n\n {showSpeedMenu && (\n <div className=\"vexor-menu-dropdown\">\n {speedOptions.map((rate) => (\n <button\n key={rate}\n type=\"button\"\n className={`vexor-menu-item ${playbackRate === rate ? \"is-active\" : \"\"}`}\n onClick={() => {\n onPlaybackRateChange(rate);\n setShowSpeedMenu(false);\n }}\n >\n <span>{rate}x</span>\n {playbackRate === rate && <span>✓</span>}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Quality Levels Selector */}\n {qualityLevels.length > 0 && (\n <div className=\"vexor-menu-anchor\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={() => {\n setShowQualityMenu(!showQualityMenu);\n setShowSpeedMenu(false);\n }}\n aria-label=\"Video quality\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\" />\n </svg>\n </button>\n\n {showQualityMenu && (\n <div className=\"vexor-menu-dropdown\">\n <button\n type=\"button\"\n className={`vexor-menu-item ${currentQuality === -1 ? \"is-active\" : \"\"}`}\n onClick={() => {\n onQualityChange(-1);\n setShowQualityMenu(false);\n }}\n >\n <span>Auto</span>\n {currentQuality === -1 && <span>✓</span>}\n </button>\n {qualityLevels.map((lvl) => (\n <button\n key={lvl.id}\n type=\"button\"\n className={`vexor-menu-item ${currentQuality === lvl.id ? \"is-active\" : \"\"}`}\n onClick={() => {\n onQualityChange(lvl.id);\n setShowQualityMenu(false);\n }}\n >\n <span>{lvl.label}</span>\n {currentQuality === lvl.id && <span>✓</span>}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Picture in Picture */}\n {pictureInPictureSupported && (\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onTogglePiP}\n aria-label=\"Picture in picture\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" />\n <rect x=\"12\" y=\"9\" width=\"8\" height=\"6\" rx=\"1\" fill=\"currentColor\" fillOpacity=\"0.4\" />\n </svg>\n </button>\n )}\n\n {/* Fullscreen Toggle */}\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onToggleFullscreen}\n aria-label={isFullscreen ? \"Exit fullscreen\" : \"Enter fullscreen\"}\n >\n {isFullscreen ? (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3\" />\n </svg>\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\" />\n </svg>\n )}\n </button>\n </div>\n </div>\n </div>\n );\n};\n","import React, { useEffect, useState, useMemo } from \"react\";\nimport type { WatermarkConfig } from \"../types\";\n\ninterface WatermarkProps {\n config?: string | WatermarkConfig;\n}\n\nexport const Watermark: React.FC<WatermarkProps> = ({ config }) => {\n const parsedConfig: WatermarkConfig | null = useMemo(() => {\n if (!config) return null;\n if (typeof config === \"string\") {\n return { text: config, position: \"dynamic\", intervalSeconds: 15, opacity: 0.35 };\n }\n return {\n position: \"dynamic\",\n intervalSeconds: 15,\n opacity: 0.35,\n ...config,\n };\n }, [config]);\n\n const [coords, setCoords] = useState<{ top: string; left: string }>({ top: \"15%\", left: \"15%\" });\n\n useEffect(() => {\n if (!parsedConfig || parsedConfig.position !== \"dynamic\") return;\n\n const intervalMs = Math.max(2, parsedConfig.intervalSeconds || 15) * 1000;\n const updatePosition = () => {\n // Keep watermark inside 10% - 80% range so it doesn't clip\n const top = Math.floor(10 + Math.random() * 70);\n const left = Math.floor(10 + Math.random() * 70);\n setCoords({ top: `${top}%`, left: `${left}%` });\n };\n\n updatePosition();\n const timer = setInterval(updatePosition, intervalMs);\n return () => clearInterval(timer);\n }, [parsedConfig?.position, parsedConfig?.intervalSeconds]);\n\n const getPositionStyles = (): React.CSSProperties => {\n switch (parsedConfig?.position) {\n case \"top-left\":\n return { top: \"16px\", left: \"16px\" };\n case \"top-right\":\n return { top: \"16px\", right: \"16px\" };\n case \"bottom-left\":\n return { bottom: \"48px\", left: \"16px\" };\n case \"bottom-right\":\n return { bottom: \"48px\", right: \"16px\" };\n case \"center\":\n return { top: \"50%\", left: \"50%\", transform: \"translate(-50%, -50%)\" };\n case \"dynamic\":\n default:\n return { top: coords.top, left: coords.left };\n }\n };\n\n if (!parsedConfig) return null;\n\n return (\n <div\n className=\"vexor-watermark\"\n style={{\n ...getPositionStyles(),\n opacity: Math.max(0, Math.min(1, parsedConfig.opacity ?? 0.35)),\n fontSize: parsedConfig.fontSize ?? \"12px\",\n color: parsedConfig.color ?? \"#ffffff\",\n }}\n aria-hidden=\"true\"\n >\n {parsedConfig.text}\n </div>\n );\n};\n"],"mappings":"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","names":["useState","useEffect","useRef","useCallback","onError","useState","useRef","useEffect","useCallback","useEffect","useState","jsx","jsx","jsxs","useState","useRef","useCallback","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/VexorPlayer.tsx","../src/hooks/useVexorPlayer.ts","../src/components/Controls.tsx","../src/components/Watermark.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from \"react\";\nimport { useVexorPlayer } from \"../hooks/useVexorPlayer\";\nimport { Controls } from \"./Controls\";\nimport { Watermark } from \"./Watermark\";\nimport type { VexorPlayerProps } from \"../types\";\n\nexport const VexorPlayer: React.FC<VexorPlayerProps> = (props) => {\n const {\n poster,\n preload = \"metadata\",\n muted = false,\n loop = false,\n controls = true,\n nativeControls = false,\n watermark,\n protect = false,\n className = \"\",\n style,\n children,\n } = props;\n\n const player = useVexorPlayer(props);\n const [controlsVisible, setControlsVisible] = useState(true);\n const hideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const resetHideTimer = useCallback(() => {\n setControlsVisible(true);\n if (hideTimerRef.current) {\n clearTimeout(hideTimerRef.current);\n }\n if (player.isPlaying && !player.containerRef.current?.contains(document.activeElement)) {\n hideTimerRef.current = setTimeout(() => {\n setControlsVisible(false);\n }, 2500);\n }\n }, [player.isPlaying]);\n\n useEffect(() => {\n resetHideTimer();\n return () => {\n if (hideTimerRef.current) clearTimeout(hideTimerRef.current);\n };\n }, [player.isPlaying, resetHideTimer]);\n\n // Anti-tamper protection handlers\n const handleContextMenu = (e: React.MouseEvent) => {\n if (protect) {\n e.preventDefault();\n }\n };\n\n // Keyboard navigation & shortcuts\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Leave keystrokes to focused form controls, buttons, and custom controls.\n const target = e.target as HTMLElement;\n if (target?.closest(\"input, textarea, select, button, [contenteditable='true'], [role='slider']\")) return;\n\n const container = player.containerRef.current;\n if (!container || (!document.fullscreenElement && !container.contains(document.activeElement) && !container.matches(\":hover\"))) {\n return;\n }\n\n switch (e.key.toLowerCase()) {\n case \" \":\n case \"k\":\n e.preventDefault();\n player.togglePlay();\n resetHideTimer();\n break;\n case \"arrowleft\":\n case \"j\":\n e.preventDefault();\n player.seek(player.currentTime - 5);\n resetHideTimer();\n break;\n case \"arrowright\":\n case \"l\":\n e.preventDefault();\n player.seek(player.currentTime + 5);\n resetHideTimer();\n break;\n case \"arrowup\":\n e.preventDefault();\n player.setVolume(player.volume + 0.1);\n resetHideTimer();\n break;\n case \"arrowdown\":\n e.preventDefault();\n player.setVolume(player.volume - 0.1);\n resetHideTimer();\n break;\n case \"m\":\n e.preventDefault();\n player.toggleMute();\n resetHideTimer();\n break;\n case \"f\":\n e.preventDefault();\n player.toggleFullscreen();\n resetHideTimer();\n break;\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [player, resetHideTimer]);\n\n return (\n <div\n ref={player.containerRef}\n className={`vexor-player ${player.isFullscreen ? \"is-fullscreen\" : \"\"} ${protect ? \"is-protected\" : \"\"} ${className}`}\n style={style}\n onMouseMove={resetHideTimer}\n onMouseLeave={(event) => {\n if (player.isPlaying && !event.currentTarget.contains(document.activeElement)) {\n setControlsVisible(false);\n }\n }}\n onFocusCapture={() => {\n if (hideTimerRef.current) clearTimeout(hideTimerRef.current);\n setControlsVisible(true);\n }}\n onBlurCapture={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) resetHideTimer();\n }}\n onContextMenu={handleContextMenu}\n tabIndex={0}\n role=\"region\"\n aria-label=\"Video Player\"\n >\n <video\n ref={player.videoRef}\n className=\"vexor-video\"\n poster={poster}\n preload={preload}\n muted={muted}\n loop={loop}\n playsInline\n controls={nativeControls}\n onClick={nativeControls ? undefined : player.togglePlay}\n />\n\n {/* Watermark Overlay */}\n {watermark && <Watermark config={watermark} />}\n\n {/* Buffering Spinner */}\n {player.isBuffering && !player.error && (\n <div className=\"vexor-spinner-overlay\" aria-label=\"Buffering video\">\n <div className=\"vexor-spinner\" />\n </div>\n )}\n\n {/* Center Big Play Button (when paused, not buffering, and custom controls active) */}\n {!nativeControls && controls && !player.isPlaying && !player.isBuffering && !player.error && (\n <button type=\"button\" className=\"vexor-center-play-overlay\" onClick={player.togglePlay} aria-label=\"Play video\">\n <span className=\"vexor-center-play-button\" aria-hidden=\"true\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <polygon points=\"6,4 20,12 6,20\" />\n </svg>\n </span>\n </button>\n )}\n\n {/* Custom Controls Bar */}\n {!nativeControls && controls && !player.error && (\n <Controls\n isPlaying={player.isPlaying}\n isBuffering={player.isBuffering}\n currentTime={player.currentTime}\n duration={player.duration}\n buffered={player.buffered}\n volume={player.volume}\n isMuted={player.isMuted}\n isFullscreen={player.isFullscreen}\n qualityLevels={player.qualityLevels}\n currentQuality={player.currentQuality}\n playbackRate={player.playbackRate}\n visible={controlsVisible}\n onPlayPause={player.togglePlay}\n onSeek={player.seek}\n onVolumeChange={player.setVolume}\n onToggleMute={player.toggleMute}\n onQualityChange={player.setQuality}\n onPlaybackRateChange={player.setPlaybackRate}\n onToggleFullscreen={player.toggleFullscreen}\n onTogglePiP={player.togglePiP}\n />\n )}\n\n {/* Error Overlay */}\n {player.error && (\n <div className=\"vexor-error-overlay\">\n <div className=\"vexor-error-title\">Playback Error</div>\n <div className=\"vexor-error-message\">{player.error.message}</div>\n <button type=\"button\" className=\"vexor-retry-button\" onClick={player.retry}>\n Retry Playback\n </button>\n </div>\n )}\n\n {/* Custom Child Overlays */}\n {children}\n </div>\n );\n};\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport Hls from \"hls.js\";\nimport type { QualityLevel, VexorPlayerProps } from \"../types\";\nimport { startNativeTokenRefresh } from \"../native-token-refresh\";\n\nexport interface UseVexorPlayerReturn {\n videoRef: React.RefObject<HTMLVideoElement | null>;\n containerRef: React.RefObject<HTMLDivElement | null>;\n isPlaying: boolean;\n isBuffering: boolean;\n currentTime: number;\n duration: number;\n buffered: number;\n volume: number;\n isMuted: boolean;\n isFullscreen: boolean;\n qualityLevels: QualityLevel[];\n currentQuality: number;\n playbackRate: number;\n error: { code: string; message: string; fatal: boolean } | null;\n play: () => Promise<void>;\n pause: () => void;\n togglePlay: () => void;\n seek: (time: number) => void;\n setVolume: (vol: number) => void;\n toggleMute: () => void;\n setQuality: (levelIndex: number) => void;\n setPlaybackRate: (rate: number) => void;\n toggleFullscreen: () => void;\n togglePiP: () => void;\n retry: () => void;\n}\n\nexport function useVexorPlayer({\n src,\n assetId,\n token,\n baseUrl = \"https://api.vexor.et\",\n fallbackSrc,\n autoPlay = false,\n muted = false,\n refreshToken,\n onReady,\n onPlay,\n onPause,\n onEnded,\n onTimeUpdate,\n onError,\n onQualityChange,\n}: VexorPlayerProps): UseVexorPlayerReturn {\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const hlsRef = useRef<Hls | null>(null);\n const callbacksRef = useRef({ onReady, onPlay, onPause, onEnded, onTimeUpdate, onError, onQualityChange, refreshToken });\n callbacksRef.current = { onReady, onPlay, onPause, onEnded, onTimeUpdate, onError, onQualityChange, refreshToken };\n const activeParamsRef = useRef(\"\");\n const refreshPromiseRef = useRef<Promise<string> | null>(null);\n const resumeAfterRefreshRef = useRef<{ time: number; shouldPlay: boolean } | null>(null);\n\n const [isPlaying, setIsPlaying] = useState(false);\n const [isBuffering, setIsBuffering] = useState(true);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [buffered, setBuffered] = useState(0);\n const [volume, setVolumeState] = useState(1);\n const [isMuted, setIsMuted] = useState(muted);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [qualityLevels, setQualityLevels] = useState<QualityLevel[]>([]);\n const [currentQuality, setCurrentQuality] = useState(-1);\n const [playbackRate, setPlaybackRateState] = useState(1);\n const [error, setError] = useState<{ code: string; message: string; fatal: boolean } | null>(null);\n const [reloadTrigger, setReloadTrigger] = useState(0);\n\n // Determine effective playback manifest URL\n const activeUrl = src\n ? src\n : assetId\n ? `${baseUrl.replace(/\\/+$/, \"\")}/v1/playback/${encodeURIComponent(assetId)}/master.m3u8${token ? `?token=${encodeURIComponent(token)}` : \"\"}`\n : \"\";\n\n const destroyHls = useCallback(() => {\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n }, []);\n\n const retry = useCallback(() => {\n setError(null);\n setIsBuffering(true);\n setReloadTrigger((v) => v + 1);\n }, []);\n\n // Initialize HLS & Media Source\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n let cleanupFallback = () => {};\n const loadFallback = () => {\n if (!fallbackSrc) return false;\n destroyHls();\n setIsBuffering(true);\n video.src = fallbackSrc;\n const onLoaded = () => {\n setIsBuffering(false);\n callbacksRef.current.onReady?.();\n };\n const onError = () => {\n const errObj = {\n code: \"FALLBACK_PLAYBACK_ERROR\",\n message: \"Unable to load fallback media source\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n video.addEventListener(\"loadeddata\", onLoaded);\n video.addEventListener(\"error\", onError);\n cleanupFallback = () => {\n video.removeEventListener(\"loadeddata\", onLoaded);\n video.removeEventListener(\"error\", onError);\n };\n video.load();\n return true;\n };\n const setFatalError = (code: string, message: string) => {\n destroyHls();\n const errObj = { code, message, fatal: true };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n\n destroyHls();\n setError(null);\n setCurrentTime(0);\n setDuration(0);\n setBuffered(0);\n setQualityLevels([]);\n setCurrentQuality(-1);\n setIsBuffering(Boolean(activeUrl));\n if (!activeUrl) {\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n return;\n }\n\n const isHlsUrl = activeUrl.includes(\".m3u8\") || activeUrl.includes(\"/playback/\");\n let fatalRecoveryAttempts = 0;\n\n if (isHlsUrl && Hls.isSupported()) {\n activeParamsRef.current = activeUrl.includes(\"?\") ? activeUrl.substring(activeUrl.indexOf(\"?\")) : \"\";\n\n class VexorLoader extends Hls.DefaultConfig.loader {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n load(context: any, config: any, callbacks: any) {\n // Propagate token query params to child playlists and segments if not present\n const activeParams = activeParamsRef.current;\n if (activeParams && context?.url) {\n try {\n const sourceUrl = new URL(activeUrl, window.location.href);\n const childUrl = new URL(context.url, sourceUrl);\n if (childUrl.origin === sourceUrl.origin && !childUrl.searchParams.has(\"token\")) {\n new URLSearchParams(activeParams).forEach((value, key) => {\n if (!childUrl.searchParams.has(key)) childUrl.searchParams.set(key, value);\n });\n context.url = childUrl.toString();\n }\n } catch {\n // Leave an unparseable child URL untouched; the loader will report failures normally.\n }\n }\n super.load(context, config, callbacks);\n }\n }\n\n const hls = new Hls({\n startFragPrefetch: true,\n maxBufferLength: 30,\n maxMaxBufferLength: 60,\n enableWorker: true,\n lowLatencyMode: true,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n loader: VexorLoader as any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fLoader: VexorLoader as any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n pLoader: VexorLoader as any,\n });\n hlsRef.current = hls;\n\n hls.loadSource(activeUrl);\n hls.attachMedia(video);\n\n hls.on(Hls.Events.MANIFEST_PARSED, (_event, data) => {\n if (hlsRef.current !== hls) return;\n setIsBuffering(false);\n const levels: QualityLevel[] = data.levels.map((lvl, index) => {\n let label = `${lvl.height}p`;\n if (lvl.height === 0 || lvl.videoCodec === undefined) {\n label = \"Audio only\";\n }\n return {\n id: index,\n height: lvl.height,\n width: lvl.width,\n bitrate: lvl.bitrate,\n label,\n };\n });\n setQualityLevels(levels);\n callbacksRef.current.onReady?.();\n const resume = resumeAfterRefreshRef.current;\n if (resume) {\n resumeAfterRefreshRef.current = null;\n if (Number.isFinite(resume.time) && resume.time > 0) video.currentTime = resume.time;\n if (resume.shouldPlay) video.play().catch(() => {});\n }\n if (autoPlay) {\n video.play().catch(() => {\n // Autoplay might be blocked by browser policy; user can interact to start\n });\n }\n });\n\n hls.on(Hls.Events.LEVEL_SWITCHED, (_event, data) => {\n if (hlsRef.current !== hls) return;\n setCurrentQuality(hls.autoLevelEnabled ? -1 : data.level);\n callbacksRef.current.onQualityChange?.(hls.autoLevelEnabled ? -1 : data.level);\n });\n\n hls.on(Hls.Events.ERROR, async (_event, data) => {\n if (hlsRef.current !== hls) return;\n // Handle token expiry (HTTP 401 or 403 on key/segment)\n if (\n (data.response?.code === 401 || data.response?.code === 403) &&\n callbacksRef.current.refreshToken\n ) {\n try {\n if (!refreshPromiseRef.current) {\n refreshPromiseRef.current = callbacksRef.current.refreshToken();\n }\n const newToken = await refreshPromiseRef.current;\n refreshPromiseRef.current = null;\n if (newToken && hlsRef.current === hls) {\n resumeAfterRefreshRef.current = {\n time: video.currentTime,\n shouldPlay: !video.paused,\n };\n const url = new URL(activeUrl, window.location.href);\n url.searchParams.set(\"token\", newToken);\n activeParamsRef.current = url.search;\n hls.loadSource(url.toString());\n hls.startLoad();\n return;\n }\n } catch {\n refreshPromiseRef.current = null;\n // Fall through to standard error handling if token refresh fails\n }\n }\n\n if (hlsRef.current !== hls) return;\n\n if (data.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n if (fatalRecoveryAttempts++ < 1) {\n hls.startLoad();\n } else if (!loadFallback()) {\n setFatalError(data.details || \"NETWORK_ERROR\", `Failed to stream video: ${data.details || \"network error\"}`);\n }\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n if (fatalRecoveryAttempts++ < 1) {\n hls.recoverMediaError();\n } else if (!loadFallback()) {\n setFatalError(data.details || \"MEDIA_ERROR\", `Failed to stream video: ${data.details || \"media error\"}`);\n }\n break;\n default:\n if (!loadFallback()) {\n setFatalError(data.details || \"MEDIA_PLAYBACK_ERROR\", `Failed to stream video: ${data.details || \"network error\"}`);\n }\n break;\n }\n }\n });\n } else if (isHlsUrl && video.canPlayType(\"application/vnd.apple.mpegurl\")) {\n // Safari / iOS Native HLS\n video.src = activeUrl;\n const nativeTokenRefresh = startNativeTokenRefresh(\n video,\n activeUrl,\n callbacksRef.current.refreshToken,\n );\n const onLoaded = () => {\n setIsBuffering(false);\n callbacksRef.current.onReady?.();\n if (autoPlay) {\n video.play().catch(() => {});\n }\n };\n const onNativeError = () => {\n void nativeTokenRefresh.refreshNow().then((refreshed) => {\n if (refreshed || hlsRef.current) return;\n if (loadFallback()) {\n video.removeEventListener(\"error\", onNativeError);\n return;\n }\n setFatalError(\"NATIVE_HLS_ERROR\", \"Failed to play native HLS stream\");\n });\n };\n video.addEventListener(\"loadedmetadata\", onLoaded);\n video.addEventListener(\"error\", onNativeError);\n return () => {\n nativeTokenRefresh.stop();\n video.removeEventListener(\"loadedmetadata\", onLoaded);\n video.removeEventListener(\"error\", onNativeError);\n };\n } else if (!isHlsUrl) {\n // Standard MP4 progressive playback\n video.src = activeUrl;\n const onLoaded = () => {\n setIsBuffering(false);\n callbacksRef.current.onReady?.();\n };\n const onErr = () => {\n const errObj = {\n code: \"DIRECT_PLAYBACK_ERROR\",\n message: \"Unable to load media source\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n };\n video.addEventListener(\"loadeddata\", onLoaded);\n video.addEventListener(\"error\", onErr);\n return () => {\n video.removeEventListener(\"loadeddata\", onLoaded);\n video.removeEventListener(\"error\", onErr);\n };\n } else if (fallbackSrc) {\n // HLS unsupported: use the configured progressive fallback.\n loadFallback();\n } else {\n const errObj = {\n code: \"HLS_UNSUPPORTED\",\n message: \"This browser does not support HLS playback and no fallback source was provided\",\n fatal: true,\n };\n setError(errObj);\n callbacksRef.current.onError?.(errObj);\n setIsBuffering(false);\n }\n\n return () => {\n cleanupFallback();\n destroyHls();\n };\n }, [activeUrl, fallbackSrc, autoPlay, reloadTrigger, destroyHls]);\n\n // Video Element Event Listeners\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n const onPlayEvent = () => {\n setIsPlaying(true);\n callbacksRef.current.onPlay?.();\n };\n\n const onPauseEvent = () => {\n setIsPlaying(false);\n callbacksRef.current.onPause?.();\n };\n\n const onEndedEvent = () => {\n setIsPlaying(false);\n callbacksRef.current.onEnded?.();\n };\n\n const onWaiting = () => setIsBuffering(true);\n const onPlaying = () => setIsBuffering(false);\n\n const onTimeUpdateEvent = () => {\n setCurrentTime(video.currentTime);\n callbacksRef.current.onTimeUpdate?.(video.currentTime, video.duration);\n\n // Calculate buffer progress\n if (video.buffered.length > 0 && video.duration > 0) {\n for (let i = video.buffered.length - 1; i >= 0; i--) {\n if (video.buffered.start(i) <= video.currentTime) {\n setBuffered((video.buffered.end(i) / video.duration) * 100);\n break;\n }\n }\n }\n };\n\n const onDurationChange = () => setDuration(video.duration || 0);\n const onVolumeChangeEvent = () => {\n setVolumeState(video.volume);\n setIsMuted(video.muted);\n };\n\n video.addEventListener(\"play\", onPlayEvent);\n video.addEventListener(\"pause\", onPauseEvent);\n video.addEventListener(\"ended\", onEndedEvent);\n video.addEventListener(\"waiting\", onWaiting);\n video.addEventListener(\"playing\", onPlaying);\n video.addEventListener(\"timeupdate\", onTimeUpdateEvent);\n video.addEventListener(\"durationchange\", onDurationChange);\n video.addEventListener(\"volumechange\", onVolumeChangeEvent);\n\n return () => {\n video.removeEventListener(\"play\", onPlayEvent);\n video.removeEventListener(\"pause\", onPauseEvent);\n video.removeEventListener(\"ended\", onEndedEvent);\n video.removeEventListener(\"waiting\", onWaiting);\n video.removeEventListener(\"playing\", onPlaying);\n video.removeEventListener(\"timeupdate\", onTimeUpdateEvent);\n video.removeEventListener(\"durationchange\", onDurationChange);\n video.removeEventListener(\"volumechange\", onVolumeChangeEvent);\n };\n }, []);\n\n // Fullscreen change listener\n useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen(Boolean(document.fullscreenElement));\n };\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () => document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, []);\n\n // Player Actions\n const play = useCallback(async () => {\n if (videoRef.current) {\n await videoRef.current.play();\n }\n }, []);\n\n const pause = useCallback(() => {\n if (videoRef.current) {\n videoRef.current.pause();\n }\n }, []);\n\n const togglePlay = useCallback(() => {\n if (!videoRef.current) return;\n if (videoRef.current.paused) {\n videoRef.current.play().catch(() => {});\n } else {\n videoRef.current.pause();\n }\n }, []);\n\n const seek = useCallback((time: number) => {\n if (videoRef.current) {\n videoRef.current.currentTime = Math.max(0, Math.min(time, videoRef.current.duration || time));\n }\n }, []);\n\n const setVolume = useCallback((vol: number) => {\n if (videoRef.current) {\n const clamped = Math.max(0, Math.min(1, vol));\n videoRef.current.volume = clamped;\n videoRef.current.muted = clamped === 0;\n }\n }, []);\n\n const toggleMute = useCallback(() => {\n if (videoRef.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n }, []);\n\n const setQuality = useCallback((levelIndex: number) => {\n if (hlsRef.current) {\n if (levelIndex === -1) {\n hlsRef.current.currentLevel = -1; // Auto\n } else {\n hlsRef.current.currentLevel = levelIndex;\n }\n setCurrentQuality(levelIndex);\n }\n }, []);\n\n const setPlaybackRate = useCallback((rate: number) => {\n if (videoRef.current) {\n videoRef.current.playbackRate = rate;\n setPlaybackRateState(rate);\n }\n }, []);\n\n const toggleFullscreen = useCallback(() => {\n const container = containerRef.current || videoRef.current;\n if (!container) return;\n\n if (!document.fullscreenElement) {\n container.requestFullscreen().catch(() => {});\n } else {\n document.exitFullscreen().catch(() => {});\n }\n }, []);\n\n const togglePiP = useCallback(async () => {\n const video = videoRef.current;\n if (!video) return;\n\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else if (document.pictureInPictureEnabled) {\n await video.requestPictureInPicture();\n }\n } catch {\n // Ignored\n }\n }, []);\n\n return {\n videoRef,\n containerRef,\n isPlaying,\n isBuffering,\n currentTime,\n duration,\n buffered,\n volume,\n isMuted,\n isFullscreen,\n qualityLevels,\n currentQuality,\n playbackRate,\n error,\n play,\n pause,\n togglePlay,\n seek,\n setVolume,\n toggleMute,\n setQuality,\n setPlaybackRate,\n toggleFullscreen,\n togglePiP,\n retry,\n };\n}\n","import React, { useState, useRef, useEffect, useCallback } from \"react\";\nimport type { QualityLevel } from \"../types\";\n\ninterface ControlsProps {\n isPlaying: boolean;\n isBuffering: boolean;\n currentTime: number;\n duration: number;\n buffered: number;\n volume: number;\n isMuted: boolean;\n isFullscreen: boolean;\n qualityLevels: QualityLevel[];\n currentQuality: number;\n playbackRate: number;\n visible: boolean;\n onPlayPause: () => void;\n onSeek: (time: number) => void;\n onVolumeChange: (volume: number) => void;\n onToggleMute: () => void;\n onQualityChange: (levelIndex: number) => void;\n onPlaybackRateChange: (rate: number) => void;\n onToggleFullscreen: () => void;\n onTogglePiP: () => void;\n}\n\nfunction formatTime(seconds: number): string {\n if (isNaN(seconds) || seconds < 0) return \"0:00\";\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = Math.floor(seconds % 60);\n if (h > 0) {\n return `${h}:${m.toString().padStart(2, \"0\")}:${s.toString().padStart(2, \"0\")}`;\n }\n return `${m}:${s.toString().padStart(2, \"0\")}`;\n}\n\nexport const Controls: React.FC<ControlsProps> = ({\n isPlaying,\n currentTime,\n duration,\n buffered,\n volume,\n isMuted,\n isFullscreen,\n qualityLevels,\n currentQuality,\n playbackRate,\n visible,\n onPlayPause,\n onSeek,\n onVolumeChange,\n onToggleMute,\n onQualityChange,\n onPlaybackRateChange,\n onToggleFullscreen,\n onTogglePiP,\n}) => {\n const [showQualityMenu, setShowQualityMenu] = useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = useState(false);\n const progressRef = useRef<HTMLDivElement>(null);\n const [isScrubbing, setIsScrubbing] = useState(false);\n const [pictureInPictureSupported, setPictureInPictureSupported] = useState(false);\n\n useEffect(() => {\n setPictureInPictureSupported(\n typeof document !== \"undefined\" && document.pictureInPictureEnabled\n );\n }, []);\n\n const playedPercent = duration > 0 ? (currentTime / duration) * 100 : 0;\n const speedOptions = [0.5, 0.75, 1, 1.25, 1.5, 2];\n\n const handleScrub = useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n if (!progressRef.current || duration <= 0) return;\n const rect = progressRef.current.getBoundingClientRect();\n const pos = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n onSeek(pos * duration);\n },\n [duration, onSeek]\n );\n\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n if (e.button !== 0) return;\n e.currentTarget.setPointerCapture(e.pointerId);\n setIsScrubbing(true);\n handleScrub(e);\n };\n\n const handleTimelineKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (duration <= 0) return;\n const step = e.shiftKey ? 30 : 5;\n let nextTime: number | undefined;\n if (e.key === \"ArrowLeft\") nextTime = currentTime - step;\n if (e.key === \"ArrowRight\") nextTime = currentTime + step;\n if (e.key === \"Home\") nextTime = 0;\n if (e.key === \"End\") nextTime = duration;\n if (nextTime !== undefined) {\n e.preventDefault();\n onSeek(Math.max(0, Math.min(duration, nextTime)));\n }\n };\n\n return (\n <div className={`vexor-controls ${visible ? \"\" : \"is-hidden\"}`}>\n {/* Timeline Scrubber */}\n <div\n className=\"vexor-progress-container\"\n ref={progressRef}\n onPointerDown={handlePointerDown}\n onPointerMove={(event) => { if (isScrubbing) handleScrub(event); }}\n onPointerUp={(event) => {\n if (progressRef.current?.hasPointerCapture(event.pointerId)) {\n progressRef.current.releasePointerCapture(event.pointerId);\n }\n setIsScrubbing(false);\n }}\n onPointerCancel={() => setIsScrubbing(false)}\n onKeyDown={handleTimelineKeyDown}\n tabIndex={0}\n role=\"slider\"\n aria-label=\"Video timeline\"\n aria-valuemin={0}\n aria-valuemax={duration}\n aria-valuenow={Math.min(currentTime, duration || 0)}\n aria-valuetext={`${formatTime(currentTime)} of ${formatTime(duration)}`}\n >\n <div className=\"vexor-progress-track\">\n <div className=\"vexor-progress-buffer\" style={{ width: `${buffered}%` }} />\n <div className=\"vexor-progress-played\" style={{ width: `${playedPercent}%` }} />\n <div className=\"vexor-progress-thumb\" style={{ left: `${playedPercent}%` }} />\n </div>\n </div>\n\n {/* Control Buttons Row */}\n <div className=\"vexor-controls-row\">\n {/* Left Side: Play/Pause, Volume, Time */}\n <div className=\"vexor-controls-group\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onPlayPause}\n aria-label={isPlaying ? \"Pause\" : \"Play\"}\n >\n {isPlaying ? (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <polygon points=\"5,3 19,12 5,21\" />\n </svg>\n )}\n </button>\n\n <div className=\"vexor-volume-wrapper\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onToggleMute}\n aria-label={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted || volume === 0 ? (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\" />\n <line x1=\"17\" y1=\"9\" x2=\"23\" y2=\"15\" />\n </svg>\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\" />\n </svg>\n )}\n </button>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n value={isMuted ? 0 : volume}\n onChange={(e) => onVolumeChange(parseFloat(e.target.value))}\n className=\"vexor-volume-slider\"\n aria-label=\"Volume slider\"\n />\n </div>\n\n <span className=\"vexor-time-display\">\n {formatTime(currentTime)} / {formatTime(duration)}\n </span>\n </div>\n\n {/* Right Side: Speed, Quality, PiP, Fullscreen */}\n <div className=\"vexor-controls-group\">\n {/* Speed Selector */}\n <div className=\"vexor-menu-anchor\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={() => {\n setShowSpeedMenu(!showSpeedMenu);\n setShowQualityMenu(false);\n }}\n aria-label=\"Playback speed\"\n style={{ fontSize: \"11px\", fontWeight: 600, padding: \"4px 8px\" }}\n >\n {playbackRate === 1 ? \"1x\" : `${playbackRate}x`}\n </button>\n\n {showSpeedMenu && (\n <div className=\"vexor-menu-dropdown\">\n {speedOptions.map((rate) => (\n <button\n key={rate}\n type=\"button\"\n className={`vexor-menu-item ${playbackRate === rate ? \"is-active\" : \"\"}`}\n onClick={() => {\n onPlaybackRateChange(rate);\n setShowSpeedMenu(false);\n }}\n >\n <span>{rate}x</span>\n {playbackRate === rate && <span>✓</span>}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Quality Levels Selector */}\n {qualityLevels.length > 0 && (\n <div className=\"vexor-menu-anchor\">\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={() => {\n setShowQualityMenu(!showQualityMenu);\n setShowSpeedMenu(false);\n }}\n aria-label=\"Video quality\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\" />\n </svg>\n </button>\n\n {showQualityMenu && (\n <div className=\"vexor-menu-dropdown\">\n <button\n type=\"button\"\n className={`vexor-menu-item ${currentQuality === -1 ? \"is-active\" : \"\"}`}\n onClick={() => {\n onQualityChange(-1);\n setShowQualityMenu(false);\n }}\n >\n <span>Auto</span>\n {currentQuality === -1 && <span>✓</span>}\n </button>\n {qualityLevels.map((lvl) => (\n <button\n key={lvl.id}\n type=\"button\"\n className={`vexor-menu-item ${currentQuality === lvl.id ? \"is-active\" : \"\"}`}\n onClick={() => {\n onQualityChange(lvl.id);\n setShowQualityMenu(false);\n }}\n >\n <span>{lvl.label}</span>\n {currentQuality === lvl.id && <span>✓</span>}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Picture in Picture */}\n {pictureInPictureSupported && (\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onTogglePiP}\n aria-label=\"Picture in picture\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" />\n <rect x=\"12\" y=\"9\" width=\"8\" height=\"6\" rx=\"1\" fill=\"currentColor\" fillOpacity=\"0.4\" />\n </svg>\n </button>\n )}\n\n {/* Fullscreen Toggle */}\n <button\n type=\"button\"\n className=\"vexor-btn\"\n onClick={onToggleFullscreen}\n aria-label={isFullscreen ? \"Exit fullscreen\" : \"Enter fullscreen\"}\n >\n {isFullscreen ? (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3\" />\n </svg>\n ) : (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\" />\n </svg>\n )}\n </button>\n </div>\n </div>\n </div>\n );\n};\n","import React, { useEffect, useState, useMemo } from \"react\";\nimport type { WatermarkConfig } from \"../types\";\n\ninterface WatermarkProps {\n config?: string | WatermarkConfig;\n}\n\nexport const Watermark: React.FC<WatermarkProps> = ({ config }) => {\n const parsedConfig: WatermarkConfig | null = useMemo(() => {\n if (!config) return null;\n if (typeof config === \"string\") {\n return { text: config, position: \"dynamic\", intervalSeconds: 15, opacity: 0.35 };\n }\n return {\n position: \"dynamic\",\n intervalSeconds: 15,\n opacity: 0.35,\n ...config,\n };\n }, [config]);\n\n const [coords, setCoords] = useState<{ top: string; left: string }>({ top: \"15%\", left: \"15%\" });\n\n useEffect(() => {\n if (!parsedConfig || parsedConfig.position !== \"dynamic\") return;\n\n const intervalMs = Math.max(2, parsedConfig.intervalSeconds || 15) * 1000;\n const updatePosition = () => {\n // Keep watermark inside 10% - 80% range so it doesn't clip\n const top = Math.floor(10 + Math.random() * 70);\n const left = Math.floor(10 + Math.random() * 70);\n setCoords({ top: `${top}%`, left: `${left}%` });\n };\n\n updatePosition();\n const timer = setInterval(updatePosition, intervalMs);\n return () => clearInterval(timer);\n }, [parsedConfig?.position, parsedConfig?.intervalSeconds]);\n\n const getPositionStyles = (): React.CSSProperties => {\n switch (parsedConfig?.position) {\n case \"top-left\":\n return { top: \"16px\", left: \"16px\" };\n case \"top-right\":\n return { top: \"16px\", right: \"16px\" };\n case \"bottom-left\":\n return { bottom: \"48px\", left: \"16px\" };\n case \"bottom-right\":\n return { bottom: \"48px\", right: \"16px\" };\n case \"center\":\n return { top: \"50%\", left: \"50%\", transform: \"translate(-50%, -50%)\" };\n case \"dynamic\":\n default:\n return { top: coords.top, left: coords.left };\n }\n };\n\n if (!parsedConfig) return null;\n\n return (\n <div\n className=\"vexor-watermark\"\n style={{\n ...getPositionStyles(),\n opacity: Math.max(0, Math.min(1, parsedConfig.opacity ?? 0.35)),\n fontSize: parsedConfig.fontSize ?? \"12px\",\n color: parsedConfig.color ?? \"#ffffff\",\n }}\n aria-hidden=\"true\"\n >\n {parsedConfig.text}\n </div>\n );\n};\n"],"mappings":"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","names":["useState","useEffect","useRef","useCallback","onError","useState","useRef","useEffect","useCallback","useEffect","useState","jsx","jsx","jsxs","useState","useRef","useCallback","useEffect"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vexor-video/player",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Official React and Vanilla JS video player for Vexor encrypted HLS streaming.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"files": [
|
|
26
26
|
"dist",
|
|
27
27
|
"README.md",
|
|
28
|
+
"CHANGELOG.md",
|
|
28
29
|
"LICENSE"
|
|
29
30
|
],
|
|
30
31
|
"scripts": {
|