@therealtinhtute/baroiplayer 1.2.1 → 2.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/README.md +90 -71
  2. package/dist/components/icons/index.d.ts +36 -0
  3. package/dist/components/icons/index.d.ts.map +1 -0
  4. package/dist/components/icons/svg-icons/ArrowLeftIcon.d.ts +4 -0
  5. package/dist/components/icons/svg-icons/ArrowLeftIcon.d.ts.map +1 -0
  6. package/dist/components/icons/svg-icons/ArrowRightIcon.d.ts +5 -0
  7. package/dist/components/icons/svg-icons/ArrowRightIcon.d.ts.map +1 -0
  8. package/dist/components/icons/svg-icons/AudioIcon.d.ts +5 -0
  9. package/dist/components/icons/svg-icons/AudioIcon.d.ts.map +1 -0
  10. package/dist/components/icons/svg-icons/BackwardIcon.d.ts +5 -0
  11. package/dist/components/icons/svg-icons/BackwardIcon.d.ts.map +1 -0
  12. package/dist/components/icons/svg-icons/CameraIcon.d.ts +5 -0
  13. package/dist/components/icons/svg-icons/CameraIcon.d.ts.map +1 -0
  14. package/dist/components/icons/svg-icons/CheckIcon.d.ts +5 -0
  15. package/dist/components/icons/svg-icons/CheckIcon.d.ts.map +1 -0
  16. package/dist/components/icons/svg-icons/EnablePiPIcon.d.ts +4 -0
  17. package/dist/components/icons/svg-icons/EnablePiPIcon.d.ts.map +1 -0
  18. package/dist/components/icons/svg-icons/ForwardIcon.d.ts +5 -0
  19. package/dist/components/icons/svg-icons/ForwardIcon.d.ts.map +1 -0
  20. package/dist/components/icons/svg-icons/FullscreenEnterIcon.d.ts +5 -0
  21. package/dist/components/icons/svg-icons/FullscreenEnterIcon.d.ts.map +1 -0
  22. package/dist/components/icons/svg-icons/FullscreenExitIcon.d.ts +5 -0
  23. package/dist/components/icons/svg-icons/FullscreenExitIcon.d.ts.map +1 -0
  24. package/dist/components/icons/svg-icons/LoadingIcon.d.ts +5 -0
  25. package/dist/components/icons/svg-icons/LoadingIcon.d.ts.map +1 -0
  26. package/dist/components/icons/svg-icons/PauseIcon.d.ts +5 -0
  27. package/dist/components/icons/svg-icons/PauseIcon.d.ts.map +1 -0
  28. package/dist/components/icons/svg-icons/PlayIcon.d.ts +5 -0
  29. package/dist/components/icons/svg-icons/PlayIcon.d.ts.map +1 -0
  30. package/dist/components/icons/svg-icons/PlaybackSpeedIcon.d.ts +5 -0
  31. package/dist/components/icons/svg-icons/PlaybackSpeedIcon.d.ts.map +1 -0
  32. package/dist/components/icons/svg-icons/QualityIcon.d.ts +5 -0
  33. package/dist/components/icons/svg-icons/QualityIcon.d.ts.map +1 -0
  34. package/dist/components/icons/svg-icons/SettingsIcon.d.ts +5 -0
  35. package/dist/components/icons/svg-icons/SettingsIcon.d.ts.map +1 -0
  36. package/dist/components/icons/svg-icons/SliderIcon.d.ts +5 -0
  37. package/dist/components/icons/svg-icons/SliderIcon.d.ts.map +1 -0
  38. package/dist/components/icons/svg-icons/SubtitleIcon.d.ts +5 -0
  39. package/dist/components/icons/svg-icons/SubtitleIcon.d.ts.map +1 -0
  40. package/dist/components/icons/svg-icons/SubtitleOffIcon.d.ts +5 -0
  41. package/dist/components/icons/svg-icons/SubtitleOffIcon.d.ts.map +1 -0
  42. package/dist/components/icons/svg-icons/UnPiPIcon.d.ts +4 -0
  43. package/dist/components/icons/svg-icons/UnPiPIcon.d.ts.map +1 -0
  44. package/dist/components/icons/svg-icons/VolumeMutedIcon.d.ts +5 -0
  45. package/dist/components/icons/svg-icons/VolumeMutedIcon.d.ts.map +1 -0
  46. package/dist/components/icons/svg-icons/VolumeOneIcon.d.ts +5 -0
  47. package/dist/components/icons/svg-icons/VolumeOneIcon.d.ts.map +1 -0
  48. package/dist/components/icons/svg-icons/VolumeThreeIcon.d.ts +5 -0
  49. package/dist/components/icons/svg-icons/VolumeThreeIcon.d.ts.map +1 -0
  50. package/dist/components/icons/svg-icons/VolumeTwoIcon.d.ts +5 -0
  51. package/dist/components/icons/svg-icons/VolumeTwoIcon.d.ts.map +1 -0
  52. package/dist/components/variants/gradient/gradient-audio.d.ts +13 -0
  53. package/dist/components/variants/gradient/gradient-audio.d.ts.map +1 -0
  54. package/dist/components/variants/gradient/gradient-controls.d.ts +4 -0
  55. package/dist/components/variants/gradient/gradient-controls.d.ts.map +1 -0
  56. package/dist/components/variants/gradient/gradient-glyphs.d.ts +30 -0
  57. package/dist/components/variants/gradient/gradient-glyphs.d.ts.map +1 -0
  58. package/dist/components/variants/gradient/gradient-video.d.ts +16 -0
  59. package/dist/components/variants/gradient/gradient-video.d.ts.map +1 -0
  60. package/dist/index.css +1 -1
  61. package/dist/index.d.ts +5 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +1 -41
  64. package/dist/index.js.map +1 -1
  65. package/dist/index.mjs +750 -5640
  66. package/dist/index.mjs.map +1 -1
  67. package/dist/package.json +3 -0
  68. package/package.json +110 -114
  69. package/src/components/variants/gradient/gradient-audio.tsx +47 -0
  70. package/src/components/variants/gradient/gradient-controls.tsx +254 -0
  71. package/src/components/variants/gradient/gradient-glyphs.test.tsx +69 -0
  72. package/src/components/variants/gradient/gradient-glyphs.tsx +129 -0
  73. package/src/components/variants/gradient/gradient-skin.css +211 -0
  74. package/src/components/variants/gradient/gradient-video.tsx +70 -0
  75. package/src/index.ts +5 -198
  76. package/src/test/accessibility-utils.ts +0 -59
  77. package/dist/context/media.js +0 -1
  78. package/dist/context/media.mjs +0 -3
  79. package/dist/context/store.js +0 -1
  80. package/dist/context/store.mjs +0 -3
  81. package/dist/context-Bzd5QCKM.cjs +0 -7
  82. package/dist/context-Bzd5QCKM.cjs.map +0 -1
  83. package/dist/context-DD_SH4tT.js +0 -1053
  84. package/dist/context-DD_SH4tT.js.map +0 -1
  85. package/dist/core-events-BRnLMB7s.cjs +0 -2
  86. package/dist/core-events-BRnLMB7s.cjs.map +0 -1
  87. package/dist/core-events-v_mKdj5p.js +0 -417
  88. package/dist/core-events-v_mKdj5p.js.map +0 -1
  89. package/dist/core-plugins-CMBv-yVh.cjs +0 -2
  90. package/dist/core-plugins-CMBv-yVh.cjs.map +0 -1
  91. package/dist/core-plugins-CqCxLkbd.js +0 -754
  92. package/dist/core-plugins-CqCxLkbd.js.map +0 -1
  93. package/dist/core.js +0 -15
  94. package/dist/core.js.map +0 -1
  95. package/dist/core.mjs +0 -960
  96. package/dist/core.mjs.map +0 -1
  97. package/dist/enhanced-components-BwjBqSA1.js +0 -2858
  98. package/dist/enhanced-components-BwjBqSA1.js.map +0 -1
  99. package/dist/enhanced-components-C-ka-XLp.cjs +0 -2
  100. package/dist/enhanced-components-C-ka-XLp.cjs.map +0 -1
  101. package/dist/hooks-B-IIWPJr.js +0 -1842
  102. package/dist/hooks-B-IIWPJr.js.map +0 -1
  103. package/dist/hooks-DcHzmBwA.cjs +0 -4
  104. package/dist/hooks-DcHzmBwA.cjs.map +0 -1
  105. package/dist/minimal-components-BYsMQde5.js +0 -1610
  106. package/dist/minimal-components-BYsMQde5.js.map +0 -1
  107. package/dist/minimal-components-CsxQbDp7.cjs +0 -2
  108. package/dist/minimal-components-CsxQbDp7.cjs.map +0 -1
  109. package/dist/minimal-components.css +0 -1
  110. package/dist/mona-loading.gif +0 -0
  111. package/dist/performance-monitor-DCSijLJg.js +0 -312
  112. package/dist/performance-monitor-DCSijLJg.js.map +0 -1
  113. package/dist/performance-monitor-wNFKmqMr.cjs +0 -2
  114. package/dist/performance-monitor-wNFKmqMr.cjs.map +0 -1
  115. package/dist/rolldown-runtime-BmowowmI.js +0 -14
  116. package/dist/rolldown-runtime-mLOUI7ql.cjs +0 -1
  117. package/dist/utils-D2gQ7c2R.js +0 -64
  118. package/dist/utils-D2gQ7c2R.js.map +0 -1
  119. package/dist/utils-DJaAwiZ9.cjs +0 -2
  120. package/dist/utils-DJaAwiZ9.cjs.map +0 -1
  121. package/dist/utils.js +0 -1
  122. package/dist/utils.mjs +0 -3
  123. package/src/adapters/videojs-adapter.tsx +0 -470
  124. package/src/assets/mona-loading.gif +0 -0
  125. package/src/components/AnimateLoading.tsx +0 -111
  126. package/src/components/LoadingState.tsx +0 -239
  127. package/src/components/__tests__/media-player-accessibility.test.tsx +0 -510
  128. package/src/components/__tests__/media-player-react19.test.tsx +0 -457
  129. package/src/components/accessibility/keyboard-help-overlay.tsx +0 -207
  130. package/src/components/audio-player.tsx +0 -85
  131. package/src/components/basic/index.ts +0 -37
  132. package/src/components/enhanced/advanced-features.tsx +0 -311
  133. package/src/components/enhanced/debug-panel.tsx +0 -448
  134. package/src/components/enhanced/enhanced-controls.tsx +0 -597
  135. package/src/components/enhanced/enhanced-media-player.tsx +0 -566
  136. package/src/components/enhanced/error-handling.tsx +0 -338
  137. package/src/components/enhanced/index.ts +0 -39
  138. package/src/components/enhanced/media-player-enhanced.tsx +0 -383
  139. package/src/components/examples/basic-video-player.tsx +0 -50
  140. package/src/components/examples/custom-controls-example.tsx +0 -63
  141. package/src/components/examples/enhanced-controls-example.tsx +0 -100
  142. package/src/components/examples/enhanced-media-player-example.tsx +0 -302
  143. package/src/components/examples/loading-states-demo.tsx +0 -141
  144. package/src/components/examples/react-19-demo.tsx +0 -349
  145. package/src/components/examples/volume-orientation-demo.tsx +0 -105
  146. package/src/components/icon-demo.tsx +0 -196
  147. package/src/components/legacy.tsx +0 -87
  148. package/src/components/media-metadata-display.tsx +0 -99
  149. package/src/components/media-player-audio.tsx +0 -39
  150. package/src/components/media-player-controls.tsx +0 -223
  151. package/src/components/media-player-error.tsx +0 -163
  152. package/src/components/media-player-fullscreen.tsx +0 -109
  153. package/src/components/media-player-hls.tsx +0 -111
  154. package/src/components/media-player-loading.tsx +0 -76
  155. package/src/components/media-player-play.tsx +0 -75
  156. package/src/components/media-player-root.tsx +0 -338
  157. package/src/components/media-player-seek.tsx +0 -168
  158. package/src/components/media-player-time.tsx +0 -99
  159. package/src/components/media-player-tooltip.tsx +0 -58
  160. package/src/components/media-player-video.tsx +0 -54
  161. package/src/components/media-player-volume.tsx +0 -155
  162. package/src/components/media-player.tsx +0 -292
  163. package/src/components/media-suspense.tsx +0 -344
  164. package/src/components/player-settings-form.tsx +0 -158
  165. package/src/components/react-player-wrapper.tsx +0 -651
  166. package/src/components/simple-video-player.tsx +0 -62
  167. package/src/components/ui/blur-poster.tsx +0 -96
  168. package/src/components/ui/empty-state.tsx +0 -91
  169. package/src/components/ui/enhanced-seek-bar.tsx +0 -254
  170. package/src/components/ui/error-state.tsx +0 -124
  171. package/src/components/ui/fullscreen-button.tsx +0 -81
  172. package/src/components/ui/loading-skeleton.tsx +0 -107
  173. package/src/components/ui/media-resource-preloader.tsx +0 -458
  174. package/src/components/ui/offline-message.tsx +0 -98
  175. package/src/components/ui/play-button.tsx +0 -99
  176. package/src/components/ui/seek-bar.tsx +0 -191
  177. package/src/components/ui/time-display.tsx +0 -61
  178. package/src/components/ui/volume-control.tsx +0 -190
  179. package/src/components/unified/base-media-player.tsx +0 -252
  180. package/src/components/unified/media-player.tsx +0 -75
  181. package/src/components/variants/minimal/AccessibleMinimalPlayer.tsx +0 -587
  182. package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.tsx +0 -573
  183. package/src/components/variants/minimal/MinimalControls.tsx +0 -124
  184. package/src/components/variants/minimal/MinimalLoading.tsx +0 -28
  185. package/src/components/variants/minimal/MinimalMediaPlayer.tsx +0 -318
  186. package/src/components/variants/minimal/MinimalOverlay.tsx +0 -58
  187. package/src/components/variants/minimal/MinimalPlayButton.tsx +0 -56
  188. package/src/components/variants/minimal/MinimalSeekBar.tsx +0 -140
  189. package/src/components/variants/minimal/MinimalVolumeControl.tsx +0 -75
  190. package/src/components/variants/minimal/SimpleMinimalPlayer.tsx +0 -206
  191. package/src/components/variants/minimal/components/CenterPlayButton.tsx +0 -22
  192. package/src/components/variants/minimal/components/ControlBar.tsx +0 -142
  193. package/src/components/variants/minimal/components/EnhancedSettingsMenu.tsx +0 -412
  194. package/src/components/variants/minimal/components/PlaybackControls.tsx +0 -46
  195. package/src/components/variants/minimal/components/RightControls.tsx +0 -164
  196. package/src/components/variants/minimal/components/SeekBar.tsx +0 -127
  197. package/src/components/variants/minimal/components/SettingsDropdown.tsx +0 -68
  198. package/src/components/variants/minimal/components/SubtitleDisplay.tsx +0 -21
  199. package/src/components/variants/minimal/components/TimeDisplay.tsx +0 -15
  200. package/src/components/variants/minimal/components/VideoElement.tsx +0 -35
  201. package/src/components/variants/minimal/components/VolumeControl.tsx +0 -220
  202. package/src/components/variants/minimal/index.ts +0 -23
  203. package/src/components/video-player.tsx +0 -100
  204. package/src/context/__tests__/media-store.test.ts +0 -509
  205. package/src/context/error-handling.ts +0 -398
  206. package/src/context/media-context.tsx +0 -254
  207. package/src/context/media-provider.tsx +0 -264
  208. package/src/context/media-store.ts +0 -387
  209. package/src/context/persistence.ts +0 -462
  210. package/src/core/events/event-system.ts +0 -448
  211. package/src/core/events/hooks.ts +0 -325
  212. package/src/core/events/index.ts +0 -22
  213. package/src/core/events/middleware.ts +0 -286
  214. package/src/core/index.ts +0 -22
  215. package/src/core/optimization/bundle-optimizer.tsx +0 -312
  216. package/src/core/performance/cicd.ts +0 -98
  217. package/src/core/performance/index.ts +0 -38
  218. package/src/core/performance/media-loading-optimizer.ts +0 -545
  219. package/src/core/performance/performance-budgets.ts +0 -437
  220. package/src/core/performance/performance-monitor.tsx +0 -488
  221. package/src/core/performance/performance-testing.ts +0 -461
  222. package/src/core/plugins/__tests__/registry.test.ts +0 -595
  223. package/src/core/plugins/base-plugin.ts +0 -225
  224. package/src/core/plugins/enhanced-plugin-system.ts +0 -435
  225. package/src/core/plugins/examples/analytics-plugin.ts +0 -241
  226. package/src/core/plugins/index.ts +0 -39
  227. package/src/core/plugins/registry.ts +0 -546
  228. package/src/core/plugins/types.ts +0 -169
  229. package/src/core/plugins/utils.ts +0 -317
  230. package/src/core/progressive-loading.tsx +0 -331
  231. package/src/core/providers/enhanced-hls-provider.ts +0 -307
  232. package/src/core/providers/lazy-provider.tsx +0 -14
  233. package/src/core/providers/service-provider.tsx +0 -164
  234. package/src/core/utils.tsx +0 -34
  235. package/src/features/media-session/media-session-manager.ts +0 -411
  236. package/src/features/picture-in-picture/pip-manager.ts +0 -428
  237. package/src/features/playlist/playlist-manager.ts +0 -626
  238. package/src/features/subtitles/subtitle-manager.ts +0 -435
  239. package/src/features/subtitles/subtitle-parser.ts +0 -284
  240. package/src/features/thumbnails/thumbnail-generator.ts +0 -528
  241. package/src/hooks/__tests__/currentTime-fix.test.ts +0 -149
  242. package/src/hooks/__tests__/use-media-player.test.ts +0 -712
  243. package/src/hooks/__tests__/use-media-state.test.tsx +0 -316
  244. package/src/hooks/accessibility/index.ts +0 -27
  245. package/src/hooks/accessibility/use-accessibility-preferences.ts +0 -190
  246. package/src/hooks/accessibility/use-focus-management.ts +0 -183
  247. package/src/hooks/accessibility/use-keyboard-shortcuts.ts +0 -152
  248. package/src/hooks/accessibility/use-screen-reader.ts +0 -212
  249. package/src/hooks/core/index.ts +0 -47
  250. package/src/hooks/legacy.ts +0 -21
  251. package/src/hooks/use-buffer-health.ts +0 -218
  252. package/src/hooks/use-enhanced-media-player.ts +0 -575
  253. package/src/hooks/use-focus-trap.tsx +0 -162
  254. package/src/hooks/use-intelligent-preloading.ts +0 -387
  255. package/src/hooks/use-keyboard-controls.ts +0 -115
  256. package/src/hooks/use-keyboard-shortcuts.ts +0 -255
  257. package/src/hooks/use-media-actions.ts +0 -184
  258. package/src/hooks/use-media-metadata.ts +0 -91
  259. package/src/hooks/use-media-optimistic.ts +0 -264
  260. package/src/hooks/use-media-player.ts +0 -343
  261. package/src/hooks/use-media-state.ts +0 -194
  262. package/src/hooks/use-memory-optimization.ts +0 -360
  263. package/src/hooks/use-network-status.ts +0 -124
  264. package/src/hooks/use-optimistic-controls.ts +0 -95
  265. package/src/hooks/use-optimized-media.ts +0 -283
  266. package/src/hooks/use-smart-preload.ts +0 -229
  267. package/src/hooks/use-touch-gestures.ts +0 -461
  268. package/src/hooks/useEnhancedSubtitles.ts +0 -258
  269. package/src/hooks/useKeyboardShortcuts.ts +0 -106
  270. package/src/hooks/useMediaControls.ts +0 -52
  271. package/src/hooks/useScreenshot.ts +0 -77
  272. package/src/hooks/useSubtitles.ts +0 -91
  273. package/src/hooks/useVideoPlayer.ts +0 -278
  274. package/src/icons/components/FullscreenIcon.tsx +0 -36
  275. package/src/icons/components/SettingsIcon.tsx +0 -37
  276. package/src/icons/components/animated/LoadingIcon.tsx +0 -27
  277. package/src/icons/components/animated/PlayPauseIcon.tsx +0 -42
  278. package/src/icons/components/media/PauseIcon.tsx +0 -38
  279. package/src/icons/components/media/PlayIcon.tsx +0 -37
  280. package/src/icons/components/volume/VolumeIcon.tsx +0 -38
  281. package/src/icons/components/volume/VolumeOffIcon.tsx +0 -38
  282. package/src/icons/index.ts +0 -56
  283. package/src/icons/provider.tsx +0 -58
  284. package/src/icons/types.ts +0 -60
  285. package/src/index-enhanced.ts +0 -35
  286. package/src/index-legacy.ts +0 -324
  287. package/src/index.css +0 -102
  288. package/src/lib/__tests__/async-utils.test.ts +0 -291
  289. package/src/lib/async-utils.ts +0 -194
  290. package/src/lib/deprecation.ts +0 -51
  291. package/src/lib/format-time.ts +0 -37
  292. package/src/lib/index.ts +0 -4
  293. package/src/lib/utils.ts +0 -6
  294. package/src/styles/globals.css +0 -462
  295. package/src/styles/minimal-player.css +0 -621
  296. package/src/styles/pixel-art.css +0 -41
  297. package/src/styles/videojs.css +0 -100
  298. package/src/types/assets.d.ts +0 -29
  299. package/src/types/events.ts +0 -47
  300. package/src/types/formats.ts +0 -79
  301. package/src/types/index.ts +0 -203
  302. package/src/types/videojs-plugins.d.ts +0 -14
@@ -1,566 +0,0 @@
1
- /**
2
- * Enhanced Media Player with all optimizations applied
3
- * Integrates React 19 features, HLS optimization, and intelligent preloading
4
- */
5
-
6
- import React, {
7
- useRef,
8
- useState,
9
- useEffect,
10
- useCallback,
11
- useMemo,
12
- useTransition,
13
- useOptimistic,
14
- useDeferredValue,
15
- Suspense
16
- } from "react"
17
- import { EnhancedPluginManager } from "../../core/plugins/enhanced-plugin-system"
18
- import {
19
- ENHANCED_HLS_DEFAULTS,
20
- EnhancedHLSProvider
21
- } from "../../core/providers/enhanced-hls-provider"
22
- import { useIntelligentPreloading } from "../../hooks/use-intelligent-preloading"
23
- import { cn } from "../../lib/utils"
24
- import { MediaPlayerProps, type MediaMimeType } from "../../types"
25
- import { MediaResourcePreloader } from "../ui/media-resource-preloader"
26
-
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
43
- /** Enable enhanced HLS optimization */
44
- enableEnhancedHLS?: boolean
45
- /** Enable intelligent preloading */
46
- enableIntelligentPreloading?: boolean
47
- /** Enable performance monitoring */
48
- enablePerformanceMonitoring?: boolean
49
- /** Custom HLS configuration */
50
- hlsConfig?: any
51
- /** Preloading strategy */
52
- preloadingStrategy?: "conservative" | "balanced" | "aggressive"
53
- /** Show performance debug panel (development only) */
54
- showDebugPanel?: boolean
55
- }
56
-
57
- interface MediaState {
58
- isPlaying: boolean
59
- currentTime: number
60
- duration: number
61
- volume: number
62
- isMuted: boolean
63
- isFullscreen: boolean
64
- isBuffering: boolean
65
- quality: number
66
- error: MediaError | null
67
- }
68
-
69
- interface PerformanceMetrics {
70
- fps: number
71
- memoryUsage: number
72
- bufferHealth: number
73
- networkBandwidth: number
74
- droppedFrames: number
75
- }
76
-
77
- /**
78
- * Enhanced Media Player Component
79
- */
80
- export const EnhancedMediaPlayer: React.FC<EnhancedMediaPlayerProps> = ({
81
- src,
82
- sources,
83
- poster,
84
- autoPlay = false,
85
- muted = false,
86
- loop = false,
87
- controls = true,
88
- className,
89
- enableEnhancedHLS = true,
90
- enableIntelligentPreloading = true,
91
- enablePerformanceMonitoring = process.env.NODE_ENV === "development",
92
- hlsConfig = {},
93
- preloadingStrategy = "balanced",
94
- showDebugPanel = false,
95
- onPlay,
96
- onPause,
97
- onEnded,
98
- onError,
99
- onTimeUpdate,
100
- onLoadStart,
101
- onCanPlay,
102
- onDurationChange,
103
- onVolumeChange,
104
- onLoadedData,
105
- volume,
106
- preload,
107
- crossOrigin,
108
- playbackRates,
109
- keyboardControls,
110
- showControls,
111
- customControls,
112
- children,
113
- ...restProps
114
- }) => {
115
- const videoRef = useRef<HTMLVideoElement>(null)
116
- const containerRef = useRef<HTMLDivElement>(null)
117
- const hlsProviderRef = useRef<EnhancedHLSProvider | null>(null)
118
- const pluginManagerRef = useRef<EnhancedPluginManager | null>(null)
119
-
120
- // React 19 concurrent features
121
- const [isPending, startTransition] = useTransition()
122
- const optimisticState = useOptimistic(
123
- { isPlaying: false, volume: 1 },
124
- (state, update: Partial<MediaState>) => ({ ...state, ...update })
125
- )
126
-
127
- // Media state
128
- const [mediaState, setMediaState] = useState<MediaState>({
129
- isPlaying: false,
130
- currentTime: 0,
131
- duration: 0,
132
- volume: 1,
133
- isMuted: muted,
134
- isFullscreen: false,
135
- isBuffering: false,
136
- quality: 0,
137
- error: null
138
- })
139
-
140
- // Performance metrics
141
- const [performanceMetrics, setPerformanceMetrics] = useState<PerformanceMetrics>({
142
- fps: 0,
143
- memoryUsage: 0,
144
- bufferHealth: 0,
145
- networkBandwidth: 0,
146
- droppedFrames: 0
147
- })
148
-
149
- // Deferred values for non-critical updates
150
- const deferredCurrentTime = useDeferredValue(mediaState.currentTime)
151
- const deferredVolume = useDeferredValue(mediaState.volume)
152
-
153
- // Prepare media sources
154
- const mediaSources = useMemo((): ExtendedMediaSource[] => {
155
- if (sources) {
156
- return sources
157
- }
158
- if (src) {
159
- const extension = src.split(".").pop()?.toLowerCase()
160
- const type = getMediaTypeFromExtension(extension)
161
- return [{ src, type: type as ExtendedMediaMimeType }]
162
- }
163
- return []
164
- }, [src, sources])
165
-
166
- // Intelligent preloading
167
- const preloadingControls = useIntelligentPreloading(mediaSources as any, {
168
- trackUserBehavior: enableIntelligentPreloading,
169
- adaptToNetwork: true,
170
- strategy: preloadingStrategy,
171
- maxPreloadItems: 3
172
- })
173
-
174
- // Initialize HLS provider
175
- const initializeHLS = useCallback(async () => {
176
- if (!videoRef.current || !enableEnhancedHLS || !mediaSources[0]?.src) return
177
-
178
- const mergedHlsConfig = { ...ENHANCED_HLS_DEFAULTS, ...hlsConfig }
179
- const provider = new EnhancedHLSProvider(mergedHlsConfig)
180
- hlsProviderRef.current = provider
181
-
182
- try {
183
- const hls = provider.initialize(videoRef.current, mediaSources[0].src, {
184
- autoPlay,
185
- muted,
186
- loop,
187
- preload,
188
- crossOrigin
189
- })
190
-
191
- // Import Hls dynamically to access Events
192
- const Hls = (await import('hls.js')).default
193
- // Setup HLS event listeners
194
- hls.on(Hls.Events.LEVEL_SWITCHED, handleQualityChange)
195
- hls.on(Hls.Events.FRAG_BUFFERED, handleFragmentBuffered)
196
- hls.on(Hls.Events.ERROR, handleHLSError)
197
- } catch (error) {
198
- console.error("HLS initialization failed:", error)
199
- fallbackToNativePlayback()
200
- }
201
- }, [enableEnhancedHLS, hlsConfig, mediaSources, autoPlay, muted, loop, preload, crossOrigin])
202
-
203
- // Fallback to native playback
204
- const fallbackToNativePlayback = useCallback(() => {
205
- if (!videoRef.current || !mediaSources[0]) return
206
-
207
- const source = document.createElement("source")
208
- source.src = mediaSources[0].src
209
- source.type = getMediaTypeFromUrl(mediaSources[0].src) || "video/mp4"
210
-
211
- videoRef.current.appendChild(source)
212
- videoRef.current.load()
213
- }, [mediaSources])
214
-
215
- // Media event handlers
216
- const handlePlay = useCallback(() => {
217
- startTransition(() => {
218
- setMediaState((prev) => ({ ...prev, isPlaying: true }))
219
- })
220
- onPlay?.()
221
- }, [onPlay])
222
-
223
- const handlePause = useCallback(() => {
224
- startTransition(() => {
225
- setMediaState((prev) => ({ ...prev, isPlaying: false }))
226
- })
227
- onPause?.()
228
- }, [onPause])
229
-
230
- const handleEnded = useCallback(() => {
231
- startTransition(() => {
232
- setMediaState((prev) => ({ ...prev, isPlaying: false }))
233
- })
234
- onEnded?.()
235
- }, [onEnded])
236
-
237
- const handleTimeUpdate = useCallback(() => {
238
- if (!videoRef.current) return
239
-
240
- startTransition(() => {
241
- setMediaState((prev) => ({
242
- ...prev,
243
- currentTime: videoRef.current!.currentTime
244
- }))
245
- })
246
- onTimeUpdate?.()
247
- }, [onTimeUpdate])
248
-
249
- const handleLoadedMetadata = useCallback(() => {
250
- if (!videoRef.current) return
251
-
252
- startTransition(() => {
253
- setMediaState((prev) => ({
254
- ...prev,
255
- duration: videoRef.current!.duration
256
- }))
257
- })
258
- }, [])
259
-
260
- const handleVolumeChange = useCallback(() => {
261
- if (!videoRef.current) return
262
-
263
- startTransition(() => {
264
- setMediaState((prev) => ({
265
- ...prev,
266
- volume: videoRef.current!.volume,
267
- isMuted: videoRef.current!.muted
268
- }))
269
- })
270
- }, [])
271
-
272
- const handleQualityChange = useCallback((event: any, data: any) => {
273
- startTransition(() => {
274
- setMediaState((prev) => ({ ...prev, quality: data.level }))
275
- })
276
- }, [])
277
-
278
- const handleFragmentBuffered = useCallback(() => {
279
- // Update buffer health
280
- if (videoRef.current) {
281
- const buffered = videoRef.current.buffered
282
- const currentTime = videoRef.current.currentTime
283
- let bufferHealth = 0
284
-
285
- for (let i = 0; i < buffered.length; i++) {
286
- const start = buffered.start(i)
287
- const end = buffered.end(i)
288
- if (start <= currentTime && end > currentTime) {
289
- bufferHealth = end - currentTime
290
- break
291
- }
292
- }
293
-
294
- setPerformanceMetrics((prev) => ({ ...prev, bufferHealth }))
295
- }
296
- }, [])
297
-
298
- const handleMediaError = useCallback(
299
- (error: MediaError | Error) => {
300
- startTransition(() => {
301
- setMediaState((prev) => ({ ...prev, error: error as MediaError }))
302
- })
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)
306
- },
307
- [onError]
308
- )
309
-
310
- const handleHLSError = useCallback(
311
- (event: any, data: any) => {
312
- if (data.fatal) {
313
- console.error("Fatal HLS error:", data)
314
- const mediaError = new Error(`HLS Error: ${data.details}`) as any
315
- mediaError.code = 4 // MEDIA_ERR_SRC_NOT_SUPPORTED
316
- handleMediaError(mediaError)
317
- }
318
- },
319
- [handleMediaError]
320
- )
321
-
322
- // Performance monitoring
323
- useEffect(() => {
324
- if (!enablePerformanceMonitoring) return
325
-
326
- let frameCount = 0
327
- let lastTime = performance.now()
328
-
329
- const measureFPS = () => {
330
- frameCount++
331
- const currentTime = performance.now()
332
-
333
- if (currentTime - lastTime >= 1000) {
334
- const fps = Math.round((frameCount * 1000) / (currentTime - lastTime))
335
-
336
- setPerformanceMetrics((prev) => ({ ...prev, fps }))
337
-
338
- frameCount = 0
339
- lastTime = currentTime
340
- }
341
-
342
- if (videoRef.current && !videoRef.current.paused) {
343
- requestAnimationFrame(measureFPS)
344
- }
345
- }
346
-
347
- if (videoRef.current) {
348
- videoRef.current.addEventListener("play", measureFPS)
349
- }
350
-
351
- return () => {
352
- if (videoRef.current) {
353
- videoRef.current.removeEventListener("play", measureFPS)
354
- }
355
- }
356
- }, [enablePerformanceMonitoring])
357
-
358
- // Memory monitoring
359
- useEffect(() => {
360
- if (!enablePerformanceMonitoring || !("memory" in performance)) return
361
-
362
- const interval = setInterval(() => {
363
- const memory = (performance as any).memory
364
- setPerformanceMetrics((prev) => ({
365
- ...prev,
366
- memoryUsage: memory.usedJSHeapSize / 1024 / 1024 // MB
367
- }))
368
- }, 2000)
369
-
370
- return () => clearInterval(interval)
371
- }, [enablePerformanceMonitoring])
372
-
373
- // Initialize player
374
- useEffect(() => {
375
- if (!videoRef.current || mediaSources.length === 0) return
376
-
377
- // Setup native event listeners
378
- const video = videoRef.current
379
-
380
- video.addEventListener("play", handlePlay)
381
- video.addEventListener("pause", handlePause)
382
- video.addEventListener("ended", handleEnded)
383
- video.addEventListener("timeupdate", handleTimeUpdate)
384
- video.addEventListener("loadedmetadata", handleLoadedMetadata)
385
- video.addEventListener("volumechange", handleVolumeChange)
386
- if (onLoadStart) {
387
- video.addEventListener("loadstart", onLoadStart)
388
- }
389
- if (onCanPlay) {
390
- video.addEventListener("canplay", onCanPlay)
391
- }
392
-
393
- // Initialize HLS if needed
394
- if (mediaSources[0]?.type === "hls" && enableEnhancedHLS) {
395
- initializeHLS()
396
- } else {
397
- fallbackToNativePlayback()
398
- }
399
-
400
- // Initialize plugin manager
401
- if (video) {
402
- pluginManagerRef.current = new EnhancedPluginManager(video as any)
403
- }
404
-
405
- return () => {
406
- // Cleanup
407
- video.removeEventListener("play", handlePlay)
408
- video.removeEventListener("pause", handlePause)
409
- video.removeEventListener("ended", handleEnded)
410
- video.removeEventListener("timeupdate", handleTimeUpdate)
411
- video.removeEventListener("loadedmetadata", handleLoadedMetadata)
412
- video.removeEventListener("volumechange", handleVolumeChange)
413
- if (onLoadStart) {
414
- video.removeEventListener("loadstart", onLoadStart)
415
- }
416
- if (onCanPlay) {
417
- video.removeEventListener("canplay", onCanPlay)
418
- }
419
-
420
- hlsProviderRef.current?.destroy()
421
- pluginManagerRef.current?.dispose()
422
- }
423
- }, [
424
- mediaSources,
425
- enableEnhancedHLS,
426
- handlePlay,
427
- handlePause,
428
- handleEnded,
429
- handleTimeUpdate,
430
- handleLoadedMetadata,
431
- handleVolumeChange,
432
- onLoadStart,
433
- onCanPlay,
434
- initializeHLS,
435
- fallbackToNativePlayback
436
- ])
437
-
438
- // Auto-play handling
439
- useEffect(() => {
440
- if (autoPlay && videoRef.current) {
441
- videoRef.current.play().catch((error) => {
442
- console.warn("Auto-play failed:", error)
443
- })
444
- }
445
- }, [autoPlay])
446
-
447
- // Render debug panel
448
- const DebugPanel = useMemo(() => {
449
- if (!showDebugPanel || process.env.NODE_ENV !== "development") return null
450
-
451
- return (
452
- <div className="fixed top-4 right-4 z-50 rounded-lg bg-black/80 p-4 font-mono text-white text-xs">
453
- <h3 className="mb-2 font-bold">Performance Metrics</h3>
454
- <div>FPS: {performanceMetrics.fps}</div>
455
- <div>Memory: {performanceMetrics.memoryUsage.toFixed(2)} MB</div>
456
- <div>Buffer: {performanceMetrics.bufferHealth.toFixed(2)}s</div>
457
- <div>
458
- Time: {deferredCurrentTime.toFixed(2)}s / {mediaState.duration.toFixed(2)}s
459
- </div>
460
- <div>Volume: {Math.round(deferredVolume * 100)}%</div>
461
- <div>Quality: {mediaState.quality}</div>
462
- <div>Playing: {mediaState.isPlaying ? "Yes" : "No"}</div>
463
- <div>Buffering: {isPending ? "Yes" : "No"}</div>
464
-
465
- <h3 className="mt-3 mb-2 font-bold">Preloading Stats</h3>
466
- <div>Preloaded: {preloadingControls.getStats().preloadedItems}</div>
467
- <div>Engagement: {preloadingControls.getStats().engagementScore.toFixed(1)}%</div>
468
- <div>Queue: {preloadingControls.getStats().queueLength}</div>
469
- </div>
470
- )
471
- }, [
472
- showDebugPanel,
473
- performanceMetrics,
474
- deferredCurrentTime,
475
- deferredVolume,
476
- mediaState,
477
- isPending,
478
- preloadingControls
479
- ])
480
-
481
- return (
482
- <div
483
- ref={containerRef}
484
- className={cn("relative aspect-video overflow-hidden rounded-lg bg-black", className)}
485
- {...restProps}>
486
- {/* Media Resource Preloader */}
487
- {enableIntelligentPreloading && (
488
- <MediaResourcePreloader
489
- sources={mediaSources as any}
490
- enableIntelligentPreloading={true}
491
- adaptToNetworkConditions={true}
492
- priority="auto"
493
- strategy={preloadingStrategy === "balanced" ? "adaptive" : preloadingStrategy}
494
- />
495
- )}
496
-
497
- {/* Video Element */}
498
- <video
499
- ref={videoRef}
500
- className="h-full w-full"
501
- poster={poster}
502
- muted={muted}
503
- loop={loop}
504
- playsInline
505
- preload="metadata"
506
- crossOrigin="anonymous"
507
- />
508
-
509
- {/* Loading State */}
510
- {isPending && (
511
- <div className="absolute inset-0 flex items-center justify-center bg-black/50">
512
- <div className="h-8 w-8 animate-spin rounded-full border-2 border-white border-t-transparent" />
513
- </div>
514
- )}
515
-
516
- {/* Error State */}
517
- {mediaState.error && (
518
- <div className="absolute inset-0 flex items-center justify-center bg-black/75">
519
- <div className="p-4 text-center text-white">
520
- <h3 className="mb-2 font-semibold text-lg">Playback Error</h3>
521
- <p className="text-sm opacity-75">{mediaState.error.message}</p>
522
- </div>
523
- </div>
524
- )}
525
-
526
- {/* Controls Slot */}
527
- {controls && (
528
- <div className="absolute right-0 bottom-0 left-0">
529
- {/* Controls will be rendered here */}
530
- </div>
531
- )}
532
-
533
- {/* Debug Panel */}
534
- {DebugPanel}
535
- </div>
536
- )
537
- }
538
-
539
- // Helper functions
540
- function getMediaTypeFromExtension(extension?: string): string {
541
- switch (extension) {
542
- case "mp4":
543
- return "video/mp4"
544
- case "webm":
545
- return "video/webm"
546
- case "ogg":
547
- return "video/ogg"
548
- case "mp3":
549
- return "audio/mp3"
550
- case "wav":
551
- return "audio/wav"
552
- case "m3u8":
553
- return "hls"
554
- case "hls":
555
- return "hls"
556
- default:
557
- return "video/mp4"
558
- }
559
- }
560
-
561
- function getMediaTypeFromUrl(url: string): string {
562
- const extension = url.split(".").pop()?.toLowerCase()
563
- return getMediaTypeFromExtension(extension)
564
- }
565
-
566
- export default EnhancedMediaPlayer