@therealtinhtute/baroiplayer 1.1.0 → 1.2.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.
Files changed (78) hide show
  1. package/dist/core-plugins-By-4-kGs.cjs +2 -0
  2. package/dist/core-plugins-By-4-kGs.cjs.map +1 -0
  3. package/dist/{core-plugins-CROGvQUy.js → core-plugins-DSBWcTuX.js} +444 -309
  4. package/dist/core-plugins-DSBWcTuX.js.map +1 -0
  5. package/dist/core.js +2 -2
  6. package/dist/core.mjs +19 -19
  7. package/dist/{enhanced-components-DUw2KrmQ.js → enhanced-components-B_l3cist.js} +2 -2
  8. package/dist/{enhanced-components-DUw2KrmQ.js.map → enhanced-components-B_l3cist.js.map} +1 -1
  9. package/dist/{enhanced-components-DXBCHU0v.cjs → enhanced-components-BspFs9OO.cjs} +2 -2
  10. package/dist/{enhanced-components-DXBCHU0v.cjs.map → enhanced-components-BspFs9OO.cjs.map} +1 -1
  11. package/dist/hooks-BXwI8QG6.cjs +4 -0
  12. package/dist/hooks-BXwI8QG6.cjs.map +1 -0
  13. package/dist/hooks-Bpi-jDiO.js +1816 -0
  14. package/dist/hooks-Bpi-jDiO.js.map +1 -0
  15. package/dist/index.js +2 -2
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.mjs +18 -20
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/{minimal-components-DlRK7Qu_.js → minimal-components-C4z900Ro.js} +297 -298
  20. package/dist/minimal-components-C4z900Ro.js.map +1 -0
  21. package/dist/minimal-components-v4qBp6jv.cjs +2 -0
  22. package/dist/minimal-components-v4qBp6jv.cjs.map +1 -0
  23. package/package.json +1 -1
  24. package/src/components/accessibility/keyboard-help-overlay.tsx +2 -0
  25. package/src/components/enhanced/debug-panel.tsx +1 -1
  26. package/src/components/enhanced/enhanced-media-player.tsx +68 -25
  27. package/src/components/legacy.tsx +6 -6
  28. package/src/components/media-player-video.tsx +5 -12
  29. package/src/components/media-player.tsx +2 -2
  30. package/src/components/ui/enhanced-seek-bar.tsx +2 -2
  31. package/src/components/ui/media-resource-preloader.tsx +21 -23
  32. package/src/components/unified/base-media-player.tsx +22 -10
  33. package/src/components/variants/minimal/AccessibleMinimalPlayer.tsx +58 -38
  34. package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.tsx +6 -6
  35. package/src/core/optimization/bundle-optimizer.tsx +26 -27
  36. package/src/core/plugins/__tests__/registry.test.ts +1 -1
  37. package/src/core/plugins/enhanced-plugin-system.ts +26 -8
  38. package/src/core/plugins/registry.ts +319 -92
  39. package/src/core/plugins/types.ts +21 -3
  40. package/src/core/providers/enhanced-hls-provider.ts +11 -40
  41. package/src/core/providers/lazy-provider.tsx +5 -42
  42. package/src/features/media-session/media-session-manager.ts +4 -26
  43. package/src/features/picture-in-picture/pip-manager.ts +2 -2
  44. package/src/features/playlist/playlist-manager.ts +26 -18
  45. package/src/features/subtitles/subtitle-manager.ts +1 -1
  46. package/src/features/subtitles/subtitle-parser.ts +19 -16
  47. package/src/features/thumbnails/thumbnail-generator.ts +12 -5
  48. package/src/hooks/__tests__/currentTime-fix.test.ts +149 -0
  49. package/src/hooks/accessibility/use-accessibility-preferences.ts +1 -1
  50. package/src/hooks/accessibility/use-focus-management.ts +2 -2
  51. package/src/hooks/accessibility/use-keyboard-shortcuts.ts +2 -2
  52. package/src/hooks/accessibility/use-screen-reader.ts +1 -1
  53. package/src/hooks/core/index.ts +1 -1
  54. package/src/hooks/use-buffer-health.ts +1 -1
  55. package/src/hooks/use-enhanced-media-player.ts +107 -9
  56. package/src/hooks/use-focus-trap.tsx +2 -2
  57. package/src/hooks/use-intelligent-preloading.ts +23 -3
  58. package/src/hooks/use-keyboard-shortcuts.ts +2 -2
  59. package/src/hooks/use-media-player.ts +74 -43
  60. package/src/hooks/use-memory-optimization.ts +15 -15
  61. package/src/hooks/use-smart-preload.ts +1 -2
  62. package/src/hooks/useKeyboardShortcuts.ts +34 -2
  63. package/src/hooks/useVideoPlayer.ts +50 -4
  64. package/src/index-legacy.ts +3 -5
  65. package/src/test/accessibility-utils.ts +7 -7
  66. package/src/test/media-mocks.ts +41 -28
  67. package/src/test/setup.ts +22 -4
  68. package/src/types/index.ts +13 -0
  69. package/dist/core-plugins-CROGvQUy.js.map +0 -1
  70. package/dist/core-plugins-DtsHBOtF.cjs +0 -2
  71. package/dist/core-plugins-DtsHBOtF.cjs.map +0 -1
  72. package/dist/hooks-BW-JjVgP.cjs +0 -4
  73. package/dist/hooks-BW-JjVgP.cjs.map +0 -1
  74. package/dist/hooks-CyX6De5M.js +0 -1693
  75. package/dist/hooks-CyX6De5M.js.map +0 -1
  76. package/dist/minimal-components-Bdcpxav5.cjs +0 -2
  77. package/dist/minimal-components-Bdcpxav5.cjs.map +0 -1
  78. package/dist/minimal-components-DlRK7Qu_.js.map +0 -1
@@ -21,10 +21,25 @@ import {
21
21
  } from "../../core/providers/enhanced-hls-provider"
22
22
  import { useIntelligentPreloading } from "../../hooks/use-intelligent-preloading"
23
23
  import { cn } from "../../lib/utils"
24
- import { MediaPlayerProps, MediaSource } from "../../types"
24
+ import { MediaPlayerProps, type MediaMimeType } from "../../types"
25
25
  import { MediaResourcePreloader } from "../ui/media-resource-preloader"
26
26
 
27
- interface EnhancedMediaPlayerProps extends MediaPlayerProps {
27
+ // Extend MediaMimeType to include HLS and define extended MediaSource
28
+ type ExtendedMediaMimeType = MediaMimeType | "hls"
29
+
30
+ interface ExtendedMediaSource {
31
+ src: string
32
+ type?: ExtendedMediaMimeType
33
+ media?: string
34
+ }
35
+
36
+ interface EnhancedMediaPlayerProps extends Omit<MediaPlayerProps, 'src' | 'onTimeUpdate' | 'onError'> {
37
+ src?: string
38
+ sources?: ExtendedMediaSource[]
39
+ controls?: boolean
40
+ onCanPlay?: () => void
41
+ onTimeUpdate?: () => void
42
+ onError?: (error: MediaError) => void
28
43
  /** Enable enhanced HLS optimization */
29
44
  enableEnhancedHLS?: boolean
30
45
  /** Enable intelligent preloading */
@@ -84,7 +99,18 @@ export const EnhancedMediaPlayer: React.FC<EnhancedMediaPlayerProps> = ({
84
99
  onTimeUpdate,
85
100
  onLoadStart,
86
101
  onCanPlay,
87
- ...props
102
+ onDurationChange,
103
+ onVolumeChange,
104
+ onLoadedData,
105
+ volume,
106
+ preload,
107
+ crossOrigin,
108
+ playbackRates,
109
+ keyboardControls,
110
+ showControls,
111
+ customControls,
112
+ children,
113
+ ...restProps
88
114
  }) => {
89
115
  const videoRef = useRef<HTMLVideoElement>(null)
90
116
  const containerRef = useRef<HTMLDivElement>(null)
@@ -125,20 +151,20 @@ export const EnhancedMediaPlayer: React.FC<EnhancedMediaPlayerProps> = ({
125
151
  const deferredVolume = useDeferredValue(mediaState.volume)
126
152
 
127
153
  // Prepare media sources
128
- const mediaSources = useMemo((): MediaSource[] => {
154
+ const mediaSources = useMemo((): ExtendedMediaSource[] => {
129
155
  if (sources) {
130
156
  return sources
131
157
  }
132
158
  if (src) {
133
159
  const extension = src.split(".").pop()?.toLowerCase()
134
160
  const type = getMediaTypeFromExtension(extension)
135
- return [{ src, type }]
161
+ return [{ src, type: type as ExtendedMediaMimeType }]
136
162
  }
137
163
  return []
138
164
  }, [src, sources])
139
165
 
140
166
  // Intelligent preloading
141
- const preloadingControls = useIntelligentPreloading(mediaSources, {
167
+ const preloadingControls = useIntelligentPreloading(mediaSources as any, {
142
168
  trackUserBehavior: enableIntelligentPreloading,
143
169
  adaptToNetwork: true,
144
170
  strategy: preloadingStrategy,
@@ -147,18 +173,23 @@ export const EnhancedMediaPlayer: React.FC<EnhancedMediaPlayerProps> = ({
147
173
 
148
174
  // Initialize HLS provider
149
175
  const initializeHLS = useCallback(async () => {
150
- if (!videoRef.current || !enableEnhancedHLS) return
176
+ if (!videoRef.current || !enableEnhancedHLS || !mediaSources[0]?.src) return
151
177
 
152
- const hlsConfig = { ...ENHANCED_HLS_DEFAULTS, ...hlsConfig }
153
- const provider = new EnhancedHLSProvider(hlsConfig)
178
+ const mergedHlsConfig = { ...ENHANCED_HLS_DEFAULTS, ...hlsConfig }
179
+ const provider = new EnhancedHLSProvider(mergedHlsConfig)
154
180
  hlsProviderRef.current = provider
155
181
 
156
182
  try {
157
183
  const hls = provider.initialize(videoRef.current, mediaSources[0].src, {
158
- hlsConfig: hlsConfig,
159
- onError: handleMediaError
184
+ autoPlay,
185
+ muted,
186
+ loop,
187
+ preload,
188
+ crossOrigin
160
189
  })
161
190
 
191
+ // Import Hls dynamically to access Events
192
+ const Hls = (await import('hls.js')).default
162
193
  // Setup HLS event listeners
163
194
  hls.on(Hls.Events.LEVEL_SWITCHED, handleQualityChange)
164
195
  hls.on(Hls.Events.FRAG_BUFFERED, handleFragmentBuffered)
@@ -167,7 +198,7 @@ export const EnhancedMediaPlayer: React.FC<EnhancedMediaPlayerProps> = ({
167
198
  console.error("HLS initialization failed:", error)
168
199
  fallbackToNativePlayback()
169
200
  }
170
- }, [enableEnhancedHLS, hlsConfig, mediaSources])
201
+ }, [enableEnhancedHLS, hlsConfig, mediaSources, autoPlay, muted, loop, preload, crossOrigin])
171
202
 
172
203
  // Fallback to native playback
173
204
  const fallbackToNativePlayback = useCallback(() => {
@@ -175,7 +206,7 @@ export const EnhancedMediaPlayer: React.FC<EnhancedMediaPlayerProps> = ({
175
206
 
176
207
  const source = document.createElement("source")
177
208
  source.src = mediaSources[0].src
178
- source.type = getMediaTypeFromUrl(mediaSources[0].src)
209
+ source.type = getMediaTypeFromUrl(mediaSources[0].src) || "video/mp4"
179
210
 
180
211
  videoRef.current.appendChild(source)
181
212
  videoRef.current.load()
@@ -265,11 +296,13 @@ export const EnhancedMediaPlayer: React.FC<EnhancedMediaPlayerProps> = ({
265
296
  }, [])
266
297
 
267
298
  const handleMediaError = useCallback(
268
- (error: MediaError) => {
299
+ (error: MediaError | Error) => {
269
300
  startTransition(() => {
270
- setMediaState((prev) => ({ ...prev, error }))
301
+ setMediaState((prev) => ({ ...prev, error: error as MediaError }))
271
302
  })
272
- onError?.(error)
303
+ // Convert to string for the callback
304
+ const errorMessage = error instanceof Error ? error.message : `Media error code: ${error.code}`
305
+ onError?.(error as MediaError)
273
306
  },
274
307
  [onError]
275
308
  )
@@ -278,7 +311,9 @@ export const EnhancedMediaPlayer: React.FC<EnhancedMediaPlayerProps> = ({
278
311
  (event: any, data: any) => {
279
312
  if (data.fatal) {
280
313
  console.error("Fatal HLS error:", data)
281
- handleMediaError(new Error(`HLS Error: ${data.details}`))
314
+ const mediaError = new Error(`HLS Error: ${data.details}`) as any
315
+ mediaError.code = 4 // MEDIA_ERR_SRC_NOT_SUPPORTED
316
+ handleMediaError(mediaError)
282
317
  }
283
318
  },
284
319
  [handleMediaError]
@@ -348,11 +383,15 @@ export const EnhancedMediaPlayer: React.FC<EnhancedMediaPlayerProps> = ({
348
383
  video.addEventListener("timeupdate", handleTimeUpdate)
349
384
  video.addEventListener("loadedmetadata", handleLoadedMetadata)
350
385
  video.addEventListener("volumechange", handleVolumeChange)
351
- video.addEventListener("loadstart", onLoadStart)
352
- video.addEventListener("canplay", onCanPlay)
386
+ if (onLoadStart) {
387
+ video.addEventListener("loadstart", onLoadStart)
388
+ }
389
+ if (onCanPlay) {
390
+ video.addEventListener("canplay", onCanPlay)
391
+ }
353
392
 
354
393
  // Initialize HLS if needed
355
- if (mediaSources[0].type === "hls" && enableEnhancedHLS) {
394
+ if (mediaSources[0]?.type === "hls" && enableEnhancedHLS) {
356
395
  initializeHLS()
357
396
  } else {
358
397
  fallbackToNativePlayback()
@@ -371,8 +410,12 @@ export const EnhancedMediaPlayer: React.FC<EnhancedMediaPlayerProps> = ({
371
410
  video.removeEventListener("timeupdate", handleTimeUpdate)
372
411
  video.removeEventListener("loadedmetadata", handleLoadedMetadata)
373
412
  video.removeEventListener("volumechange", handleVolumeChange)
374
- video.removeEventListener("loadstart", onLoadStart)
375
- video.removeEventListener("canplay", onCanPlay)
413
+ if (onLoadStart) {
414
+ video.removeEventListener("loadstart", onLoadStart)
415
+ }
416
+ if (onCanPlay) {
417
+ video.removeEventListener("canplay", onCanPlay)
418
+ }
376
419
 
377
420
  hlsProviderRef.current?.destroy()
378
421
  pluginManagerRef.current?.dispose()
@@ -439,15 +482,15 @@ export const EnhancedMediaPlayer: React.FC<EnhancedMediaPlayerProps> = ({
439
482
  <div
440
483
  ref={containerRef}
441
484
  className={cn("relative aspect-video overflow-hidden rounded-lg bg-black", className)}
442
- {...props}>
485
+ {...restProps}>
443
486
  {/* Media Resource Preloader */}
444
487
  {enableIntelligentPreloading && (
445
488
  <MediaResourcePreloader
446
- sources={mediaSources}
489
+ sources={mediaSources as any}
447
490
  enableIntelligentPreloading={true}
448
491
  adaptToNetworkConditions={true}
449
492
  priority="auto"
450
- strategy={preloadingStrategy}
493
+ strategy={preloadingStrategy === "balanced" ? "adaptive" : preloadingStrategy}
451
494
  />
452
495
  )}
453
496
 
@@ -30,7 +30,7 @@ ModernMediaPlayer.displayName = "DeprecatedModernMediaPlayer"
30
30
 
31
31
  export const SimpleVideoPlayer = React.forwardRef<any, any>((props, ref) => {
32
32
  showDeprecationWarning("SimpleVideoPlayer", "VideoPlayer (the primary video player component)")
33
- return <SimpleVideoPlayerBase {...props} ref={ref} />
33
+ return <SimpleVideoPlayerBase {...(props as any)} />
34
34
  })
35
35
 
36
36
  SimpleVideoPlayer.displayName = "DeprecatedSimpleVideoPlayer"
@@ -41,7 +41,7 @@ export const LegacyPlayButton = React.forwardRef<any, any>((props, ref) => {
41
41
  "PlayButton",
42
42
  "Use MediaPlayer compound components or MediaPlayer (all-in-one)"
43
43
  )
44
- return <PlayButton {...props} ref={ref} />
44
+ return <PlayButton {...(props as any)} />
45
45
  })
46
46
 
47
47
  LegacyPlayButton.displayName = "DeprecatedPlayButton"
@@ -51,7 +51,7 @@ export const LegacySeekBar = React.forwardRef<any, any>((props, ref) => {
51
51
  "SeekBar",
52
52
  "Use MediaPlayer compound components or MediaPlayer (all-in-one)"
53
53
  )
54
- return <SeekBar {...props} ref={ref} />
54
+ return <SeekBar {...(props as any)} />
55
55
  })
56
56
 
57
57
  LegacySeekBar.displayName = "DeprecatedSeekBar"
@@ -61,7 +61,7 @@ export const LegacyTimeDisplay = React.forwardRef<any, any>((props, ref) => {
61
61
  "TimeDisplay",
62
62
  "Use MediaPlayer compound components or MediaPlayer (all-in-one)"
63
63
  )
64
- return <TimeDisplay {...props} ref={ref} />
64
+ return <TimeDisplay {...(props as any)} />
65
65
  })
66
66
 
67
67
  LegacyTimeDisplay.displayName = "DeprecatedTimeDisplay"
@@ -71,7 +71,7 @@ export const LegacyVolumeControl = React.forwardRef<any, any>((props, ref) => {
71
71
  "VolumeControl",
72
72
  "Use MediaPlayer compound components or MediaPlayer (all-in-one)"
73
73
  )
74
- return <VolumeControl {...props} ref={ref} />
74
+ return <VolumeControl {...(props as any)} />
75
75
  })
76
76
 
77
77
  LegacyVolumeControl.displayName = "DeprecatedVolumeControl"
@@ -81,7 +81,7 @@ export const LegacyFullscreenButton = React.forwardRef<any, any>((props, ref) =>
81
81
  "FullscreenButton",
82
82
  "Use MediaPlayer compound components or MediaPlayer (all-in-one)"
83
83
  )
84
- return <FullscreenButton {...props} ref={ref} />
84
+ return <FullscreenButton {...(props as any)} />
85
85
  })
86
86
 
87
87
  LegacyFullscreenButton.displayName = "DeprecatedFullscreenButton"
@@ -5,12 +5,12 @@ import { useMediaContext } from "../context/media-context"
5
5
 
6
6
  // Utility function to compose refs
7
7
  function composeRefs<T>(...refs: Array<React.Ref<T> | undefined>) {
8
- return (node: T) => {
8
+ return (node: T | null) => {
9
9
  refs.forEach((ref) => {
10
10
  if (typeof ref === "function") {
11
11
  ref(node)
12
12
  } else if (ref) {
13
- ;(ref as React.MutableRefObject<T>).current = node
13
+ ;(ref as React.MutableRefObject<T | null>).current = node
14
14
  }
15
15
  })
16
16
  }
@@ -29,18 +29,11 @@ export function MediaPlayerVideo({
29
29
  const context = useMediaContext()
30
30
 
31
31
  // Create a ref that will be composed with the context mediaRef when mounted
32
- const [combinedRef, setCombinedRef] = React.useState<React.RefCallback<HTMLVideoElement> | null>(
33
- () => {
34
- // This runs once during initialization to create the combined ref
35
- return composeRefs(context.mediaRef)
36
- }
32
+ const combinedRef = React.useMemo(
33
+ () => composeRefs(context.mediaRef),
34
+ [context.mediaRef]
37
35
  )
38
36
 
39
- // Update combined ref when context changes (but this won't trigger render)
40
- React.useEffect(() => {
41
- setCombinedRef(() => composeRefs(context.mediaRef))
42
- }, [context.mediaRef])
43
-
44
37
  if (asChild) {
45
38
  // When asChild is true, clone the child element and add our props
46
39
  const child = React.Children.only(children) as React.ReactElement
@@ -191,7 +191,7 @@ export const MediaPlayer = forwardRef<HTMLDivElement, MediaPlayerProps>(
191
191
  playsInline
192
192
  x-webkit-airplay="allow"
193
193
  style={{ willChange: "transform" }}>
194
- {renderSources()}
194
+ {renderSources}
195
195
  Your browser does not support the video element.
196
196
  </video>
197
197
  ) : (
@@ -201,7 +201,7 @@ export const MediaPlayer = forwardRef<HTMLDivElement, MediaPlayerProps>(
201
201
  // Performance optimizations
202
202
  preload={preloadStrategy === "eager" ? "auto" : "metadata"}
203
203
  >
204
- {renderSources()}
204
+ {renderSources}
205
205
  Your browser does not support the audio element.
206
206
  </audio>
207
207
  )}
@@ -28,9 +28,9 @@ export const EnhancedSeekBar = forwardRef<HTMLDivElement, SeekBarProps>(
28
28
  const deferredPreviewTime = useDeferredValue(previewTime)
29
29
 
30
30
  // Throttling refs
31
- const seekTimeoutRef = useRef<NodeJS.Timeout>()
31
+ const seekTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined)
32
32
  const lastSeekTime = useRef<number>(0)
33
- const rafId = useRef<number>()
33
+ const rafId = useRef<number | undefined>(undefined)
34
34
 
35
35
  // Memoize expensive calculations
36
36
  const progress = useMemo(
@@ -34,7 +34,7 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
34
34
  priority = "auto",
35
35
  strategy = "adaptive"
36
36
  }) => {
37
- const networkInfoRef = useRef<NetworkInformation | null>(null)
37
+ const networkInfoRef = useRef<any>(null)
38
38
  const userBehaviorRef = useRef<UserBehaviorTracker | null>(null)
39
39
  const preloadingHistoryRef = useRef<Map<string, number>>(new Map())
40
40
 
@@ -56,10 +56,9 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
56
56
 
57
57
  // Preload the content
58
58
  preload(url, {
59
- as: "fetch",
60
- crossOrigin: "anonymous",
61
- priority: "high"
62
- })
59
+ as: "fetch" as any,
60
+ crossOrigin: "anonymous"
61
+ } as any)
63
62
  })
64
63
  }
65
64
 
@@ -92,7 +91,7 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
92
91
  }
93
92
 
94
93
  // Preconnect to media domains
95
- if (shouldPreconnect(source.type, strategy)) {
94
+ if (shouldPreconnect(source.type || "", strategy)) {
96
95
  config.preconnect.push(domain)
97
96
  }
98
97
 
@@ -100,7 +99,7 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
100
99
  if (shouldPreloadBasic(source, priority, strategy)) {
101
100
  config.preload.push({
102
101
  url: source.src,
103
- type: getPreloadType(source.type)
102
+ type: getPreloadType(source.type || "")
104
103
  })
105
104
  }
106
105
 
@@ -133,7 +132,7 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
133
132
 
134
133
  // Strategy-based decision
135
134
  if (strategy === "conservative") {
136
- return priority === "high" && source.type === "hls"
135
+ return priority === "high" && (source.type as string) === "hls"
137
136
  }
138
137
 
139
138
  if (strategy === "aggressive") {
@@ -146,10 +145,10 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
146
145
 
147
146
  if (saveData) return false
148
147
  if (effectiveType === "slow-2g" || effectiveType === "2g") {
149
- return priority === "high" && source.type === "hls"
148
+ return priority === "high" && (source.type as string) === "hls"
150
149
  }
151
150
  if (effectiveType === "3g") {
152
- return ["hls", "m3u8"].includes(source.type)
151
+ return ["hls", "m3u8"].includes(source.type || "")
153
152
  }
154
153
  }
155
154
 
@@ -208,11 +207,10 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
208
207
  const crossOrigin = shouldUseCrossOrigin(url) ? "anonymous" : undefined
209
208
 
210
209
  preload(url, {
211
- as: type,
210
+ as: type as any,
212
211
  crossOrigin,
213
- integrity: getAssetIntegrity(url),
214
- priority
215
- })
212
+ integrity: getAssetIntegrity(url)
213
+ } as any)
216
214
  })
217
215
  }, [filteredPreloadingConfig.preload, priority])
218
216
 
@@ -222,9 +220,9 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
222
220
  const crossOrigin = shouldUseCrossOrigin(url) ? "anonymous" : undefined
223
221
 
224
222
  preinit(url, {
225
- as: type,
223
+ as: type as any,
226
224
  crossOrigin
227
- })
225
+ } as any)
228
226
  })
229
227
  }, [filteredPreloadingConfig.preinit])
230
228
 
@@ -264,7 +262,7 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
264
262
  function shouldPreloadBasic(source: MediaSource, priority: string, strategy: string): boolean {
265
263
  // Basic strategy-based decision without ref access
266
264
  if (strategy === "conservative") {
267
- return priority === "high" && source.type === "hls"
265
+ return priority === "high" && (source.type as string) === "hls"
268
266
  }
269
267
 
270
268
  if (strategy === "aggressive") {
@@ -280,7 +278,7 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
280
278
  priority: string,
281
279
  strategy: string,
282
280
  preloadingHistory: Map<string, number>,
283
- networkInfo: NetworkInformation | null
281
+ networkInfo: any
284
282
  ): boolean {
285
283
  // Check if already preloaded recently
286
284
  const lastPreload = preloadingHistory.get(source.src)
@@ -288,7 +286,7 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
288
286
 
289
287
  // Strategy-based decision
290
288
  if (strategy === "conservative") {
291
- return priority === "high" && source.type === "hls"
289
+ return priority === "high" && (source.type as string) === "hls"
292
290
  }
293
291
 
294
292
  if (strategy === "aggressive") {
@@ -302,7 +300,7 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
302
300
  function shouldAdaptivePreload(
303
301
  source: MediaSource,
304
302
  priority: string,
305
- networkInfo: NetworkInformation | null
303
+ networkInfo: any
306
304
  ): boolean {
307
305
  // Consider network conditions
308
306
  if (networkInfo) {
@@ -310,10 +308,10 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
310
308
 
311
309
  if (saveData) return false
312
310
  if (effectiveType === "slow-2g" || effectiveType === "2g") {
313
- return priority === "high" && source.type === "hls"
311
+ return priority === "high" && (source.type as string) === "hls"
314
312
  }
315
313
  if (effectiveType === "3g") {
316
- return ["hls", "m3u8"].includes(source.type)
314
+ return ["hls", "m3u8"].includes(source.type || "")
317
315
  }
318
316
  }
319
317
 
@@ -329,7 +327,7 @@ export const MediaResourcePreloader: React.FC<MediaResourcePreloaderProps> = ({
329
327
  }
330
328
 
331
329
  function shouldPreinit(source: MediaSource, strategy: string): boolean {
332
- return strategy === "aggressive" && source.type === "hls"
330
+ return strategy === "aggressive" && (source.type as string) === "hls"
333
331
  }
334
332
 
335
333
  function getPreloadType(mediaType: string): string {
@@ -111,9 +111,16 @@ export const BaseMediaPlayer = forwardRef<HTMLDivElement, BaseMediaPlayerProps>(
111
111
 
112
112
  // Determine the media element based on type
113
113
  const MediaElement = useMemo(() => {
114
+ type MediaSource = { src: string; type?: string }
115
+
116
+ const srcString = typeof src === "string"
117
+ ? src
118
+ : Array.isArray(src)
119
+ ? (typeof src[0] === "string" ? src[0] : ((src[0] as unknown) as MediaSource)?.src || "")
120
+ : ""
121
+
114
122
  const commonProps = {
115
- ref: mediaRef,
116
- src,
123
+ src: srcString,
117
124
  className: cn(
118
125
  "w-full h-full",
119
126
  state.isLoading && "opacity-0",
@@ -129,8 +136,8 @@ export const BaseMediaPlayer = forwardRef<HTMLDivElement, BaseMediaPlayerProps>(
129
136
 
130
137
  if (detectedMediaType === "audio") {
131
138
  return (
132
- <audio {...commonProps} controls={!customControls && showControls}>
133
- {src && <source src={typeof src === "string" ? src : src.src} />}
139
+ <audio {...commonProps} ref={mediaRef as React.RefObject<HTMLAudioElement>} controls={!customControls && showControls}>
140
+ {typeof src === "string" && <source src={src} />}
134
141
  Your browser does not support the audio element.
135
142
  </audio>
136
143
  )
@@ -140,14 +147,21 @@ export const BaseMediaPlayer = forwardRef<HTMLDivElement, BaseMediaPlayerProps>(
140
147
  return (
141
148
  <video
142
149
  {...commonProps}
150
+ ref={mediaRef as React.RefObject<HTMLVideoElement>}
143
151
  poster={poster}
144
152
  muted={state.isMuted}
145
153
  playsInline
146
154
  controls={!customControls && showControls}>
147
155
  {Array.isArray(src) ? (
148
- src.map((source, index) => <source key={index} src={source.src} type={source.type} />)
156
+ src.map((source, index) => (
157
+ <source
158
+ key={index}
159
+ src={typeof source === "string" ? source : ((source as unknown) as MediaSource).src}
160
+ type={typeof source === "string" ? undefined : ((source as unknown) as MediaSource).type}
161
+ />
162
+ ))
149
163
  ) : src ? (
150
- <source src={typeof src === "string" ? src : src.src} />
164
+ <source src={srcString} />
151
165
  ) : null}
152
166
  Your browser does not support the video element.
153
167
  </video>
@@ -208,7 +222,7 @@ export const BaseMediaPlayer = forwardRef<HTMLDivElement, BaseMediaPlayerProps>(
208
222
  <div className="p-4 text-center text-white">
209
223
  <div className="mb-2 text-lg text-red-400">⚠️</div>
210
224
  <p className="text-sm">Failed to load media</p>
211
- <p className="mt-1 text-xs opacity-75">{state.error.message}</p>
225
+ <p className="mt-1 text-xs opacity-75">{state.error}</p>
212
226
  </div>
213
227
  </div>
214
228
  )}
@@ -216,9 +230,7 @@ export const BaseMediaPlayer = forwardRef<HTMLDivElement, BaseMediaPlayerProps>(
216
230
  {/* Custom controls or children */}
217
231
  {children && (
218
232
  <div className="pointer-events-none absolute inset-0">
219
- {typeof children === "function"
220
- ? children({ state, controls, mediaType: detectedMediaType })
221
- : children}
233
+ {typeof children === "function" ? children({ state, controls }) : children}
222
234
  </div>
223
235
  )}
224
236