@therealtinhtute/baroiplayer 1.0.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 (244) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +384 -0
  3. package/dist/context/media.js +2 -0
  4. package/dist/context/media.js.map +1 -0
  5. package/dist/context/media.mjs +15 -0
  6. package/dist/context/media.mjs.map +1 -0
  7. package/dist/context/store.js +2 -0
  8. package/dist/context/store.js.map +1 -0
  9. package/dist/context/store.mjs +5 -0
  10. package/dist/context/store.mjs.map +1 -0
  11. package/dist/context-BMteAJDN.js +1140 -0
  12. package/dist/context-BMteAJDN.js.map +1 -0
  13. package/dist/context-DCJ_scmO.cjs +23 -0
  14. package/dist/context-DCJ_scmO.cjs.map +1 -0
  15. package/dist/core-events-B5W_j8yU.js +480 -0
  16. package/dist/core-events-B5W_j8yU.js.map +1 -0
  17. package/dist/core-events-CN0-Vhhq.cjs +2 -0
  18. package/dist/core-events-CN0-Vhhq.cjs.map +1 -0
  19. package/dist/core-plugins-Bq9KLany.js +696 -0
  20. package/dist/core-plugins-Bq9KLany.js.map +1 -0
  21. package/dist/core-plugins-CPDSHMiQ.cjs +2 -0
  22. package/dist/core-plugins-CPDSHMiQ.cjs.map +1 -0
  23. package/dist/core.js +37 -0
  24. package/dist/core.js.map +1 -0
  25. package/dist/core.mjs +1217 -0
  26. package/dist/core.mjs.map +1 -0
  27. package/dist/enhanced-components-DHv0MFvG.js +1073 -0
  28. package/dist/enhanced-components-DHv0MFvG.js.map +1 -0
  29. package/dist/enhanced-components-DTIObgB7.cjs +2 -0
  30. package/dist/enhanced-components-DTIObgB7.cjs.map +1 -0
  31. package/dist/hooks-C_r8wexn.cjs +4 -0
  32. package/dist/hooks-C_r8wexn.cjs.map +1 -0
  33. package/dist/hooks-Da2wVXlF.js +1630 -0
  34. package/dist/hooks-Da2wVXlF.js.map +1 -0
  35. package/dist/index.css +1 -0
  36. package/dist/index.js +112 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/index.mjs +6126 -0
  39. package/dist/index.mjs.map +1 -0
  40. package/dist/minimal-components-DSq5sQpy.js +2002 -0
  41. package/dist/minimal-components-DSq5sQpy.js.map +1 -0
  42. package/dist/minimal-components-DflWiihN.cjs +2 -0
  43. package/dist/minimal-components-DflWiihN.cjs.map +1 -0
  44. package/dist/minimal-components.css +1 -0
  45. package/dist/mona-loading.gif +0 -0
  46. package/dist/performance-monitor-CUW6f5ll.cjs +2 -0
  47. package/dist/performance-monitor-CUW6f5ll.cjs.map +1 -0
  48. package/dist/performance-monitor-rMW1RgV3.js +302 -0
  49. package/dist/performance-monitor-rMW1RgV3.js.map +1 -0
  50. package/dist/utils-BnscpYYd.js +2798 -0
  51. package/dist/utils-BnscpYYd.js.map +1 -0
  52. package/dist/utils-D_czS_0K.cjs +9 -0
  53. package/dist/utils-D_czS_0K.cjs.map +1 -0
  54. package/dist/utils.js +2 -0
  55. package/dist/utils.js.map +1 -0
  56. package/dist/utils.mjs +7 -0
  57. package/dist/utils.mjs.map +1 -0
  58. package/package.json +114 -0
  59. package/src/adapters/videojs-adapter.tsx +470 -0
  60. package/src/assets/mona-loading.gif +0 -0
  61. package/src/components/AnimateLoading.tsx +115 -0
  62. package/src/components/LoadingState.tsx +248 -0
  63. package/src/components/accessibility/keyboard-help-overlay.tsx +213 -0
  64. package/src/components/audio-player.tsx +85 -0
  65. package/src/components/basic/index.ts +37 -0
  66. package/src/components/enhanced/advanced-features.tsx +316 -0
  67. package/src/components/enhanced/debug-panel.tsx +422 -0
  68. package/src/components/enhanced/enhanced-controls.tsx +600 -0
  69. package/src/components/enhanced/enhanced-media-player.tsx +509 -0
  70. package/src/components/enhanced/error-handling.tsx +345 -0
  71. package/src/components/enhanced/index.ts +39 -0
  72. package/src/components/enhanced/media-player-enhanced.tsx +349 -0
  73. package/src/components/examples/basic-video-player.tsx +55 -0
  74. package/src/components/examples/custom-controls-example.tsx +63 -0
  75. package/src/components/examples/enhanced-controls-example.tsx +114 -0
  76. package/src/components/examples/enhanced-media-player-example.tsx +293 -0
  77. package/src/components/examples/loading-states-demo.tsx +142 -0
  78. package/src/components/examples/react-19-demo.tsx +381 -0
  79. package/src/components/examples/volume-orientation-demo.tsx +114 -0
  80. package/src/components/icon-demo.tsx +209 -0
  81. package/src/components/icons/index.tsx +166 -0
  82. package/src/components/icons/svg-icons/ArrowLeftIcon.tsx +18 -0
  83. package/src/components/icons/svg-icons/ArrowRightIcon.tsx +18 -0
  84. package/src/components/icons/svg-icons/AudioIcon.tsx +22 -0
  85. package/src/components/icons/svg-icons/BackwardIcon.tsx +12 -0
  86. package/src/components/icons/svg-icons/CameraIcon.tsx +19 -0
  87. package/src/components/icons/svg-icons/CheckIcon.tsx +19 -0
  88. package/src/components/icons/svg-icons/EnablePiPIcon.tsx +17 -0
  89. package/src/components/icons/svg-icons/ForwardIcon.tsx +12 -0
  90. package/src/components/icons/svg-icons/FullscreenEnterIcon.tsx +23 -0
  91. package/src/components/icons/svg-icons/FullscreenExitIcon.tsx +23 -0
  92. package/src/components/icons/svg-icons/LoadingIcon.tsx +32 -0
  93. package/src/components/icons/svg-icons/PauseIcon.tsx +23 -0
  94. package/src/components/icons/svg-icons/PlayIcon.tsx +21 -0
  95. package/src/components/icons/svg-icons/PlaybackSpeedIcon.tsx +23 -0
  96. package/src/components/icons/svg-icons/QualityIcon.tsx +21 -0
  97. package/src/components/icons/svg-icons/SettingsIcon.tsx +12 -0
  98. package/src/components/icons/svg-icons/SliderIcon.tsx +21 -0
  99. package/src/components/icons/svg-icons/SubtitleIcon.tsx +21 -0
  100. package/src/components/icons/svg-icons/SubtitleOffIcon.tsx +25 -0
  101. package/src/components/icons/svg-icons/UnPiPIcon.tsx +17 -0
  102. package/src/components/icons/svg-icons/VolumeMutedIcon.tsx +16 -0
  103. package/src/components/icons/svg-icons/VolumeOneIcon.tsx +22 -0
  104. package/src/components/icons/svg-icons/VolumeThreeIcon.tsx +16 -0
  105. package/src/components/icons/svg-icons/VolumeTwoIcon.tsx +16 -0
  106. package/src/components/legacy.tsx +93 -0
  107. package/src/components/media-metadata-display.tsx +100 -0
  108. package/src/components/media-player-audio.tsx +39 -0
  109. package/src/components/media-player-controls.tsx +226 -0
  110. package/src/components/media-player-error.tsx +163 -0
  111. package/src/components/media-player-fullscreen.tsx +109 -0
  112. package/src/components/media-player-hls.tsx +111 -0
  113. package/src/components/media-player-loading.tsx +76 -0
  114. package/src/components/media-player-play.tsx +75 -0
  115. package/src/components/media-player-root.tsx +340 -0
  116. package/src/components/media-player-seek.tsx +168 -0
  117. package/src/components/media-player-time.tsx +99 -0
  118. package/src/components/media-player-tooltip.tsx +58 -0
  119. package/src/components/media-player-video.tsx +39 -0
  120. package/src/components/media-player-volume.tsx +155 -0
  121. package/src/components/media-player.tsx +257 -0
  122. package/src/components/media-suspense.tsx +362 -0
  123. package/src/components/player-settings-form.tsx +163 -0
  124. package/src/components/react-player-wrapper.tsx +651 -0
  125. package/src/components/simple-video-player.tsx +60 -0
  126. package/src/components/ui/enhanced-seek-bar.tsx +235 -0
  127. package/src/components/ui/fullscreen-button.tsx +60 -0
  128. package/src/components/ui/media-resource-preloader.tsx +395 -0
  129. package/src/components/ui/play-button.tsx +107 -0
  130. package/src/components/ui/seek-bar.tsx +161 -0
  131. package/src/components/ui/time-display.tsx +40 -0
  132. package/src/components/ui/volume-control.tsx +143 -0
  133. package/src/components/unified/base-media-player.tsx +246 -0
  134. package/src/components/unified/media-player.tsx +75 -0
  135. package/src/components/variants/minimal/AccessibleMinimalPlayer.tsx +561 -0
  136. package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.tsx +552 -0
  137. package/src/components/variants/minimal/MinimalControls.tsx +142 -0
  138. package/src/components/variants/minimal/MinimalLoading.tsx +32 -0
  139. package/src/components/variants/minimal/MinimalMediaPlayer.tsx +315 -0
  140. package/src/components/variants/minimal/MinimalOverlay.tsx +64 -0
  141. package/src/components/variants/minimal/MinimalPlayButton.tsx +65 -0
  142. package/src/components/variants/minimal/MinimalSeekBar.tsx +150 -0
  143. package/src/components/variants/minimal/MinimalVolumeControl.tsx +80 -0
  144. package/src/components/variants/minimal/SimpleMinimalPlayer.tsx +210 -0
  145. package/src/components/variants/minimal/components/CenterPlayButton.tsx +22 -0
  146. package/src/components/variants/minimal/components/ControlBar.tsx +146 -0
  147. package/src/components/variants/minimal/components/EnhancedSettingsMenu.tsx +361 -0
  148. package/src/components/variants/minimal/components/PlaybackControls.tsx +51 -0
  149. package/src/components/variants/minimal/components/RightControls.tsx +173 -0
  150. package/src/components/variants/minimal/components/SeekBar.tsx +131 -0
  151. package/src/components/variants/minimal/components/SettingsDropdown.tsx +70 -0
  152. package/src/components/variants/minimal/components/SubtitleDisplay.tsx +21 -0
  153. package/src/components/variants/minimal/components/TimeDisplay.tsx +18 -0
  154. package/src/components/variants/minimal/components/VideoElement.tsx +40 -0
  155. package/src/components/variants/minimal/components/VolumeControl.tsx +217 -0
  156. package/src/components/variants/minimal/index.ts +23 -0
  157. package/src/components/video-player.tsx +100 -0
  158. package/src/context/error-handling.ts +394 -0
  159. package/src/context/media-context.tsx +208 -0
  160. package/src/context/media-provider.tsx +265 -0
  161. package/src/context/media-store.ts +379 -0
  162. package/src/context/persistence.ts +453 -0
  163. package/src/core/events/event-system.ts +442 -0
  164. package/src/core/events/hooks.ts +302 -0
  165. package/src/core/events/index.ts +22 -0
  166. package/src/core/events/middleware.ts +269 -0
  167. package/src/core/index.ts +22 -0
  168. package/src/core/optimization/bundle-optimizer.tsx +308 -0
  169. package/src/core/performance/cicd.ts +96 -0
  170. package/src/core/performance/index.ts +38 -0
  171. package/src/core/performance/media-loading-optimizer.ts +538 -0
  172. package/src/core/performance/performance-budgets.ts +432 -0
  173. package/src/core/performance/performance-monitor.tsx +476 -0
  174. package/src/core/performance/performance-testing.ts +459 -0
  175. package/src/core/plugins/base-plugin.ts +224 -0
  176. package/src/core/plugins/enhanced-plugin-system.ts +411 -0
  177. package/src/core/plugins/examples/analytics-plugin.ts +242 -0
  178. package/src/core/plugins/index.ts +39 -0
  179. package/src/core/plugins/registry.ts +327 -0
  180. package/src/core/plugins/types.ts +159 -0
  181. package/src/core/plugins/utils.ts +316 -0
  182. package/src/core/progressive-loading.tsx +322 -0
  183. package/src/core/providers/enhanced-hls-provider.ts +339 -0
  184. package/src/core/providers/service-provider.tsx +168 -0
  185. package/src/core/utils.tsx +38 -0
  186. package/src/features/media-session/media-session-manager.ts +429 -0
  187. package/src/features/picture-in-picture/pip-manager.ts +429 -0
  188. package/src/features/playlist/playlist-manager.ts +606 -0
  189. package/src/features/subtitles/subtitle-manager.ts +441 -0
  190. package/src/features/subtitles/subtitle-parser.ts +280 -0
  191. package/src/features/thumbnails/thumbnail-generator.ts +519 -0
  192. package/src/hooks/accessibility/index.ts +27 -0
  193. package/src/hooks/accessibility/use-accessibility-preferences.ts +188 -0
  194. package/src/hooks/accessibility/use-focus-management.ts +176 -0
  195. package/src/hooks/accessibility/use-keyboard-shortcuts.ts +144 -0
  196. package/src/hooks/accessibility/use-screen-reader.ts +182 -0
  197. package/src/hooks/core/index.ts +47 -0
  198. package/src/hooks/legacy.ts +27 -0
  199. package/src/hooks/use-enhanced-media-player.ts +468 -0
  200. package/src/hooks/use-intelligent-preloading.ts +358 -0
  201. package/src/hooks/use-keyboard-controls.ts +115 -0
  202. package/src/hooks/use-media-actions.ts +175 -0
  203. package/src/hooks/use-media-metadata.ts +89 -0
  204. package/src/hooks/use-media-optimistic.ts +270 -0
  205. package/src/hooks/use-media-player.ts +312 -0
  206. package/src/hooks/use-media-state.ts +190 -0
  207. package/src/hooks/use-memory-optimization.ts +358 -0
  208. package/src/hooks/use-optimistic-controls.ts +92 -0
  209. package/src/hooks/use-optimized-media.ts +263 -0
  210. package/src/hooks/use-touch-gestures.ts +417 -0
  211. package/src/hooks/useEnhancedSubtitles.ts +258 -0
  212. package/src/hooks/useKeyboardShortcuts.ts +74 -0
  213. package/src/hooks/useMediaControls.ts +52 -0
  214. package/src/hooks/useScreenshot.ts +57 -0
  215. package/src/hooks/useSubtitles.ts +91 -0
  216. package/src/hooks/useVideoPlayer.ts +232 -0
  217. package/src/icons/components/FullscreenIcon.tsx +37 -0
  218. package/src/icons/components/SettingsIcon.tsx +38 -0
  219. package/src/icons/components/animated/LoadingIcon.tsx +43 -0
  220. package/src/icons/components/animated/PlayPauseIcon.tsx +50 -0
  221. package/src/icons/components/media/PauseIcon.tsx +39 -0
  222. package/src/icons/components/media/PlayIcon.tsx +38 -0
  223. package/src/icons/components/volume/VolumeIcon.tsx +39 -0
  224. package/src/icons/components/volume/VolumeOffIcon.tsx +39 -0
  225. package/src/icons/index.ts +56 -0
  226. package/src/icons/provider.tsx +64 -0
  227. package/src/icons/types.ts +40 -0
  228. package/src/index-enhanced.ts +35 -0
  229. package/src/index-legacy.ts +326 -0
  230. package/src/index.css +102 -0
  231. package/src/index.ts +216 -0
  232. package/src/lib/deprecation.ts +51 -0
  233. package/src/lib/format-time.ts +37 -0
  234. package/src/lib/index.ts +3 -0
  235. package/src/lib/utils.ts +6 -0
  236. package/src/styles/globals.css +462 -0
  237. package/src/styles/minimal-player.css +589 -0
  238. package/src/styles/pixel-art.css +46 -0
  239. package/src/styles/videojs.css +100 -0
  240. package/src/test/setup.ts +79 -0
  241. package/src/types/events.ts +47 -0
  242. package/src/types/formats.ts +95 -0
  243. package/src/types/index.ts +190 -0
  244. package/src/types/videojs-plugins.d.ts +14 -0
@@ -0,0 +1,422 @@
1
+ /**
2
+ * Debug Panel Component for Performance Monitoring
3
+ * Development-only component for displaying performance metrics
4
+ */
5
+
6
+ import React, { useMemo } from 'react';
7
+ import { cn } from '../../lib/utils';
8
+
9
+ interface PerformanceMetrics {
10
+ fps: number;
11
+ memoryUsage: number;
12
+ bufferHealth: number;
13
+ networkBandwidth: number;
14
+ droppedFrames: number;
15
+ decodedFrames: number;
16
+ presentationTime: number;
17
+ }
18
+
19
+ interface PreloadingStats {
20
+ preloadedItems: number;
21
+ engagementScore: number;
22
+ queueLength: number;
23
+ hitRate: number;
24
+ totalSaved: number;
25
+ }
26
+
27
+ interface DebugPanelProps {
28
+ /** Performance metrics to display */
29
+ performanceMetrics?: Partial<PerformanceMetrics>;
30
+ /** Preloading statistics */
31
+ preloadingStats?: PreloadingStats;
32
+ /** Current playback state */
33
+ playbackState?: {
34
+ currentTime: number;
35
+ duration: number;
36
+ volume: number;
37
+ isPlaying: boolean;
38
+ quality: number;
39
+ isBuffering: boolean;
40
+ error?: string;
41
+ };
42
+ /** HLS-specific metrics */
43
+ hlsMetrics?: {
44
+ currentLevel: number;
45
+ availableLevels: number;
46
+ bandwidthEstimate: number;
47
+ droppedFrames: number;
48
+ };
49
+ /** Plugin information */
50
+ pluginInfo?: {
51
+ loadedPlugins: string[];
52
+ activePlugins: string[];
53
+ pluginCount: number;
54
+ };
55
+ /** Additional debug information */
56
+ debugInfo?: Record<string, any>;
57
+ /** Custom className */
58
+ className?: string;
59
+ /** Panel position */
60
+ position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
61
+ /** Whether the panel is collapsed by default */
62
+ defaultCollapsed?: boolean;
63
+ /** Custom title */
64
+ title?: string;
65
+ }
66
+
67
+ /**
68
+ * Debug Panel Component
69
+ */
70
+ export const DebugPanel: React.FC<DebugPanelProps> = ({
71
+ performanceMetrics = {},
72
+ preloadingStats = {} as PreloadingStats,
73
+ playbackState = {} as any,
74
+ hlsMetrics = {},
75
+ pluginInfo = {},
76
+ debugInfo = {},
77
+ className,
78
+ position = 'top-right',
79
+ defaultCollapsed = false,
80
+ title = 'BaroiPlayer Debug Panel'
81
+ }) => {
82
+ const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed);
83
+ const [activeTab, setActiveTab] = React.useState<'performance' | 'hls' | 'plugins' | 'debug'>('performance');
84
+
85
+ // Position classes
86
+ const positionClasses = useMemo(() => {
87
+ switch (position) {
88
+ case 'top-left':
89
+ return 'top-4 left-4';
90
+ case 'top-right':
91
+ return 'top-4 right-4';
92
+ case 'bottom-left':
93
+ return 'bottom-4 left-4';
94
+ case 'bottom-right':
95
+ return 'bottom-4 right-4';
96
+ default:
97
+ return 'top-4 right-4';
98
+ }
99
+ }, [position]);
100
+
101
+ // Format bytes
102
+ const formatBytes = (bytes: number): string => {
103
+ if (bytes === 0) return '0 B';
104
+ const k = 1024;
105
+ const sizes = ['B', 'KB', 'MB', 'GB'];
106
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
107
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
108
+ };
109
+
110
+ // Format time
111
+ const formatTime = (seconds: number): string => {
112
+ const mins = Math.floor(seconds / 60);
113
+ const secs = Math.floor(seconds % 60);
114
+ return `${mins}:${secs.toString().padStart(2, '0')}`;
115
+ };
116
+
117
+ // Render performance metrics
118
+ const renderPerformanceMetrics = () => (
119
+ <div className="space-y-2">
120
+ <div className="grid grid-cols-2 gap-2 text-xs">
121
+ <div>
122
+ <span className="text-green-400">FPS:</span>
123
+ <span className="ml-2 font-mono">{performanceMetrics.fps || 0}</span>
124
+ </div>
125
+ <div>
126
+ <span className="text-blue-400">Memory:</span>
127
+ <span className="ml-2 font-mono">{((performanceMetrics.memoryUsage || 0) / 1024 / 1024).toFixed(1)} MB</span>
128
+ </div>
129
+ <div>
130
+ <span className="text-yellow-400">Buffer:</span>
131
+ <span className="ml-2 font-mono">{(performanceMetrics.bufferHealth || 0).toFixed(2)}s</span>
132
+ </div>
133
+ <div>
134
+ <span className="text-purple-400">Bandwidth:</span>
135
+ <span className="ml-2 font-mono">{formatBytes(performanceMetrics.networkBandwidth || 0)}/s</span>
136
+ </div>
137
+ <div>
138
+ <span className="text-red-400">Dropped:</span>
139
+ <span className="ml-2 font-mono">{performanceMetrics.droppedFrames || 0} frames</span>
140
+ </div>
141
+ <div>
142
+ <span className="text-cyan-400">Decoded:</span>
143
+ <span className="ml-2 font-mono">{performanceMetrics.decodedFrames || 0} frames</span>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ );
148
+
149
+ // Render playback state
150
+ const renderPlaybackState = () => (
151
+ <div className="space-y-2">
152
+ <div className="grid grid-cols-2 gap-2 text-xs">
153
+ <div>
154
+ <span className="text-green-400">Status:</span>
155
+ <span className="ml-2 font-mono">
156
+ {playbackState.isPlaying ? (
157
+ <span className="text-green-300">Playing</span>
158
+ ) : (
159
+ <span className="text-red-300">Paused</span>
160
+ )}
161
+ </span>
162
+ </div>
163
+ <div>
164
+ <span className="text-blue-400">Time:</span>
165
+ <span className="ml-2 font-mono">
166
+ {formatTime(playbackState.currentTime || 0)} / {formatTime(playbackState.duration || 0)}
167
+ </span>
168
+ </div>
169
+ <div>
170
+ <span className="text-yellow-400">Volume:</span>
171
+ <span className="ml-2 font-mono">{Math.round((playbackState.volume || 0) * 100)}%</span>
172
+ </div>
173
+ <div>
174
+ <span className="text-purple-400">Quality:</span>
175
+ <span className="ml-2 font-mono">{playbackState.quality || 0}p</span>
176
+ </div>
177
+ <div>
178
+ <span className="text-red-400">Buffering:</span>
179
+ <span className="ml-2 font-mono">
180
+ {playbackState.isBuffering ? (
181
+ <span className="text-yellow-300">Yes</span>
182
+ ) : (
183
+ <span className="text-green-300">No</span>
184
+ )}
185
+ </span>
186
+ </div>
187
+ {playbackState.error && (
188
+ <div className="col-span-2">
189
+ <span className="text-red-400">Error:</span>
190
+ <span className="ml-2 break-all font-mono text-red-300 text-xs">
191
+ {playbackState.error}
192
+ </span>
193
+ </div>
194
+ )}
195
+ </div>
196
+ </div>
197
+ );
198
+
199
+ // Render preloading stats
200
+ const renderPreloadingStats = () => (
201
+ <div className="space-y-2">
202
+ <div className="grid grid-cols-2 gap-2 text-xs">
203
+ <div>
204
+ <span className="text-green-400">Preloaded:</span>
205
+ <span className="ml-2 font-mono">{preloadingStats.preloadedItems || 0} items</span>
206
+ </div>
207
+ <div>
208
+ <span className="text-blue-400">Engagement:</span>
209
+ <span className="ml-2 font-mono">{(preloadingStats.engagementScore || 0).toFixed(1)}%</span>
210
+ </div>
211
+ <div>
212
+ <span className="text-yellow-400">Queue:</span>
213
+ <span className="ml-2 font-mono">{preloadingStats.queueLength || 0} items</span>
214
+ </div>
215
+ <div>
216
+ <span className="text-purple-400">Hit Rate:</span>
217
+ <span className="ml-2 font-mono">{(preloadingStats.hitRate || 0).toFixed(1)}%</span>
218
+ </div>
219
+ <div className="col-span-2">
220
+ <span className="text-cyan-400">Saved:</span>
221
+ <span className="ml-2 font-mono">{formatBytes(preloadingStats.totalSaved || 0)}</span>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ );
226
+
227
+ // Render HLS metrics
228
+ const renderHLSMetrics = () => (
229
+ <div className="space-y-2">
230
+ <div className="grid grid-cols-2 gap-2 text-xs">
231
+ <div>
232
+ <span className="text-green-400">Level:</span>
233
+ <span className="ml-2 font-mono">
234
+ {hlsMetrics.currentLevel || 0} / {hlsMetrics.availableLevels || 0}
235
+ </span>
236
+ </div>
237
+ <div>
238
+ <span className="text-blue-400">Bandwidth:</span>
239
+ <span className="ml-2 font-mono">{formatBytes(hlsMetrics.bandwidthEstimate || 0)}/s</span>
240
+ </div>
241
+ <div>
242
+ <span className="text-red-400">Dropped:</span>
243
+ <span className="ml-2 font-mono">{hlsMetrics.droppedFrames || 0} frames</span>
244
+ </div>
245
+ </div>
246
+ </div>
247
+ );
248
+
249
+ // Render plugin info
250
+ const renderPluginInfo = () => (
251
+ <div className="space-y-2">
252
+ <div className="text-xs">
253
+ <div>
254
+ <span className="text-green-400">Total:</span>
255
+ <span className="ml-2 font-mono">{pluginInfo.pluginCount || 0} plugins</span>
256
+ </div>
257
+ <div className="mt-2">
258
+ <span className="text-blue-400">Active:</span>
259
+ <div className="ml-2 space-y-1 font-mono text-xs">
260
+ {pluginInfo.activePlugins?.map((plugin, index) => (
261
+ <div key={index} className="text-green-300">• {plugin}</div>
262
+ )) || <div className="text-gray-400">None</div>}
263
+ </div>
264
+ </div>
265
+ {pluginInfo.loadedPlugins && pluginInfo.loadedPlugins.length > pluginInfo.activePlugins?.length && (
266
+ <div className="mt-2">
267
+ <span className="text-yellow-400">Loaded (inactive):</span>
268
+ <div className="ml-2 space-y-1 font-mono text-xs">
269
+ {pluginInfo.loadedPlugins
270
+ .filter(plugin => !pluginInfo.activePlugins?.includes(plugin))
271
+ .map((plugin, index) => (
272
+ <div key={index} className="text-yellow-300">• {plugin}</div>
273
+ ))}
274
+ </div>
275
+ </div>
276
+ )}
277
+ </div>
278
+ </div>
279
+ );
280
+
281
+ // Render debug info
282
+ const renderDebugInfo = () => (
283
+ <div className="space-y-2">
284
+ <div className="space-y-1 font-mono text-xs">
285
+ {Object.entries(debugInfo).map(([key, value]) => (
286
+ <div key={key}>
287
+ <span className="text-yellow-400">{key}:</span>
288
+ <span className="ml-2 text-gray-300">
289
+ {typeof value === 'object' ? JSON.stringify(value, null, 2) : String(value)}
290
+ </span>
291
+ </div>
292
+ ))}
293
+ </div>
294
+ </div>
295
+ );
296
+
297
+ // Render tabs
298
+ const renderTabs = () => (
299
+ <div className="flex space-x-1 border-gray-600 border-b">
300
+ {[
301
+ { id: 'performance', label: 'Performance' },
302
+ { id: 'hls', label: 'HLS' },
303
+ { id: 'plugins', label: 'Plugins' },
304
+ { id: 'debug', label: 'Debug' }
305
+ ].map(tab => (
306
+ <button
307
+ key={tab.id}
308
+ onClick={() => setActiveTab(tab.id as any)}
309
+ className={cn(
310
+ "px-2 py-1 font-medium text-xs transition-colors",
311
+ activeTab === tab.id
312
+ ? "border-blue-400 border-b text-blue-400"
313
+ : 'text-gray-400 hover:text-white'
314
+ )}
315
+ >
316
+ {tab.label}
317
+ </button>
318
+ ))}
319
+ </div>
320
+ );
321
+
322
+ // Render active tab content
323
+ const renderTabContent = () => {
324
+ switch (activeTab) {
325
+ case 'performance':
326
+ return (
327
+ <div className="space-y-3">
328
+ {renderPerformanceMetrics()}
329
+ <hr className="border-gray-600" />
330
+ {renderPlaybackState()}
331
+ <hr className="border-gray-600" />
332
+ {renderPreloadingStats()}
333
+ </div>
334
+ );
335
+ case 'hls':
336
+ return renderHLSMetrics();
337
+ case 'plugins':
338
+ return renderPluginInfo();
339
+ case 'debug':
340
+ return renderDebugInfo();
341
+ default:
342
+ return renderPerformanceMetrics();
343
+ }
344
+ };
345
+
346
+ // Only render in development
347
+ if (process.env.NODE_ENV !== 'development') {
348
+ return null;
349
+ }
350
+
351
+ return (
352
+ <div
353
+ className={cn(
354
+ "fixed z-50 min-w-80 max-w-96 rounded-lg border border-gray-700 bg-black/90 p-3 font-mono text-white text-xs backdrop-blur-sm",
355
+ positionClasses,
356
+ className
357
+ )}
358
+ >
359
+ {/* Header */}
360
+ <div className="mb-3 flex items-center justify-between">
361
+ <h3 className="font-bold text-blue-400 text-sm">{title}</h3>
362
+ <div className="flex items-center space-x-2">
363
+ <button
364
+ onClick={() => setIsCollapsed(!isCollapsed)}
365
+ className="text-gray-400 transition-colors hover:text-white"
366
+ aria-label={isCollapsed ? 'Expand' : 'Collapse'}
367
+ >
368
+ {isCollapsed ? (
369
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="none">
370
+ <path d="M3 4.5L6 7.5L9 4.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
371
+ </svg>
372
+ ) : (
373
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="none">
374
+ <path d="M3 7.5L6 4.5L9 7.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
375
+ </svg>
376
+ )}
377
+ </button>
378
+ </div>
379
+ </div>
380
+
381
+ {/* Collapsed content */}
382
+ {isCollapsed ? (
383
+ <div className="grid grid-cols-2 gap-2 text-xs">
384
+ <div>
385
+ <span className="text-green-400">FPS:</span>
386
+ <span className="ml-1 font-mono">{performanceMetrics.fps || 0}</span>
387
+ </div>
388
+ <div>
389
+ <span className="text-blue-400">Memory:</span>
390
+ <span className="ml-1 font-mono">{((performanceMetrics.memoryUsage || 0) / 1024 / 1024).toFixed(1)}MB</span>
391
+ </div>
392
+ </div>
393
+ ) : (
394
+ <>
395
+ {/* Tabs */}
396
+ {renderTabs()}
397
+
398
+ {/* Tab Content */}
399
+ <div className="mt-3 max-h-64 overflow-y-auto">
400
+ {renderTabContent()}
401
+ </div>
402
+ </>
403
+ )}
404
+ </div>
405
+ );
406
+ };
407
+
408
+ /**
409
+ * Performance Debug Panel - simplified version focused on performance metrics
410
+ */
411
+ export const PerformanceDebugPanel: React.FC<Omit<DebugPanelProps, 'position' | 'defaultCollapsed' | 'title'>> = (props) => {
412
+ return (
413
+ <DebugPanel
414
+ {...props}
415
+ position="top-right"
416
+ defaultCollapsed={false}
417
+ title="Performance Monitor"
418
+ />
419
+ );
420
+ };
421
+
422
+ export default DebugPanel;