@therealtinhtute/baroiplayer 1.0.3 → 1.0.5
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/dist/core.js +1 -1
- package/dist/core.mjs +2 -2
- package/dist/hooks-BCMilGRf.cjs +4 -0
- package/dist/hooks-BCMilGRf.cjs.map +1 -0
- package/dist/{hooks-BhW_i-9L.js → hooks-BPtHV1ZT.js} +793 -764
- package/dist/hooks-BPtHV1ZT.js.map +1 -0
- package/dist/index.d.ts +38 -1
- package/dist/{minimal-components-BsqodtY8.cjs → minimal-components-BHJMuaL7.cjs} +2 -2
- package/dist/{minimal-components-BsqodtY8.cjs.map → minimal-components-BHJMuaL7.cjs.map} +1 -1
- package/dist/{minimal-components-B0bILe18.js → minimal-components-BmqRefl1.js} +2 -2
- package/dist/{minimal-components-B0bILe18.js.map → minimal-components-BmqRefl1.js.map} +1 -1
- package/dist/package.json +38 -4
- package/dist/src/components/media-player-controls.tsx +1 -1
- package/dist/src/components/media-player-root.tsx +1 -1
- package/dist/src/components/ui/button.tsx +49 -0
- package/dist/src/components/ui/dropdown-menu.tsx +137 -0
- package/dist/src/components/ui/icons.tsx +174 -0
- package/dist/src/components/ui/slider.tsx +55 -0
- package/dist/src/components/ui/tooltip.tsx +131 -0
- package/dist/src/hooks/use-enhanced-media-player.ts +12 -12
- package/dist/src/hooks/use-intelligent-preloading.ts +27 -22
- package/dist/src/hooks/use-media-player.ts +0 -2
- package/dist/src/hooks/use-memory-optimization.ts +19 -19
- package/dist/src/hooks/use-mobile.ts +125 -0
- package/dist/src/hooks/use-touch-gestures.js +1 -1
- package/dist/src/index-legacy.ts +2 -1
- package/dist/styles/globals.css +462 -0
- package/dist/styles/pixel-art.css +46 -0
- package/dist/styles/videojs.css +100 -0
- package/package.json +23 -3
- package/src/components/media-player-controls.tsx +1 -1
- package/src/components/media-player-root.tsx +1 -1
- package/src/components/ui/button.tsx +49 -0
- package/src/components/ui/dropdown-menu.tsx +137 -0
- package/src/components/ui/icons.tsx +174 -0
- package/src/components/ui/slider.tsx +55 -0
- package/src/components/ui/tooltip.tsx +131 -0
- package/src/hooks/use-enhanced-media-player.ts +12 -12
- package/src/hooks/use-intelligent-preloading.ts +27 -22
- package/src/hooks/use-media-player.ts +0 -2
- package/src/hooks/use-memory-optimization.ts +19 -19
- package/src/hooks/use-mobile.ts +125 -0
- package/src/hooks/use-touch-gestures.js +1 -1
- package/src/index-legacy.ts +2 -1
- package/dist/hooks-BhW_i-9L.js.map +0 -1
- package/dist/hooks-DTXeB5Z-.cjs +0 -4
- package/dist/hooks-DTXeB5Z-.cjs.map +0 -1
|
@@ -57,7 +57,13 @@ export const useIntelligentPreloading = (
|
|
|
57
57
|
lastInteraction: Date.now(),
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
// Network Information API (if available)
|
|
61
|
+
const networkInfoRef = useRef<{
|
|
62
|
+
effectiveType?: string;
|
|
63
|
+
downlink?: number;
|
|
64
|
+
rtt?: number;
|
|
65
|
+
saveData?: boolean;
|
|
66
|
+
} | null>(null);
|
|
61
67
|
const preloadedItemsRef = useRef<Set<string>>(new Set());
|
|
62
68
|
const preloadQueueRef = useRef<Array<{ source: MediaSource; priority: number }>>([]);
|
|
63
69
|
|
|
@@ -89,7 +95,7 @@ export const useIntelligentPreloading = (
|
|
|
89
95
|
|
|
90
96
|
const network = networkInfoRef.current;
|
|
91
97
|
return {
|
|
92
|
-
type: network.type
|
|
98
|
+
type: network.effectiveType || '4g', // Use effectiveType as the primary type indicator
|
|
93
99
|
downlink: network.downlink || 10,
|
|
94
100
|
effectiveType: network.effectiveType || '4g',
|
|
95
101
|
saveData: network.saveData || false,
|
|
@@ -156,8 +162,9 @@ export const useIntelligentPreloading = (
|
|
|
156
162
|
|
|
157
163
|
// Additional heuristics
|
|
158
164
|
if (shouldPreload) {
|
|
159
|
-
// Prioritize HLS and adaptive streaming
|
|
160
|
-
|
|
165
|
+
// Prioritize HLS and adaptive streaming (check URL extension)
|
|
166
|
+
const sourceUrl = source.src.toLowerCase();
|
|
167
|
+
if (sourceUrl.includes('.m3u8') || sourceUrl.includes('hls')) {
|
|
161
168
|
priority = priority === 'low' ? 'medium' : 'high';
|
|
162
169
|
}
|
|
163
170
|
|
|
@@ -168,7 +175,8 @@ export const useIntelligentPreloading = (
|
|
|
168
175
|
}
|
|
169
176
|
|
|
170
177
|
// Consider content type (video gets higher priority than audio)
|
|
171
|
-
if (source.type
|
|
178
|
+
if (source.type?.includes('mp4') || source.type?.includes('webm') ||
|
|
179
|
+
sourceUrl.includes('.mp4') || sourceUrl.includes('.webm')) {
|
|
172
180
|
priority = priority === 'low' ? 'medium' : priority;
|
|
173
181
|
}
|
|
174
182
|
}
|
|
@@ -184,23 +192,20 @@ export const useIntelligentPreloading = (
|
|
|
184
192
|
link.rel = 'preload';
|
|
185
193
|
link.href = source.src;
|
|
186
194
|
|
|
187
|
-
// Determine the correct 'as' attribute
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
break;
|
|
202
|
-
default:
|
|
203
|
-
link.as = 'fetch';
|
|
195
|
+
// Determine the correct 'as' attribute based on URL or MIME type
|
|
196
|
+
const sourceUrl = source.src.toLowerCase();
|
|
197
|
+
const mimeType = source.type?.toLowerCase() || '';
|
|
198
|
+
|
|
199
|
+
if (sourceUrl.includes('.m3u8') || sourceUrl.includes('hls')) {
|
|
200
|
+
link.as = 'fetch';
|
|
201
|
+
} else if (mimeType.includes('mp4') || mimeType.includes('webm') ||
|
|
202
|
+
sourceUrl.includes('.mp4') || sourceUrl.includes('.webm')) {
|
|
203
|
+
link.as = 'video';
|
|
204
|
+
} else if (mimeType.includes('mp3') || mimeType.includes('wav') || mimeType.includes('ogg') ||
|
|
205
|
+
sourceUrl.includes('.mp3') || sourceUrl.includes('.wav') || sourceUrl.includes('.ogg')) {
|
|
206
|
+
link.as = 'audio';
|
|
207
|
+
} else {
|
|
208
|
+
link.as = 'fetch';
|
|
204
209
|
}
|
|
205
210
|
|
|
206
211
|
link.crossOrigin = 'anonymous';
|
|
@@ -16,10 +16,10 @@ export function useMemoryOptimization(options: {
|
|
|
16
16
|
monitorMemory = true
|
|
17
17
|
} = options
|
|
18
18
|
|
|
19
|
-
const cleanupTimeoutRef = useRef<NodeJS.Timeout>()
|
|
19
|
+
const cleanupTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined)
|
|
20
20
|
const observersRef = useRef<Set<MutationObserver>>(new Set())
|
|
21
21
|
const eventListenersRef = useRef<Map<Element, Array<{ event: string; handler: EventListener }>>>(new Map())
|
|
22
|
-
const intervalRefs = useRef<Set<
|
|
22
|
+
const intervalRefs = useRef<Set<ReturnType<typeof setInterval>>>(new Set()) // Use proper timer type
|
|
23
23
|
const animationFrameRefs = useRef<Set<number>>(new Set())
|
|
24
24
|
|
|
25
25
|
// Get current memory usage
|
|
@@ -67,20 +67,20 @@ export function useMemoryOptimization(options: {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
checkMemory()
|
|
70
|
-
const
|
|
71
|
-
intervalRefs.current.add(
|
|
70
|
+
const intervalId: ReturnType<typeof setInterval> = setInterval(checkMemory, cleanupInterval)
|
|
71
|
+
intervalRefs.current.add(intervalId)
|
|
72
72
|
|
|
73
73
|
return () => {
|
|
74
|
-
clearInterval(
|
|
75
|
-
intervalRefs.current.delete(
|
|
74
|
+
clearInterval(intervalId as any)
|
|
75
|
+
intervalRefs.current.delete(intervalId)
|
|
76
76
|
}
|
|
77
77
|
}, [monitorMemory, getMemoryUsage, maxMemoryUsage, enableGC, cleanupInterval])
|
|
78
78
|
|
|
79
79
|
// Cleanup function
|
|
80
80
|
const performCleanup = useCallback(() => {
|
|
81
|
-
// Clear all
|
|
82
|
-
intervalRefs.current.forEach(
|
|
83
|
-
|
|
81
|
+
// Clear all intervals
|
|
82
|
+
intervalRefs.current.forEach(intervalId => {
|
|
83
|
+
clearInterval(intervalId as any)
|
|
84
84
|
})
|
|
85
85
|
intervalRefs.current.clear()
|
|
86
86
|
|
|
@@ -141,29 +141,29 @@ export function useMemoryOptimization(options: {
|
|
|
141
141
|
}, [])
|
|
142
142
|
|
|
143
143
|
// Safe interval management
|
|
144
|
-
const
|
|
144
|
+
const safeSetInterval = useCallback((callback: () => void, delay: number) => {
|
|
145
145
|
const timeoutId = setInterval(callback, delay)
|
|
146
146
|
intervalRefs.current.add(timeoutId)
|
|
147
147
|
|
|
148
148
|
return () => {
|
|
149
|
-
clearInterval(timeoutId)
|
|
149
|
+
clearInterval(timeoutId as any)
|
|
150
150
|
intervalRefs.current.delete(timeoutId)
|
|
151
151
|
}
|
|
152
152
|
}, [])
|
|
153
153
|
|
|
154
154
|
// Safe timeout management
|
|
155
|
-
const
|
|
155
|
+
const safeSetTimeout = useCallback((callback: () => void, delay: number) => {
|
|
156
156
|
const timeoutId = setTimeout(callback, delay)
|
|
157
157
|
intervalRefs.current.add(timeoutId)
|
|
158
158
|
|
|
159
159
|
return () => {
|
|
160
|
-
clearTimeout(timeoutId)
|
|
160
|
+
clearTimeout(timeoutId as any)
|
|
161
161
|
intervalRefs.current.delete(timeoutId)
|
|
162
162
|
}
|
|
163
163
|
}, [])
|
|
164
164
|
|
|
165
165
|
// Safe animation frame management
|
|
166
|
-
const
|
|
166
|
+
const safeRequestAnimationFrame = useCallback((callback: FrameRequestCallback) => {
|
|
167
167
|
const frameId = requestAnimationFrame(callback)
|
|
168
168
|
animationFrameRefs.current.add(frameId)
|
|
169
169
|
|
|
@@ -200,9 +200,9 @@ export function useMemoryOptimization(options: {
|
|
|
200
200
|
|
|
201
201
|
// Safe API functions
|
|
202
202
|
addEventListener,
|
|
203
|
-
setInterval,
|
|
204
|
-
setTimeout,
|
|
205
|
-
requestAnimationFrame,
|
|
203
|
+
setInterval: safeSetInterval,
|
|
204
|
+
setTimeout: safeSetTimeout,
|
|
205
|
+
requestAnimationFrame: safeRequestAnimationFrame,
|
|
206
206
|
addObserver,
|
|
207
207
|
|
|
208
208
|
// Utilities
|
|
@@ -227,7 +227,7 @@ export function useMediaResourceCleanup(mediaRef: React.RefObject<HTMLVideoEleme
|
|
|
227
227
|
|
|
228
228
|
// Stop media playback
|
|
229
229
|
if (!media.paused) {
|
|
230
|
-
|
|
230
|
+
media.pause()
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
// Clear source
|
|
@@ -284,7 +284,7 @@ export function usePerformanceMonitoring() {
|
|
|
284
284
|
|
|
285
285
|
const frameCountRef = useRef(0)
|
|
286
286
|
const lastFrameTimeRef = useRef(performance.now())
|
|
287
|
-
const longTaskObserverRef = useRef<PerformanceObserver>()
|
|
287
|
+
const longTaskObserverRef = useRef<PerformanceObserver | undefined>(undefined)
|
|
288
288
|
|
|
289
289
|
// FPS monitoring
|
|
290
290
|
useEffect(() => {
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
interface DeviceInfo {
|
|
4
|
+
isMobile: boolean;
|
|
5
|
+
isTablet: boolean;
|
|
6
|
+
isDesktop: boolean;
|
|
7
|
+
userAgent: string;
|
|
8
|
+
screenWidth: number;
|
|
9
|
+
screenHeight: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function useDeviceInfo(): DeviceInfo {
|
|
13
|
+
const [deviceInfo, setDeviceInfo] = useState<DeviceInfo>(() => {
|
|
14
|
+
if (typeof window === 'undefined') {
|
|
15
|
+
return {
|
|
16
|
+
isMobile: false,
|
|
17
|
+
isTablet: false,
|
|
18
|
+
isDesktop: true,
|
|
19
|
+
userAgent: '',
|
|
20
|
+
screenWidth: 1920,
|
|
21
|
+
screenHeight: 1080
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const userAgent = navigator.userAgent;
|
|
26
|
+
const screenWidth = window.innerWidth;
|
|
27
|
+
const screenHeight = window.innerHeight;
|
|
28
|
+
|
|
29
|
+
const isMobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent) && screenWidth < 768;
|
|
30
|
+
const isTablet = /iPad|Android/i.test(userAgent) && screenWidth >= 768 && screenWidth < 1024;
|
|
31
|
+
const isDesktop = !isMobile && !isTablet;
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
isMobile,
|
|
35
|
+
isTablet,
|
|
36
|
+
isDesktop,
|
|
37
|
+
userAgent,
|
|
38
|
+
screenWidth,
|
|
39
|
+
screenHeight
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (typeof window === 'undefined') return;
|
|
45
|
+
|
|
46
|
+
const handleResize = () => {
|
|
47
|
+
const userAgent = navigator.userAgent;
|
|
48
|
+
const screenWidth = window.innerWidth;
|
|
49
|
+
const screenHeight = window.innerHeight;
|
|
50
|
+
|
|
51
|
+
const isMobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent) && screenWidth < 768;
|
|
52
|
+
const isTablet = /iPad|Android/i.test(userAgent) && screenWidth >= 768 && screenWidth < 1024;
|
|
53
|
+
const isDesktop = !isMobile && !isTablet;
|
|
54
|
+
|
|
55
|
+
setDeviceInfo({
|
|
56
|
+
isMobile,
|
|
57
|
+
isTablet,
|
|
58
|
+
isDesktop,
|
|
59
|
+
userAgent,
|
|
60
|
+
screenWidth,
|
|
61
|
+
screenHeight
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
window.addEventListener('resize', handleResize);
|
|
66
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
67
|
+
}, []);
|
|
68
|
+
|
|
69
|
+
return deviceInfo;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function useContainerQuery(): boolean {
|
|
73
|
+
const [isSmall, setIsSmall] = useState(false);
|
|
74
|
+
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (typeof window === 'undefined') return;
|
|
77
|
+
|
|
78
|
+
const checkSize = () => {
|
|
79
|
+
setIsSmall(window.innerWidth < 640);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
checkSize();
|
|
83
|
+
window.addEventListener('resize', checkSize);
|
|
84
|
+
return () => window.removeEventListener('resize', checkSize);
|
|
85
|
+
}, []);
|
|
86
|
+
|
|
87
|
+
return isSmall;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function useMobileOptimizations() {
|
|
91
|
+
const deviceInfo = useDeviceInfo();
|
|
92
|
+
const [isTouch, setIsTouch] = useState(false);
|
|
93
|
+
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
setIsTouch('ontouchstart' in window || navigator.maxTouchPoints > 0);
|
|
96
|
+
}, []);
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
...deviceInfo,
|
|
100
|
+
isTouch,
|
|
101
|
+
preferReducedMotion: window.matchMedia('(prefers-reduced-motion: reduce)').matches,
|
|
102
|
+
prefersDarkScheme: window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function useHapticFeedback() {
|
|
107
|
+
const deviceInfo = useDeviceInfo();
|
|
108
|
+
|
|
109
|
+
const triggerHaptic = (type: 'light' | 'medium' | 'heavy' = 'light') => {
|
|
110
|
+
if (!deviceInfo.isMobile || !('vibrate' in navigator)) return;
|
|
111
|
+
|
|
112
|
+
const patterns = {
|
|
113
|
+
light: [10],
|
|
114
|
+
medium: [20],
|
|
115
|
+
heavy: [50]
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
navigator.vibrate(patterns[type]);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
triggerHaptic,
|
|
123
|
+
supported: deviceInfo.isMobile && 'vibrate' in navigator
|
|
124
|
+
};
|
|
125
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import { useDeviceInfo, useHapticFeedback } from "
|
|
3
|
+
import { useDeviceInfo, useHapticFeedback } from "./use-mobile";
|
|
4
4
|
// Default configuration
|
|
5
5
|
const defaultConfig = {
|
|
6
6
|
enabledGestures: ['tap', 'double-tap', 'long-press', 'swipe-left', 'swipe-right', 'swipe-up', 'swipe-down', 'pinch-in', 'pinch-out'],
|
package/dist/src/index-legacy.ts
CHANGED
|
@@ -133,10 +133,11 @@ export { useEnhancedMediaPlayer } from "./hooks/use-enhanced-media-player"
|
|
|
133
133
|
// Performance Monitoring
|
|
134
134
|
export {
|
|
135
135
|
PerformanceMonitor,
|
|
136
|
-
PerformanceMetrics,
|
|
137
136
|
usePerformanceMonitor as usePerformanceMonitoring
|
|
138
137
|
} from "./core/performance"
|
|
139
138
|
|
|
139
|
+
export type { PerformanceMetrics } from "./core/performance"
|
|
140
|
+
|
|
140
141
|
// Media Resource Preloader
|
|
141
142
|
export { MediaResourcePreloader } from "./components/ui/media-resource-preloader"
|
|
142
143
|
|