@livepeer-frameworks/player-core 0.0.3

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 (120) hide show
  1. package/dist/cjs/index.js +19493 -0
  2. package/dist/cjs/index.js.map +1 -0
  3. package/dist/esm/index.js +19398 -0
  4. package/dist/esm/index.js.map +1 -0
  5. package/dist/player.css +2140 -0
  6. package/dist/types/core/ABRController.d.ts +164 -0
  7. package/dist/types/core/CodecUtils.d.ts +54 -0
  8. package/dist/types/core/Disposable.d.ts +61 -0
  9. package/dist/types/core/EventEmitter.d.ts +73 -0
  10. package/dist/types/core/GatewayClient.d.ts +144 -0
  11. package/dist/types/core/InteractionController.d.ts +121 -0
  12. package/dist/types/core/LiveDurationProxy.d.ts +102 -0
  13. package/dist/types/core/MetaTrackManager.d.ts +220 -0
  14. package/dist/types/core/MistReporter.d.ts +163 -0
  15. package/dist/types/core/MistSignaling.d.ts +148 -0
  16. package/dist/types/core/PlayerController.d.ts +665 -0
  17. package/dist/types/core/PlayerInterface.d.ts +230 -0
  18. package/dist/types/core/PlayerManager.d.ts +182 -0
  19. package/dist/types/core/PlayerRegistry.d.ts +27 -0
  20. package/dist/types/core/QualityMonitor.d.ts +184 -0
  21. package/dist/types/core/ScreenWakeLockManager.d.ts +70 -0
  22. package/dist/types/core/SeekingUtils.d.ts +142 -0
  23. package/dist/types/core/StreamStateClient.d.ts +108 -0
  24. package/dist/types/core/SubtitleManager.d.ts +111 -0
  25. package/dist/types/core/TelemetryReporter.d.ts +79 -0
  26. package/dist/types/core/TimeFormat.d.ts +97 -0
  27. package/dist/types/core/TimerManager.d.ts +83 -0
  28. package/dist/types/core/UrlUtils.d.ts +81 -0
  29. package/dist/types/core/detector.d.ts +149 -0
  30. package/dist/types/core/index.d.ts +49 -0
  31. package/dist/types/core/scorer.d.ts +167 -0
  32. package/dist/types/core/selector.d.ts +9 -0
  33. package/dist/types/index.d.ts +45 -0
  34. package/dist/types/lib/utils.d.ts +2 -0
  35. package/dist/types/players/DashJsPlayer.d.ts +102 -0
  36. package/dist/types/players/HlsJsPlayer.d.ts +70 -0
  37. package/dist/types/players/MewsWsPlayer/SourceBufferManager.d.ts +119 -0
  38. package/dist/types/players/MewsWsPlayer/WebSocketManager.d.ts +60 -0
  39. package/dist/types/players/MewsWsPlayer/index.d.ts +220 -0
  40. package/dist/types/players/MewsWsPlayer/types.d.ts +89 -0
  41. package/dist/types/players/MistPlayer.d.ts +25 -0
  42. package/dist/types/players/MistWebRTCPlayer/index.d.ts +133 -0
  43. package/dist/types/players/NativePlayer.d.ts +143 -0
  44. package/dist/types/players/VideoJsPlayer.d.ts +59 -0
  45. package/dist/types/players/WebCodecsPlayer/JitterBuffer.d.ts +118 -0
  46. package/dist/types/players/WebCodecsPlayer/LatencyProfiles.d.ts +64 -0
  47. package/dist/types/players/WebCodecsPlayer/RawChunkParser.d.ts +63 -0
  48. package/dist/types/players/WebCodecsPlayer/SyncController.d.ts +174 -0
  49. package/dist/types/players/WebCodecsPlayer/WebSocketController.d.ts +164 -0
  50. package/dist/types/players/WebCodecsPlayer/index.d.ts +149 -0
  51. package/dist/types/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.d.ts +105 -0
  52. package/dist/types/players/WebCodecsPlayer/types.d.ts +395 -0
  53. package/dist/types/players/WebCodecsPlayer/worker/decoder.worker.d.ts +13 -0
  54. package/dist/types/players/WebCodecsPlayer/worker/types.d.ts +197 -0
  55. package/dist/types/players/index.d.ts +14 -0
  56. package/dist/types/styles/index.d.ts +11 -0
  57. package/dist/types/types.d.ts +363 -0
  58. package/dist/types/vanilla/FrameWorksPlayer.d.ts +143 -0
  59. package/dist/types/vanilla/index.d.ts +19 -0
  60. package/dist/workers/decoder.worker.js +989 -0
  61. package/dist/workers/decoder.worker.js.map +1 -0
  62. package/package.json +80 -0
  63. package/src/core/ABRController.ts +550 -0
  64. package/src/core/CodecUtils.ts +257 -0
  65. package/src/core/Disposable.ts +120 -0
  66. package/src/core/EventEmitter.ts +113 -0
  67. package/src/core/GatewayClient.ts +439 -0
  68. package/src/core/InteractionController.ts +712 -0
  69. package/src/core/LiveDurationProxy.ts +270 -0
  70. package/src/core/MetaTrackManager.ts +753 -0
  71. package/src/core/MistReporter.ts +543 -0
  72. package/src/core/MistSignaling.ts +346 -0
  73. package/src/core/PlayerController.ts +2829 -0
  74. package/src/core/PlayerInterface.ts +432 -0
  75. package/src/core/PlayerManager.ts +900 -0
  76. package/src/core/PlayerRegistry.ts +149 -0
  77. package/src/core/QualityMonitor.ts +597 -0
  78. package/src/core/ScreenWakeLockManager.ts +163 -0
  79. package/src/core/SeekingUtils.ts +364 -0
  80. package/src/core/StreamStateClient.ts +457 -0
  81. package/src/core/SubtitleManager.ts +297 -0
  82. package/src/core/TelemetryReporter.ts +308 -0
  83. package/src/core/TimeFormat.ts +205 -0
  84. package/src/core/TimerManager.ts +209 -0
  85. package/src/core/UrlUtils.ts +179 -0
  86. package/src/core/detector.ts +382 -0
  87. package/src/core/index.ts +140 -0
  88. package/src/core/scorer.ts +553 -0
  89. package/src/core/selector.ts +16 -0
  90. package/src/global.d.ts +11 -0
  91. package/src/index.ts +75 -0
  92. package/src/lib/utils.ts +6 -0
  93. package/src/players/DashJsPlayer.ts +642 -0
  94. package/src/players/HlsJsPlayer.ts +483 -0
  95. package/src/players/MewsWsPlayer/SourceBufferManager.ts +572 -0
  96. package/src/players/MewsWsPlayer/WebSocketManager.ts +241 -0
  97. package/src/players/MewsWsPlayer/index.ts +1065 -0
  98. package/src/players/MewsWsPlayer/types.ts +106 -0
  99. package/src/players/MistPlayer.ts +188 -0
  100. package/src/players/MistWebRTCPlayer/index.ts +703 -0
  101. package/src/players/NativePlayer.ts +820 -0
  102. package/src/players/VideoJsPlayer.ts +643 -0
  103. package/src/players/WebCodecsPlayer/JitterBuffer.ts +299 -0
  104. package/src/players/WebCodecsPlayer/LatencyProfiles.ts +151 -0
  105. package/src/players/WebCodecsPlayer/RawChunkParser.ts +151 -0
  106. package/src/players/WebCodecsPlayer/SyncController.ts +456 -0
  107. package/src/players/WebCodecsPlayer/WebSocketController.ts +564 -0
  108. package/src/players/WebCodecsPlayer/index.ts +1650 -0
  109. package/src/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.ts +379 -0
  110. package/src/players/WebCodecsPlayer/types.ts +542 -0
  111. package/src/players/WebCodecsPlayer/worker/decoder.worker.ts +1360 -0
  112. package/src/players/WebCodecsPlayer/worker/types.ts +276 -0
  113. package/src/players/index.ts +22 -0
  114. package/src/styles/animations.css +21 -0
  115. package/src/styles/index.ts +52 -0
  116. package/src/styles/player.css +2126 -0
  117. package/src/styles/tailwind.css +1015 -0
  118. package/src/types.ts +421 -0
  119. package/src/vanilla/FrameWorksPlayer.ts +367 -0
  120. package/src/vanilla/index.ts +22 -0
@@ -0,0 +1,142 @@
1
+ /**
2
+ * SeekingUtils.ts
3
+ *
4
+ * Centralized seeking and live detection logic for player controls.
5
+ * Used by React, Svelte, and Vanilla wrappers to ensure consistent behavior.
6
+ *
7
+ * Key concepts:
8
+ * - Seekable range: The portion of the stream that can be seeked to
9
+ * - Live edge: The furthest point in time that can be played (live point)
10
+ * - Near live: Whether playback is close enough to live edge to show "LIVE" badge
11
+ * - Latency tier: Protocol-based classification affecting live detection thresholds
12
+ */
13
+ import type { MistStreamInfo } from '../types';
14
+ export type LatencyTier = 'ultra-low' | 'low' | 'medium' | 'high';
15
+ export interface LiveThresholds {
16
+ /** Seconds behind live edge to exit "LIVE" state (become clickable) */
17
+ exitLive: number;
18
+ /** Seconds behind live edge to enter "LIVE" state (become non-clickable) */
19
+ enterLive: number;
20
+ }
21
+ export interface SeekableRange {
22
+ /** Start of seekable range in seconds */
23
+ seekableStart: number;
24
+ /** End of seekable range (live edge) in seconds */
25
+ liveEdge: number;
26
+ }
27
+ export interface SeekableRangeParams {
28
+ isLive: boolean;
29
+ video: HTMLVideoElement | null;
30
+ mistStreamInfo?: MistStreamInfo;
31
+ currentTime: number;
32
+ duration: number;
33
+ }
34
+ export interface CanSeekParams {
35
+ video: HTMLVideoElement | null;
36
+ isLive: boolean;
37
+ duration: number;
38
+ bufferWindowMs?: number;
39
+ playerCanSeek?: () => boolean;
40
+ }
41
+ /**
42
+ * Latency tier thresholds for "near live" detection.
43
+ * Different protocols have vastly different latency expectations.
44
+ *
45
+ * exitLive: How far behind (seconds) before we show "behind live" indicator
46
+ * enterLive: How close to live (seconds) before we show "LIVE" badge again
47
+ *
48
+ * The gap between exitLive and enterLive creates hysteresis to prevent flicker.
49
+ */
50
+ export declare const LATENCY_TIERS: Record<LatencyTier, LiveThresholds>;
51
+ /**
52
+ * Playback speed presets for UI controls.
53
+ */
54
+ export declare const SPEED_PRESETS: readonly [0.5, 1, 1.5, 2];
55
+ /**
56
+ * Default fallback buffer window when no other info available (in seconds).
57
+ * Aligned with MistServer reference player's 60-second default.
58
+ */
59
+ export declare const DEFAULT_BUFFER_WINDOW_SEC = 60;
60
+ /**
61
+ * Detect latency tier from source type string.
62
+ *
63
+ * @param sourceType - MIME type or protocol identifier (e.g., 'whep', 'ws/video/mp4')
64
+ * @returns Latency tier classification
65
+ */
66
+ export declare function getLatencyTier(sourceType?: string): LatencyTier;
67
+ /**
68
+ * Check if video element is using WebRTC/MediaStream source.
69
+ * WebRTC streams have special constraints (no seeking, no playback rate changes).
70
+ *
71
+ * @param video - HTML video element
72
+ * @returns true if source is a MediaStream
73
+ */
74
+ export declare function isMediaStreamSource(video: HTMLVideoElement | null): boolean;
75
+ /**
76
+ * Check if playback rate adjustment is supported.
77
+ * WebRTC/MediaStream sources don't support playback rate changes.
78
+ *
79
+ * @param video - HTML video element
80
+ * @returns true if playback rate can be changed
81
+ */
82
+ export declare function supportsPlaybackRate(video: HTMLVideoElement | null): boolean;
83
+ /**
84
+ * Calculate seekable range for live or VOD streams.
85
+ *
86
+ * Priority order:
87
+ * 1. Browser's video.seekable ranges (most accurate for MSE-based players)
88
+ * 2. Track firstms/lastms from MistServer metadata
89
+ * 3. buffer_window from MistServer signaling
90
+ * 4. Fallback (only for non-WebRTC sources)
91
+ *
92
+ * @param params - Calculation parameters
93
+ * @returns Seekable range with start and live edge
94
+ */
95
+ export declare function calculateSeekableRange(params: SeekableRangeParams): SeekableRange;
96
+ /**
97
+ * Determine if seeking is supported for the current stream.
98
+ *
99
+ * @param params - Check parameters
100
+ * @returns true if seeking is available
101
+ */
102
+ export declare function canSeekStream(params: CanSeekParams): boolean;
103
+ /**
104
+ * Calculate live detection thresholds, optionally scaled by buffer_window.
105
+ *
106
+ * For medium/high latency tiers, scales thresholds based on the actual
107
+ * buffer window to provide more appropriate "near live" detection.
108
+ *
109
+ * @param sourceType - Protocol/MIME type for tier detection
110
+ * @param isWebRTC - Whether source is WebRTC (overrides tier to ultra-low)
111
+ * @param bufferWindowMs - Optional buffer window in milliseconds
112
+ * @returns Thresholds for entering/exiting "LIVE" state
113
+ */
114
+ export declare function calculateLiveThresholds(sourceType?: string, isWebRTC?: boolean, bufferWindowMs?: number): LiveThresholds;
115
+ /**
116
+ * Calculate whether playback is "near live" using hysteresis.
117
+ *
118
+ * Hysteresis prevents flip-flopping when hovering near the threshold:
119
+ * - To EXIT "LIVE" state: must be > exitLive + margin behind
120
+ * - To ENTER "LIVE" state: must be < enterLive - margin behind
121
+ *
122
+ * @param currentTime - Current playback position in seconds
123
+ * @param liveEdge - Live edge position in seconds
124
+ * @param thresholds - Enter/exit thresholds
125
+ * @param currentState - Current isNearLive state
126
+ * @returns New isNearLive state
127
+ */
128
+ export declare function calculateIsNearLive(currentTime: number, liveEdge: number, thresholds: LiveThresholds, currentState: boolean): boolean;
129
+ /**
130
+ * Determine if content is live based on available metadata.
131
+ *
132
+ * Priority:
133
+ * 1. Explicit isContentLive flag (highest priority)
134
+ * 2. MistServer stream type
135
+ * 3. Duration check (non-finite = live)
136
+ *
137
+ * @param isContentLive - Explicit live flag from content metadata
138
+ * @param mistStreamInfo - MistServer stream info
139
+ * @param duration - Video duration
140
+ * @returns true if content is live
141
+ */
142
+ export declare function isLiveContent(isContentLive?: boolean, mistStreamInfo?: MistStreamInfo, duration?: number): boolean;
@@ -0,0 +1,108 @@
1
+ /**
2
+ * StreamStateClient.ts
3
+ *
4
+ * Framework-agnostic client for polling MistServer stream status via WebSocket or HTTP.
5
+ * Extracted from useStreamState.ts for use in headless core.
6
+ */
7
+ import { TypedEventEmitter } from './EventEmitter';
8
+ import type { StreamState } from '../types';
9
+ export interface StreamStateClientConfig {
10
+ /** MistServer base URL (e.g., https://mist.example.com) */
11
+ mistBaseUrl: string;
12
+ /** Stream name to poll */
13
+ streamName: string;
14
+ /** Poll interval in ms for HTTP fallback (default: 3000) */
15
+ pollInterval?: number;
16
+ /** Use WebSocket if available (default: true) */
17
+ useWebSocket?: boolean;
18
+ }
19
+ export interface StreamStateClientEvents {
20
+ /** Emitted when stream state changes */
21
+ stateChange: {
22
+ state: StreamState;
23
+ };
24
+ /** Emitted when stream comes online */
25
+ online: void;
26
+ /** Emitted when stream goes offline */
27
+ offline: void;
28
+ /** Emitted on connection error */
29
+ error: {
30
+ error: string;
31
+ };
32
+ }
33
+ /**
34
+ * Client for polling MistServer stream status via WebSocket or HTTP.
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const client = new StreamStateClient({
39
+ * mistBaseUrl: 'https://mist.example.com',
40
+ * streamName: 'my-stream',
41
+ * });
42
+ *
43
+ * client.on('stateChange', ({ state }) => console.log('State:', state));
44
+ * client.on('online', () => console.log('Stream is online!'));
45
+ * client.on('offline', () => console.log('Stream is offline'));
46
+ *
47
+ * client.start();
48
+ * // ...later
49
+ * client.stop();
50
+ * ```
51
+ */
52
+ export declare class StreamStateClient extends TypedEventEmitter<StreamStateClientEvents> {
53
+ private config;
54
+ private state;
55
+ private ws;
56
+ private timers;
57
+ private isRunning;
58
+ private wasOnline;
59
+ private connectionId;
60
+ private static readonly CONNECTION_DEBOUNCE_MS;
61
+ constructor(config: StreamStateClientConfig);
62
+ /**
63
+ * Start polling/WebSocket connection.
64
+ * Always does initial HTTP poll to get full stream info (including sources),
65
+ * then connects WebSocket for real-time status updates.
66
+ *
67
+ * Debounced to prevent orphaned connections during rapid mount/unmount cycles.
68
+ */
69
+ start(): void;
70
+ /**
71
+ * Stop polling and close connections.
72
+ */
73
+ stop(): void;
74
+ /**
75
+ * Manual refresh - trigger an immediate poll.
76
+ */
77
+ refresh(): void;
78
+ /**
79
+ * Get the underlying WebSocket connection (for MistReporter integration).
80
+ * Returns null if WebSocket is not connected.
81
+ */
82
+ getSocket(): WebSocket | null;
83
+ /**
84
+ * Check if the WebSocket is connected and ready.
85
+ */
86
+ isSocketReady(): boolean;
87
+ /**
88
+ * Get current stream state.
89
+ */
90
+ getState(): StreamState;
91
+ /**
92
+ * Check if stream is online.
93
+ */
94
+ isOnline(): boolean;
95
+ /**
96
+ * Update configuration (stops and restarts if running).
97
+ */
98
+ updateConfig(config: Partial<StreamStateClientConfig>): void;
99
+ /**
100
+ * Clean up resources.
101
+ */
102
+ destroy(): void;
103
+ private connectWebSocket;
104
+ private pollHttp;
105
+ private processStreamInfo;
106
+ private setState;
107
+ }
108
+ export default StreamStateClient;
@@ -0,0 +1,111 @@
1
+ /**
2
+ * SubtitleManager - WebVTT subtitle track management
3
+ *
4
+ * Based on MistMetaPlayer's subtitle handling (wrappers/html5.js, webrtc.js).
5
+ * Manages text tracks on video elements with support for:
6
+ * - Loading WebVTT from MistServer URLs
7
+ * - Multiple subtitle track selection
8
+ * - Sync correction for WebRTC seek offsets
9
+ */
10
+ export interface SubtitleTrackInfo {
11
+ /** Track ID (from MistServer) */
12
+ id: string;
13
+ /** Display label */
14
+ label: string;
15
+ /** Language code (e.g., 'en', 'es') */
16
+ lang: string;
17
+ /** Source URL for WebVTT file */
18
+ src: string;
19
+ /** Whether this is the default track */
20
+ default?: boolean;
21
+ }
22
+ export interface SubtitleManagerConfig {
23
+ /** Base URL for MistServer (for constructing track URLs) */
24
+ mistBaseUrl?: string;
25
+ /** Stream name */
26
+ streamName?: string;
27
+ /** URL append string (auth tokens, etc.) */
28
+ urlAppend?: string;
29
+ /** Debug logging */
30
+ debug?: boolean;
31
+ }
32
+ /**
33
+ * SubtitleManager handles text track lifecycle on a video element
34
+ */
35
+ export declare class SubtitleManager {
36
+ private video;
37
+ private config;
38
+ private currentTrackId;
39
+ private seekOffset;
40
+ private debug;
41
+ private listeners;
42
+ constructor(config?: SubtitleManagerConfig);
43
+ /**
44
+ * Attach to a video element
45
+ */
46
+ attach(video: HTMLVideoElement): void;
47
+ /**
48
+ * Detach from video element
49
+ */
50
+ detach(): void;
51
+ /**
52
+ * Get available text tracks from the video element
53
+ */
54
+ getTextTracks(): TextTrack[];
55
+ /**
56
+ * Get all track elements from the video
57
+ */
58
+ getTrackElements(): HTMLTrackElement[];
59
+ /**
60
+ * Set the active subtitle track
61
+ * Pass null to disable subtitles
62
+ */
63
+ setSubtitle(track: SubtitleTrackInfo | null): void;
64
+ /**
65
+ * Build track URL with base URL and append params
66
+ */
67
+ private buildTrackUrl;
68
+ /**
69
+ * Create subtitle track info from MistServer track metadata
70
+ */
71
+ static createTrackInfo(trackId: string, label: string, lang: string, baseUrl: string, streamName: string): SubtitleTrackInfo;
72
+ /**
73
+ * Remove all track elements from video
74
+ */
75
+ removeAllTracks(): void;
76
+ /**
77
+ * Get currently active track ID
78
+ */
79
+ getCurrentTrackId(): string | null;
80
+ /**
81
+ * Set seek offset for WebRTC sync correction
82
+ * WebRTC playback has a seek offset that needs to be applied to subtitle timing
83
+ */
84
+ setSeekOffset(offset: number): void;
85
+ /**
86
+ * Correct subtitle timing based on seek offset
87
+ * This is needed for WebRTC where video.currentTime doesn't match actual playback position
88
+ */
89
+ private correctSubtitleSync;
90
+ /**
91
+ * Parse subtitle tracks from MistServer stream info
92
+ */
93
+ static parseTracksFromStreamInfo(streamInfo: {
94
+ meta?: {
95
+ tracks?: Record<string, {
96
+ type: string;
97
+ codec: string;
98
+ lang?: string;
99
+ }>;
100
+ };
101
+ }, baseUrl: string, streamName: string): SubtitleTrackInfo[];
102
+ /**
103
+ * Debug logging
104
+ */
105
+ private log;
106
+ /**
107
+ * Cleanup
108
+ */
109
+ destroy(): void;
110
+ }
111
+ export default SubtitleManager;
@@ -0,0 +1,79 @@
1
+ import type { PlaybackQuality, ContentType } from '../types';
2
+ export interface TelemetryReporterConfig {
3
+ /** Telemetry endpoint URL */
4
+ endpoint: string;
5
+ /** Auth token for endpoint */
6
+ authToken?: string;
7
+ /** Report interval in ms (default: 5000) */
8
+ interval?: number;
9
+ /** Batch size before flush (default: 1) */
10
+ batchSize?: number;
11
+ /** Content ID being played */
12
+ contentId: string;
13
+ /** Content type */
14
+ contentType: ContentType;
15
+ /** Player type name */
16
+ playerType: string;
17
+ /** Protocol being used */
18
+ protocol: string;
19
+ }
20
+ /**
21
+ * TelemetryReporter - Sends playback metrics to server
22
+ *
23
+ * Features:
24
+ * - Batched reporting at configurable interval
25
+ * - Retry with exponential backoff on failure
26
+ * - Uses navigator.sendBeacon() for reliable page unload reporting
27
+ * - Tracks errors during playback
28
+ */
29
+ export declare class TelemetryReporter {
30
+ private config;
31
+ private sessionId;
32
+ private intervalId;
33
+ private pendingPayloads;
34
+ private errors;
35
+ private stallCount;
36
+ private totalStallMs;
37
+ private lastStallStart;
38
+ private videoElement;
39
+ private qualityGetter;
40
+ private listeners;
41
+ constructor(config: TelemetryReporterConfig);
42
+ /**
43
+ * Start telemetry reporting
44
+ */
45
+ start(videoElement: HTMLVideoElement, qualityGetter?: () => PlaybackQuality | null): void;
46
+ /**
47
+ * Stop telemetry reporting
48
+ */
49
+ stop(): void;
50
+ /**
51
+ * Record a custom error
52
+ */
53
+ recordError(code: string, message: string): void;
54
+ /**
55
+ * Generate telemetry payload
56
+ */
57
+ private generatePayload;
58
+ /**
59
+ * Send telemetry report
60
+ */
61
+ private report;
62
+ /**
63
+ * Flush pending payloads (async)
64
+ */
65
+ private flush;
66
+ /**
67
+ * Flush synchronously using sendBeacon (for page unload)
68
+ */
69
+ private flushSync;
70
+ /**
71
+ * Get session ID
72
+ */
73
+ getSessionId(): string;
74
+ /**
75
+ * Check if reporting is active
76
+ */
77
+ isActive(): boolean;
78
+ }
79
+ export default TelemetryReporter;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * TimeFormat.ts
3
+ *
4
+ * Time formatting utilities for player controls.
5
+ * Used by React, Svelte, and Vanilla wrappers.
6
+ */
7
+ export interface TimeDisplayParams {
8
+ isLive: boolean;
9
+ currentTime: number;
10
+ duration: number;
11
+ liveEdge: number;
12
+ seekableStart: number;
13
+ /** Unix timestamp (ms) at stream time 0 - for wall-clock display */
14
+ unixoffset?: number;
15
+ }
16
+ /**
17
+ * Format seconds as MM:SS or HH:MM:SS.
18
+ *
19
+ * @param seconds - Time in seconds
20
+ * @returns Formatted time string, or "LIVE" for invalid input
21
+ *
22
+ * @example
23
+ * formatTime(65) // "01:05"
24
+ * formatTime(3665) // "1:01:05"
25
+ * formatTime(-1) // "LIVE"
26
+ * formatTime(NaN) // "LIVE"
27
+ */
28
+ export declare function formatTime(seconds: number): string;
29
+ /**
30
+ * Format a Date as wall-clock time (HH:MM:SS).
31
+ *
32
+ * @param date - Date object
33
+ * @returns Formatted time string in HH:MM:SS format
34
+ *
35
+ * @example
36
+ * formatClockTime(new Date('2024-01-15T14:30:45')) // "14:30:45"
37
+ */
38
+ export declare function formatClockTime(date: Date): string;
39
+ /**
40
+ * Format time display for player controls.
41
+ *
42
+ * For live streams:
43
+ * - With unixoffset: Shows actual wall-clock time (HH:MM:SS)
44
+ * - With seekable window: Shows time behind live (-MM:SS) or "LIVE"
45
+ * - Fallback: Shows elapsed time
46
+ *
47
+ * For VOD:
48
+ * - Shows "current / duration" (MM:SS / MM:SS)
49
+ *
50
+ * @param params - Display parameters
51
+ * @returns Formatted time display string
52
+ *
53
+ * @example
54
+ * // Live with unixoffset
55
+ * formatTimeDisplay({ isLive: true, currentTime: 60, unixoffset: 1705330245000, ... })
56
+ * // "14:30:45"
57
+ *
58
+ * // Live behind
59
+ * formatTimeDisplay({ isLive: true, currentTime: 50, liveEdge: 60, ... })
60
+ * // "-00:10"
61
+ *
62
+ * // VOD
63
+ * formatTimeDisplay({ isLive: false, currentTime: 65, duration: 300, ... })
64
+ * // "01:05 / 05:00"
65
+ */
66
+ export declare function formatTimeDisplay(params: TimeDisplayParams): string;
67
+ /**
68
+ * Format time for seek bar tooltip.
69
+ * For live streams, can show time relative to live edge.
70
+ *
71
+ * @param time - Time position in seconds
72
+ * @param isLive - Whether stream is live
73
+ * @param liveEdge - Live edge position (for relative display)
74
+ * @returns Formatted tooltip time
75
+ */
76
+ export declare function formatTooltipTime(time: number, isLive: boolean, liveEdge?: number): string;
77
+ /**
78
+ * Format duration for display (e.g., in stats panel).
79
+ * Handles edge cases like infinite duration for live streams.
80
+ *
81
+ * @param duration - Duration in seconds
82
+ * @param isLive - Whether content is live
83
+ * @returns Formatted duration string
84
+ */
85
+ export declare function formatDuration(duration: number, isLive?: boolean): string;
86
+ /**
87
+ * Parse time string (HH:MM:SS or MM:SS) to seconds.
88
+ *
89
+ * @param timeStr - Time string to parse
90
+ * @returns Time in seconds, or NaN if invalid
91
+ *
92
+ * @example
93
+ * parseTime("01:30") // 90
94
+ * parseTime("1:30:45") // 5445
95
+ * parseTime("invalid") // NaN
96
+ */
97
+ export declare function parseTime(timeStr: string): number;
@@ -0,0 +1,83 @@
1
+ /**
2
+ * TimerManager - Centralized timer management for memory leak prevention
3
+ *
4
+ * Tracks all setTimeout/setInterval calls and provides bulk cleanup.
5
+ * Based on MistMetaPlayer's MistVideo.timers pattern.
6
+ *
7
+ * Usage:
8
+ * ```ts
9
+ * const timers = new TimerManager();
10
+ *
11
+ * // Start a timeout
12
+ * const id = timers.start(() => console.log('fired'), 1000);
13
+ *
14
+ * // Start an interval
15
+ * const intervalId = timers.startInterval(() => console.log('tick'), 500);
16
+ *
17
+ * // Stop a specific timer
18
+ * timers.stop(id);
19
+ *
20
+ * // Stop all timers (on cleanup/destroy)
21
+ * timers.stopAll();
22
+ * ```
23
+ */
24
+ export declare class TimerManager {
25
+ private timers;
26
+ private nextId;
27
+ private debug;
28
+ constructor(options?: {
29
+ debug?: boolean;
30
+ });
31
+ /**
32
+ * Start a timeout
33
+ * @param callback Function to call after delay
34
+ * @param delay Delay in milliseconds
35
+ * @param label Optional label for debugging
36
+ * @returns Timer ID (internal, not the native timeout ID)
37
+ */
38
+ start(callback: () => void, delay: number, label?: string): number;
39
+ /**
40
+ * Start an interval
41
+ * @param callback Function to call repeatedly
42
+ * @param interval Interval in milliseconds
43
+ * @param label Optional label for debugging
44
+ * @returns Timer ID (internal, not the native interval ID)
45
+ */
46
+ startInterval(callback: () => void, interval: number, label?: string): number;
47
+ /**
48
+ * Stop a specific timer
49
+ * @param internalId The timer ID returned by start() or startInterval()
50
+ */
51
+ stop(internalId: number): boolean;
52
+ /**
53
+ * Stop all active timers
54
+ * Call this on component unmount/destroy to prevent memory leaks
55
+ */
56
+ stopAll(): void;
57
+ /**
58
+ * Get count of active timers
59
+ */
60
+ get activeCount(): number;
61
+ /**
62
+ * Check if a timer is active
63
+ */
64
+ isActive(internalId: number): boolean;
65
+ /**
66
+ * Get remaining time for a timeout (0 for intervals or expired)
67
+ */
68
+ getRemainingTime(internalId: number): number;
69
+ /**
70
+ * Get debug info about all active timers
71
+ */
72
+ getDebugInfo(): Array<{
73
+ id: number;
74
+ type: 'timeout' | 'interval';
75
+ label?: string;
76
+ remainingMs?: number;
77
+ }>;
78
+ /**
79
+ * Cleanup - alias for stopAll()
80
+ */
81
+ destroy(): void;
82
+ }
83
+ export default TimerManager;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * UrlUtils - URL manipulation utilities
3
+ *
4
+ * Based on MistMetaPlayer's urlappend functionality.
5
+ * Provides helpers for appending query parameters to URLs.
6
+ */
7
+ /**
8
+ * Append query parameters to a URL
9
+ * Handles URLs that already have query parameters
10
+ *
11
+ * @param url - Base URL
12
+ * @param params - Parameters to append (string or object)
13
+ * @returns URL with appended parameters
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * appendUrlParams('https://example.com/video.m3u8', 'token=abc&session=123')
18
+ * // => 'https://example.com/video.m3u8?token=abc&session=123'
19
+ *
20
+ * appendUrlParams('https://example.com/video.m3u8?existing=param', 'token=abc')
21
+ * // => 'https://example.com/video.m3u8?existing=param&token=abc'
22
+ *
23
+ * appendUrlParams('https://example.com/video.m3u8', { token: 'abc', session: '123' })
24
+ * // => 'https://example.com/video.m3u8?token=abc&session=123'
25
+ * ```
26
+ */
27
+ export declare function appendUrlParams(url: string, params: string | Record<string, string | number | boolean | undefined | null>): string;
28
+ /**
29
+ * Parse query parameters from a URL
30
+ *
31
+ * @param url - URL to parse
32
+ * @returns Object with query parameters
33
+ */
34
+ export declare function parseUrlParams(url: string): Record<string, string>;
35
+ /**
36
+ * Remove query parameters from a URL
37
+ *
38
+ * @param url - URL to strip
39
+ * @returns URL without query parameters
40
+ */
41
+ export declare function stripUrlParams(url: string): string;
42
+ /**
43
+ * Build a URL with query parameters
44
+ *
45
+ * @param baseUrl - Base URL
46
+ * @param params - Query parameters
47
+ * @returns Complete URL
48
+ */
49
+ export declare function buildUrl(baseUrl: string, params: Record<string, string | number | boolean | undefined | null>): string;
50
+ /**
51
+ * Check if URL uses secure protocol (https/wss)
52
+ */
53
+ export declare function isSecureUrl(url: string): boolean;
54
+ /**
55
+ * Convert HTTP URL to WebSocket URL
56
+ * http:// -> ws://
57
+ * https:// -> wss://
58
+ */
59
+ export declare function httpToWs(url: string): string;
60
+ /**
61
+ * Convert WebSocket URL to HTTP URL
62
+ * ws:// -> http://
63
+ * wss:// -> https://
64
+ */
65
+ export declare function wsToHttp(url: string): string;
66
+ /**
67
+ * Ensure URL uses the same protocol as the current page
68
+ * Useful for avoiding mixed content issues
69
+ */
70
+ export declare function matchPageProtocol(url: string): string;
71
+ declare const _default: {
72
+ appendUrlParams: typeof appendUrlParams;
73
+ parseUrlParams: typeof parseUrlParams;
74
+ stripUrlParams: typeof stripUrlParams;
75
+ buildUrl: typeof buildUrl;
76
+ isSecureUrl: typeof isSecureUrl;
77
+ httpToWs: typeof httpToWs;
78
+ wsToHttp: typeof wsToHttp;
79
+ matchPageProtocol: typeof matchPageProtocol;
80
+ };
81
+ export default _default;