@vexor-video/player 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +221 -2
- package/dist/chunk-NBWDQALI.js +290 -0
- package/dist/chunk-NBWDQALI.js.map +1 -0
- package/dist/index.cjs +1312 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +306 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.cts +120 -0
- package/dist/index.d.ts +120 -0
- package/dist/index.js +991 -0
- package/dist/index.js.map +1 -0
- package/dist/vanilla-BZJjSEad.d.cts +66 -0
- package/dist/vanilla-BZJjSEad.d.ts +66 -0
- package/dist/vanilla.cjs +325 -0
- package/dist/vanilla.cjs.map +1 -0
- package/dist/vanilla.d.cts +1 -0
- package/dist/vanilla.d.ts +1 -0
- package/dist/vanilla.js +7 -0
- package/dist/vanilla.js.map +1 -0
- package/dist/vexor-player.global.js +45 -0
- package/dist/vexor-player.global.js.map +1 -0
- package/package.json +57 -4
|
@@ -0,0 +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"]}
|
package/dist/index.css
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
/* src/styles/player.css */
|
|
2
|
+
.vexor-player {
|
|
3
|
+
position: relative;
|
|
4
|
+
background-color: #000000;
|
|
5
|
+
overflow: hidden;
|
|
6
|
+
display: flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
width: 100%;
|
|
10
|
+
aspect-ratio: 16 / 9;
|
|
11
|
+
font-family:
|
|
12
|
+
-apple-system,
|
|
13
|
+
BlinkMacSystemFont,
|
|
14
|
+
"Segoe UI",
|
|
15
|
+
Roboto,
|
|
16
|
+
Helvetica,
|
|
17
|
+
Arial,
|
|
18
|
+
sans-serif;
|
|
19
|
+
user-select: none;
|
|
20
|
+
-webkit-user-select: none;
|
|
21
|
+
}
|
|
22
|
+
.vexor-player.is-fullscreen {
|
|
23
|
+
width: 100vw;
|
|
24
|
+
height: 100vh;
|
|
25
|
+
aspect-ratio: auto;
|
|
26
|
+
border-radius: 0;
|
|
27
|
+
}
|
|
28
|
+
.vexor-video {
|
|
29
|
+
width: 100%;
|
|
30
|
+
height: 100%;
|
|
31
|
+
object-fit: contain;
|
|
32
|
+
display: block;
|
|
33
|
+
}
|
|
34
|
+
.vexor-player.is-protected {
|
|
35
|
+
-webkit-touch-callout: none;
|
|
36
|
+
-webkit-user-select: none;
|
|
37
|
+
}
|
|
38
|
+
.vexor-watermark {
|
|
39
|
+
position: absolute;
|
|
40
|
+
pointer-events: none;
|
|
41
|
+
user-select: none;
|
|
42
|
+
z-index: 10;
|
|
43
|
+
font-weight: 500;
|
|
44
|
+
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8), 0 0 1px rgba(0, 0, 0, 0.9);
|
|
45
|
+
transition: all 1s ease-in-out;
|
|
46
|
+
white-space: nowrap;
|
|
47
|
+
}
|
|
48
|
+
.vexor-spinner-overlay {
|
|
49
|
+
position: absolute;
|
|
50
|
+
inset: 0;
|
|
51
|
+
display: flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
justify-content: center;
|
|
54
|
+
pointer-events: none;
|
|
55
|
+
z-index: 15;
|
|
56
|
+
}
|
|
57
|
+
.vexor-spinner {
|
|
58
|
+
width: 44px;
|
|
59
|
+
height: 44px;
|
|
60
|
+
border: 3px solid rgba(255, 255, 255, 0.2);
|
|
61
|
+
border-top-color: #ffffff;
|
|
62
|
+
border-radius: 50%;
|
|
63
|
+
animation: vexor-spin 0.8s linear infinite;
|
|
64
|
+
}
|
|
65
|
+
@keyframes vexor-spin {
|
|
66
|
+
to {
|
|
67
|
+
transform: rotate(360deg);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
.vexor-center-play-overlay {
|
|
71
|
+
position: absolute;
|
|
72
|
+
inset: 0;
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
z-index: 12;
|
|
78
|
+
padding: 0;
|
|
79
|
+
border: 0;
|
|
80
|
+
background: transparent;
|
|
81
|
+
color: inherit;
|
|
82
|
+
}
|
|
83
|
+
.vexor-center-play-button {
|
|
84
|
+
width: 64px;
|
|
85
|
+
height: 64px;
|
|
86
|
+
border-radius: 50%;
|
|
87
|
+
background: rgba(18, 18, 20, 0.75);
|
|
88
|
+
backdrop-filter: blur(8px);
|
|
89
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
90
|
+
color: #ffffff;
|
|
91
|
+
display: flex;
|
|
92
|
+
align-items: center;
|
|
93
|
+
justify-content: center;
|
|
94
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
|
|
95
|
+
transition: transform 0.15s ease, background-color 0.15s ease;
|
|
96
|
+
}
|
|
97
|
+
.vexor-center-play-overlay:hover .vexor-center-play-button {
|
|
98
|
+
transform: scale(1.08);
|
|
99
|
+
background: rgba(25, 25, 30, 0.9);
|
|
100
|
+
}
|
|
101
|
+
.vexor-controls {
|
|
102
|
+
position: absolute;
|
|
103
|
+
bottom: 0;
|
|
104
|
+
left: 0;
|
|
105
|
+
right: 0;
|
|
106
|
+
padding: 24px 16px 12px;
|
|
107
|
+
background:
|
|
108
|
+
linear-gradient(
|
|
109
|
+
to top,
|
|
110
|
+
rgba(0, 0, 0, 0.85) 0%,
|
|
111
|
+
rgba(0, 0, 0, 0.4) 65%,
|
|
112
|
+
transparent 100%);
|
|
113
|
+
display: flex;
|
|
114
|
+
flex-direction: column;
|
|
115
|
+
gap: 8px;
|
|
116
|
+
z-index: 20;
|
|
117
|
+
opacity: 1;
|
|
118
|
+
transition: opacity 0.25s ease;
|
|
119
|
+
}
|
|
120
|
+
.vexor-controls.is-hidden {
|
|
121
|
+
opacity: 0;
|
|
122
|
+
pointer-events: none;
|
|
123
|
+
}
|
|
124
|
+
.vexor-progress-container {
|
|
125
|
+
position: relative;
|
|
126
|
+
height: 14px;
|
|
127
|
+
display: flex;
|
|
128
|
+
align-items: center;
|
|
129
|
+
cursor: pointer;
|
|
130
|
+
touch-action: none;
|
|
131
|
+
}
|
|
132
|
+
.vexor-progress-container:focus-visible {
|
|
133
|
+
outline: 2px solid var(--vexor-accent, #ec6d1c);
|
|
134
|
+
outline-offset: 4px;
|
|
135
|
+
}
|
|
136
|
+
.vexor-progress-track {
|
|
137
|
+
width: 100%;
|
|
138
|
+
height: 4px;
|
|
139
|
+
background: rgba(255, 255, 255, 0.25);
|
|
140
|
+
border-radius: 2px;
|
|
141
|
+
position: relative;
|
|
142
|
+
transition: height 0.1s ease;
|
|
143
|
+
}
|
|
144
|
+
.vexor-progress-container:hover .vexor-progress-track {
|
|
145
|
+
height: 6px;
|
|
146
|
+
}
|
|
147
|
+
.vexor-progress-buffer {
|
|
148
|
+
position: absolute;
|
|
149
|
+
top: 0;
|
|
150
|
+
left: 0;
|
|
151
|
+
bottom: 0;
|
|
152
|
+
background: rgba(255, 255, 255, 0.4);
|
|
153
|
+
border-radius: 2px;
|
|
154
|
+
}
|
|
155
|
+
.vexor-progress-played {
|
|
156
|
+
position: absolute;
|
|
157
|
+
top: 0;
|
|
158
|
+
left: 0;
|
|
159
|
+
bottom: 0;
|
|
160
|
+
background: #2563eb;
|
|
161
|
+
border-radius: 2px;
|
|
162
|
+
}
|
|
163
|
+
.vexor-progress-thumb {
|
|
164
|
+
position: absolute;
|
|
165
|
+
top: 50%;
|
|
166
|
+
width: 12px;
|
|
167
|
+
height: 12px;
|
|
168
|
+
background: #ffffff;
|
|
169
|
+
border-radius: 50%;
|
|
170
|
+
transform: translate(-50%, -50%) scale(0);
|
|
171
|
+
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
|
|
172
|
+
transition: transform 0.15s ease;
|
|
173
|
+
}
|
|
174
|
+
.vexor-progress-container:hover .vexor-progress-thumb {
|
|
175
|
+
transform: translate(-50%, -50%) scale(1);
|
|
176
|
+
}
|
|
177
|
+
.vexor-controls-row {
|
|
178
|
+
display: flex;
|
|
179
|
+
align-items: center;
|
|
180
|
+
justify-content: space-between;
|
|
181
|
+
}
|
|
182
|
+
.vexor-controls-group {
|
|
183
|
+
display: flex;
|
|
184
|
+
align-items: center;
|
|
185
|
+
gap: 12px;
|
|
186
|
+
}
|
|
187
|
+
.vexor-btn {
|
|
188
|
+
background: none;
|
|
189
|
+
border: none;
|
|
190
|
+
color: #f3f4f6;
|
|
191
|
+
padding: 6px;
|
|
192
|
+
cursor: pointer;
|
|
193
|
+
display: flex;
|
|
194
|
+
align-items: center;
|
|
195
|
+
justify-content: center;
|
|
196
|
+
border-radius: 6px;
|
|
197
|
+
transition: color 0.15s ease, background-color 0.15s ease;
|
|
198
|
+
}
|
|
199
|
+
.vexor-btn:hover {
|
|
200
|
+
color: #ffffff;
|
|
201
|
+
background-color: rgba(255, 255, 255, 0.15);
|
|
202
|
+
}
|
|
203
|
+
.vexor-time-display {
|
|
204
|
+
color: #d1d5db;
|
|
205
|
+
font-size: 12px;
|
|
206
|
+
font-variant-numeric: tabular-nums;
|
|
207
|
+
margin-left: 4px;
|
|
208
|
+
}
|
|
209
|
+
.vexor-volume-wrapper {
|
|
210
|
+
display: flex;
|
|
211
|
+
align-items: center;
|
|
212
|
+
gap: 6px;
|
|
213
|
+
}
|
|
214
|
+
.vexor-volume-slider {
|
|
215
|
+
width: 0;
|
|
216
|
+
opacity: 0;
|
|
217
|
+
height: 4px;
|
|
218
|
+
accent-color: #ffffff;
|
|
219
|
+
cursor: pointer;
|
|
220
|
+
transition: width 0.2s ease, opacity 0.2s ease;
|
|
221
|
+
}
|
|
222
|
+
.vexor-volume-wrapper:hover .vexor-volume-slider {
|
|
223
|
+
width: 64px;
|
|
224
|
+
opacity: 1;
|
|
225
|
+
}
|
|
226
|
+
.vexor-menu-anchor {
|
|
227
|
+
position: relative;
|
|
228
|
+
}
|
|
229
|
+
.vexor-menu-dropdown {
|
|
230
|
+
position: absolute;
|
|
231
|
+
bottom: 100%;
|
|
232
|
+
right: 0;
|
|
233
|
+
margin-bottom: 8px;
|
|
234
|
+
background: rgba(20, 20, 22, 0.95);
|
|
235
|
+
backdrop-filter: blur(12px);
|
|
236
|
+
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
237
|
+
border-radius: 8px;
|
|
238
|
+
padding: 6px;
|
|
239
|
+
min-width: 120px;
|
|
240
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
|
|
241
|
+
display: flex;
|
|
242
|
+
flex-direction: column;
|
|
243
|
+
gap: 2px;
|
|
244
|
+
}
|
|
245
|
+
.vexor-menu-item {
|
|
246
|
+
background: none;
|
|
247
|
+
border: none;
|
|
248
|
+
color: #e5e7eb;
|
|
249
|
+
padding: 6px 10px;
|
|
250
|
+
font-size: 12px;
|
|
251
|
+
text-align: left;
|
|
252
|
+
border-radius: 4px;
|
|
253
|
+
cursor: pointer;
|
|
254
|
+
display: flex;
|
|
255
|
+
align-items: center;
|
|
256
|
+
justify-content: space-between;
|
|
257
|
+
width: 100%;
|
|
258
|
+
transition: background-color 0.12s ease;
|
|
259
|
+
}
|
|
260
|
+
.vexor-menu-item:hover {
|
|
261
|
+
background: rgba(255, 255, 255, 0.12);
|
|
262
|
+
color: #ffffff;
|
|
263
|
+
}
|
|
264
|
+
.vexor-menu-item.is-active {
|
|
265
|
+
color: #60a5fa;
|
|
266
|
+
font-weight: 600;
|
|
267
|
+
}
|
|
268
|
+
.vexor-error-overlay {
|
|
269
|
+
position: absolute;
|
|
270
|
+
inset: 0;
|
|
271
|
+
background: rgba(10, 10, 12, 0.92);
|
|
272
|
+
display: flex;
|
|
273
|
+
flex-direction: column;
|
|
274
|
+
align-items: center;
|
|
275
|
+
justify-content: center;
|
|
276
|
+
padding: 24px;
|
|
277
|
+
text-align: center;
|
|
278
|
+
color: #ffffff;
|
|
279
|
+
z-index: 30;
|
|
280
|
+
}
|
|
281
|
+
.vexor-error-title {
|
|
282
|
+
font-size: 15px;
|
|
283
|
+
font-weight: 600;
|
|
284
|
+
margin-bottom: 6px;
|
|
285
|
+
}
|
|
286
|
+
.vexor-error-message {
|
|
287
|
+
font-size: 12px;
|
|
288
|
+
color: #9ca3af;
|
|
289
|
+
max-width: 400px;
|
|
290
|
+
margin-bottom: 16px;
|
|
291
|
+
}
|
|
292
|
+
.vexor-retry-button {
|
|
293
|
+
padding: 8px 16px;
|
|
294
|
+
font-size: 12px;
|
|
295
|
+
font-weight: 500;
|
|
296
|
+
border-radius: 6px;
|
|
297
|
+
background: #2563eb;
|
|
298
|
+
color: #ffffff;
|
|
299
|
+
border: none;
|
|
300
|
+
cursor: pointer;
|
|
301
|
+
transition: background-color 0.15s ease;
|
|
302
|
+
}
|
|
303
|
+
.vexor-retry-button:hover {
|
|
304
|
+
background: #1d4ed8;
|
|
305
|
+
}
|
|
306
|
+
/*# sourceMappingURL=index.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/styles/player.css"],"sourcesContent":["/* Vexor Player Core Styles */\n\n.vexor-player {\n position: relative;\n background-color: #000000;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n aspect-ratio: 16 / 9;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n user-select: none;\n -webkit-user-select: none;\n}\n\n.vexor-player.is-fullscreen {\n width: 100vw;\n height: 100vh;\n aspect-ratio: auto;\n border-radius: 0;\n}\n\n.vexor-video {\n width: 100%;\n height: 100%;\n object-fit: contain;\n display: block;\n}\n\n.vexor-player.is-protected {\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n}\n\n/* Watermark */\n.vexor-watermark {\n position: absolute;\n pointer-events: none;\n user-select: none;\n z-index: 10;\n font-weight: 500;\n text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8), 0 0 1px rgba(0, 0, 0, 0.9);\n transition: all 1s ease-in-out;\n white-space: nowrap;\n}\n\n/* Buffering Spinner */\n.vexor-spinner-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 15;\n}\n\n.vexor-spinner {\n width: 44px;\n height: 44px;\n border: 3px solid rgba(255, 255, 255, 0.2);\n border-top-color: #ffffff;\n border-radius: 50%;\n animation: vexor-spin 0.8s linear infinite;\n}\n\n@keyframes vexor-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n/* Big Play Button Overlay */\n.vexor-center-play-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: 12;\n padding: 0;\n border: 0;\n background: transparent;\n color: inherit;\n}\n\n.vexor-center-play-button {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: rgba(18, 18, 20, 0.75);\n backdrop-filter: blur(8px);\n border: 1px solid rgba(255, 255, 255, 0.15);\n color: #ffffff;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);\n transition: transform 0.15s ease, background-color 0.15s ease;\n}\n\n.vexor-center-play-overlay:hover .vexor-center-play-button {\n transform: scale(1.08);\n background: rgba(25, 25, 30, 0.9);\n}\n\n/* Controls Bar */\n.vexor-controls {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n padding: 24px 16px 12px;\n background: linear-gradient(to top, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.4) 65%, transparent 100%);\n display: flex;\n flex-direction: column;\n gap: 8px;\n z-index: 20;\n opacity: 1;\n transition: opacity 0.25s ease;\n}\n\n.vexor-controls.is-hidden {\n opacity: 0;\n pointer-events: none;\n}\n\n/* Scrubber / Progress Bar */\n.vexor-progress-container {\n position: relative;\n height: 14px;\n display: flex;\n align-items: center;\n cursor: pointer;\n touch-action: none;\n}\n\n.vexor-progress-container:focus-visible {\n outline: 2px solid var(--vexor-accent, #ec6d1c);\n outline-offset: 4px;\n}\n\n.vexor-progress-track {\n width: 100%;\n height: 4px;\n background: rgba(255, 255, 255, 0.25);\n border-radius: 2px;\n position: relative;\n transition: height 0.1s ease;\n}\n\n.vexor-progress-container:hover .vexor-progress-track {\n height: 6px;\n}\n\n.vexor-progress-buffer {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n background: rgba(255, 255, 255, 0.4);\n border-radius: 2px;\n}\n\n.vexor-progress-played {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n background: #2563eb;\n border-radius: 2px;\n}\n\n.vexor-progress-thumb {\n position: absolute;\n top: 50%;\n width: 12px;\n height: 12px;\n background: #ffffff;\n border-radius: 50%;\n transform: translate(-50%, -50%) scale(0);\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);\n transition: transform 0.15s ease;\n}\n\n.vexor-progress-container:hover .vexor-progress-thumb {\n transform: translate(-50%, -50%) scale(1);\n}\n\n/* Controls Buttons Bar */\n.vexor-controls-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n.vexor-controls-group {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.vexor-btn {\n background: none;\n border: none;\n color: #f3f4f6;\n padding: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n transition: color 0.15s ease, background-color 0.15s ease;\n}\n\n.vexor-btn:hover {\n color: #ffffff;\n background-color: rgba(255, 255, 255, 0.15);\n}\n\n.vexor-time-display {\n color: #d1d5db;\n font-size: 12px;\n font-variant-numeric: tabular-nums;\n margin-left: 4px;\n}\n\n/* Volume Slider */\n.vexor-volume-wrapper {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.vexor-volume-slider {\n width: 0;\n opacity: 0;\n height: 4px;\n accent-color: #ffffff;\n cursor: pointer;\n transition: width 0.2s ease, opacity 0.2s ease;\n}\n\n.vexor-volume-wrapper:hover .vexor-volume-slider {\n width: 64px;\n opacity: 1;\n}\n\n/* Quality & Settings Menu */\n.vexor-menu-anchor {\n position: relative;\n}\n\n.vexor-menu-dropdown {\n position: absolute;\n bottom: 100%;\n right: 0;\n margin-bottom: 8px;\n background: rgba(20, 20, 22, 0.95);\n backdrop-filter: blur(12px);\n border: 1px solid rgba(255, 255, 255, 0.12);\n border-radius: 8px;\n padding: 6px;\n min-width: 120px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.vexor-menu-item {\n background: none;\n border: none;\n color: #e5e7eb;\n padding: 6px 10px;\n font-size: 12px;\n text-align: left;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n transition: background-color 0.12s ease;\n}\n\n.vexor-menu-item:hover {\n background: rgba(255, 255, 255, 0.12);\n color: #ffffff;\n}\n\n.vexor-menu-item.is-active {\n color: #60a5fa;\n font-weight: 600;\n}\n\n/* Error State */\n.vexor-error-overlay {\n position: absolute;\n inset: 0;\n background: rgba(10, 10, 12, 0.92);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 24px;\n text-align: center;\n color: #ffffff;\n z-index: 30;\n}\n\n.vexor-error-title {\n font-size: 15px;\n font-weight: 600;\n margin-bottom: 6px;\n}\n\n.vexor-error-message {\n font-size: 12px;\n color: #9ca3af;\n max-width: 400px;\n margin-bottom: 16px;\n}\n\n.vexor-retry-button {\n padding: 8px 16px;\n font-size: 12px;\n font-weight: 500;\n border-radius: 6px;\n background: #2563eb;\n color: #ffffff;\n border: none;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.vexor-retry-button:hover {\n background: #1d4ed8;\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React$1, { ReactNode, CSSProperties } from 'react';
|
|
2
|
+
import { W as WatermarkConfig, Q as QualityLevel } from './vanilla-BZJjSEad.cjs';
|
|
3
|
+
export { V as VanillaPlayerInstance, c as createVexorPlayer } from './vanilla-BZJjSEad.cjs';
|
|
4
|
+
|
|
5
|
+
interface VexorPlayerProps {
|
|
6
|
+
/** Full authenticated HLS manifest URL. */
|
|
7
|
+
src?: string;
|
|
8
|
+
/** Vexor asset UUID used when src is not provided. */
|
|
9
|
+
assetId?: string;
|
|
10
|
+
/** Short-lived playback token used with assetId. */
|
|
11
|
+
token?: string;
|
|
12
|
+
/** Vexor API base URL (default: https://api.vexor.et). */
|
|
13
|
+
baseUrl?: string;
|
|
14
|
+
/** Poster thumbnail URL. */
|
|
15
|
+
poster?: string;
|
|
16
|
+
/** Automatically start playback (browser policy may require muted=true). */
|
|
17
|
+
autoPlay?: boolean;
|
|
18
|
+
/** Start audio muted. */
|
|
19
|
+
muted?: boolean;
|
|
20
|
+
/** Loop playback. */
|
|
21
|
+
loop?: boolean;
|
|
22
|
+
/** HTML video preload behavior. */
|
|
23
|
+
preload?: "auto" | "metadata" | "none";
|
|
24
|
+
/** Fallback URL if HLS is unsupported or cannot be played. */
|
|
25
|
+
fallbackSrc?: string;
|
|
26
|
+
/** Display custom controls (default: true). */
|
|
27
|
+
controls?: boolean;
|
|
28
|
+
/** Use browser native controls instead of Vexor controls. */
|
|
29
|
+
nativeControls?: boolean;
|
|
30
|
+
/** Visible watermark overlay; this is a deterrent, not DRM or capture prevention. */
|
|
31
|
+
watermark?: string | WatermarkConfig;
|
|
32
|
+
/** Suppress context menu and drag interactions as a casual-copy deterrent only. */
|
|
33
|
+
protect?: boolean;
|
|
34
|
+
/** Retrieve a fresh playback token when an active token expires. */
|
|
35
|
+
refreshToken?: () => Promise<string>;
|
|
36
|
+
/** Playback lifecycle callbacks. */
|
|
37
|
+
onReady?: () => void;
|
|
38
|
+
onPlay?: () => void;
|
|
39
|
+
onPause?: () => void;
|
|
40
|
+
onEnded?: () => void;
|
|
41
|
+
onTimeUpdate?: (currentTime: number, duration: number) => void;
|
|
42
|
+
onError?: (error: {
|
|
43
|
+
code: string;
|
|
44
|
+
message: string;
|
|
45
|
+
fatal: boolean;
|
|
46
|
+
}) => void;
|
|
47
|
+
onQualityChange?: (levelIndex: number) => void;
|
|
48
|
+
/** Custom child elements rendered over the player. */
|
|
49
|
+
children?: ReactNode;
|
|
50
|
+
/** CSS class name applied to player container. */
|
|
51
|
+
className?: string;
|
|
52
|
+
/** Inline styles applied to player container. */
|
|
53
|
+
style?: CSSProperties;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
declare const VexorPlayer: React$1.FC<VexorPlayerProps>;
|
|
57
|
+
|
|
58
|
+
interface ControlsProps {
|
|
59
|
+
isPlaying: boolean;
|
|
60
|
+
isBuffering: boolean;
|
|
61
|
+
currentTime: number;
|
|
62
|
+
duration: number;
|
|
63
|
+
buffered: number;
|
|
64
|
+
volume: number;
|
|
65
|
+
isMuted: boolean;
|
|
66
|
+
isFullscreen: boolean;
|
|
67
|
+
qualityLevels: QualityLevel[];
|
|
68
|
+
currentQuality: number;
|
|
69
|
+
playbackRate: number;
|
|
70
|
+
visible: boolean;
|
|
71
|
+
onPlayPause: () => void;
|
|
72
|
+
onSeek: (time: number) => void;
|
|
73
|
+
onVolumeChange: (volume: number) => void;
|
|
74
|
+
onToggleMute: () => void;
|
|
75
|
+
onQualityChange: (levelIndex: number) => void;
|
|
76
|
+
onPlaybackRateChange: (rate: number) => void;
|
|
77
|
+
onToggleFullscreen: () => void;
|
|
78
|
+
onTogglePiP: () => void;
|
|
79
|
+
}
|
|
80
|
+
declare const Controls: React$1.FC<ControlsProps>;
|
|
81
|
+
|
|
82
|
+
interface WatermarkProps {
|
|
83
|
+
config?: string | WatermarkConfig;
|
|
84
|
+
}
|
|
85
|
+
declare const Watermark: React$1.FC<WatermarkProps>;
|
|
86
|
+
|
|
87
|
+
interface UseVexorPlayerReturn {
|
|
88
|
+
videoRef: React.RefObject<HTMLVideoElement | null>;
|
|
89
|
+
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
90
|
+
isPlaying: boolean;
|
|
91
|
+
isBuffering: boolean;
|
|
92
|
+
currentTime: number;
|
|
93
|
+
duration: number;
|
|
94
|
+
buffered: number;
|
|
95
|
+
volume: number;
|
|
96
|
+
isMuted: boolean;
|
|
97
|
+
isFullscreen: boolean;
|
|
98
|
+
qualityLevels: QualityLevel[];
|
|
99
|
+
currentQuality: number;
|
|
100
|
+
playbackRate: number;
|
|
101
|
+
error: {
|
|
102
|
+
code: string;
|
|
103
|
+
message: string;
|
|
104
|
+
fatal: boolean;
|
|
105
|
+
} | null;
|
|
106
|
+
play: () => Promise<void>;
|
|
107
|
+
pause: () => void;
|
|
108
|
+
togglePlay: () => void;
|
|
109
|
+
seek: (time: number) => void;
|
|
110
|
+
setVolume: (vol: number) => void;
|
|
111
|
+
toggleMute: () => void;
|
|
112
|
+
setQuality: (levelIndex: number) => void;
|
|
113
|
+
setPlaybackRate: (rate: number) => void;
|
|
114
|
+
toggleFullscreen: () => void;
|
|
115
|
+
togglePiP: () => void;
|
|
116
|
+
retry: () => void;
|
|
117
|
+
}
|
|
118
|
+
declare function useVexorPlayer({ src, assetId, token, baseUrl, fallbackSrc, autoPlay, muted, refreshToken, onReady, onPlay, onPause, onEnded, onTimeUpdate, onError, onQualityChange, }: VexorPlayerProps): UseVexorPlayerReturn;
|
|
119
|
+
|
|
120
|
+
export { Controls, QualityLevel, type UseVexorPlayerReturn, VexorPlayer, type VexorPlayerProps, Watermark, WatermarkConfig, useVexorPlayer };
|