@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.
- package/dist/cjs/index.js +19493 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.js +19398 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/player.css +2140 -0
- package/dist/types/core/ABRController.d.ts +164 -0
- package/dist/types/core/CodecUtils.d.ts +54 -0
- package/dist/types/core/Disposable.d.ts +61 -0
- package/dist/types/core/EventEmitter.d.ts +73 -0
- package/dist/types/core/GatewayClient.d.ts +144 -0
- package/dist/types/core/InteractionController.d.ts +121 -0
- package/dist/types/core/LiveDurationProxy.d.ts +102 -0
- package/dist/types/core/MetaTrackManager.d.ts +220 -0
- package/dist/types/core/MistReporter.d.ts +163 -0
- package/dist/types/core/MistSignaling.d.ts +148 -0
- package/dist/types/core/PlayerController.d.ts +665 -0
- package/dist/types/core/PlayerInterface.d.ts +230 -0
- package/dist/types/core/PlayerManager.d.ts +182 -0
- package/dist/types/core/PlayerRegistry.d.ts +27 -0
- package/dist/types/core/QualityMonitor.d.ts +184 -0
- package/dist/types/core/ScreenWakeLockManager.d.ts +70 -0
- package/dist/types/core/SeekingUtils.d.ts +142 -0
- package/dist/types/core/StreamStateClient.d.ts +108 -0
- package/dist/types/core/SubtitleManager.d.ts +111 -0
- package/dist/types/core/TelemetryReporter.d.ts +79 -0
- package/dist/types/core/TimeFormat.d.ts +97 -0
- package/dist/types/core/TimerManager.d.ts +83 -0
- package/dist/types/core/UrlUtils.d.ts +81 -0
- package/dist/types/core/detector.d.ts +149 -0
- package/dist/types/core/index.d.ts +49 -0
- package/dist/types/core/scorer.d.ts +167 -0
- package/dist/types/core/selector.d.ts +9 -0
- package/dist/types/index.d.ts +45 -0
- package/dist/types/lib/utils.d.ts +2 -0
- package/dist/types/players/DashJsPlayer.d.ts +102 -0
- package/dist/types/players/HlsJsPlayer.d.ts +70 -0
- package/dist/types/players/MewsWsPlayer/SourceBufferManager.d.ts +119 -0
- package/dist/types/players/MewsWsPlayer/WebSocketManager.d.ts +60 -0
- package/dist/types/players/MewsWsPlayer/index.d.ts +220 -0
- package/dist/types/players/MewsWsPlayer/types.d.ts +89 -0
- package/dist/types/players/MistPlayer.d.ts +25 -0
- package/dist/types/players/MistWebRTCPlayer/index.d.ts +133 -0
- package/dist/types/players/NativePlayer.d.ts +143 -0
- package/dist/types/players/VideoJsPlayer.d.ts +59 -0
- package/dist/types/players/WebCodecsPlayer/JitterBuffer.d.ts +118 -0
- package/dist/types/players/WebCodecsPlayer/LatencyProfiles.d.ts +64 -0
- package/dist/types/players/WebCodecsPlayer/RawChunkParser.d.ts +63 -0
- package/dist/types/players/WebCodecsPlayer/SyncController.d.ts +174 -0
- package/dist/types/players/WebCodecsPlayer/WebSocketController.d.ts +164 -0
- package/dist/types/players/WebCodecsPlayer/index.d.ts +149 -0
- package/dist/types/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.d.ts +105 -0
- package/dist/types/players/WebCodecsPlayer/types.d.ts +395 -0
- package/dist/types/players/WebCodecsPlayer/worker/decoder.worker.d.ts +13 -0
- package/dist/types/players/WebCodecsPlayer/worker/types.d.ts +197 -0
- package/dist/types/players/index.d.ts +14 -0
- package/dist/types/styles/index.d.ts +11 -0
- package/dist/types/types.d.ts +363 -0
- package/dist/types/vanilla/FrameWorksPlayer.d.ts +143 -0
- package/dist/types/vanilla/index.d.ts +19 -0
- package/dist/workers/decoder.worker.js +989 -0
- package/dist/workers/decoder.worker.js.map +1 -0
- package/package.json +80 -0
- package/src/core/ABRController.ts +550 -0
- package/src/core/CodecUtils.ts +257 -0
- package/src/core/Disposable.ts +120 -0
- package/src/core/EventEmitter.ts +113 -0
- package/src/core/GatewayClient.ts +439 -0
- package/src/core/InteractionController.ts +712 -0
- package/src/core/LiveDurationProxy.ts +270 -0
- package/src/core/MetaTrackManager.ts +753 -0
- package/src/core/MistReporter.ts +543 -0
- package/src/core/MistSignaling.ts +346 -0
- package/src/core/PlayerController.ts +2829 -0
- package/src/core/PlayerInterface.ts +432 -0
- package/src/core/PlayerManager.ts +900 -0
- package/src/core/PlayerRegistry.ts +149 -0
- package/src/core/QualityMonitor.ts +597 -0
- package/src/core/ScreenWakeLockManager.ts +163 -0
- package/src/core/SeekingUtils.ts +364 -0
- package/src/core/StreamStateClient.ts +457 -0
- package/src/core/SubtitleManager.ts +297 -0
- package/src/core/TelemetryReporter.ts +308 -0
- package/src/core/TimeFormat.ts +205 -0
- package/src/core/TimerManager.ts +209 -0
- package/src/core/UrlUtils.ts +179 -0
- package/src/core/detector.ts +382 -0
- package/src/core/index.ts +140 -0
- package/src/core/scorer.ts +553 -0
- package/src/core/selector.ts +16 -0
- package/src/global.d.ts +11 -0
- package/src/index.ts +75 -0
- package/src/lib/utils.ts +6 -0
- package/src/players/DashJsPlayer.ts +642 -0
- package/src/players/HlsJsPlayer.ts +483 -0
- package/src/players/MewsWsPlayer/SourceBufferManager.ts +572 -0
- package/src/players/MewsWsPlayer/WebSocketManager.ts +241 -0
- package/src/players/MewsWsPlayer/index.ts +1065 -0
- package/src/players/MewsWsPlayer/types.ts +106 -0
- package/src/players/MistPlayer.ts +188 -0
- package/src/players/MistWebRTCPlayer/index.ts +703 -0
- package/src/players/NativePlayer.ts +820 -0
- package/src/players/VideoJsPlayer.ts +643 -0
- package/src/players/WebCodecsPlayer/JitterBuffer.ts +299 -0
- package/src/players/WebCodecsPlayer/LatencyProfiles.ts +151 -0
- package/src/players/WebCodecsPlayer/RawChunkParser.ts +151 -0
- package/src/players/WebCodecsPlayer/SyncController.ts +456 -0
- package/src/players/WebCodecsPlayer/WebSocketController.ts +564 -0
- package/src/players/WebCodecsPlayer/index.ts +1650 -0
- package/src/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.ts +379 -0
- package/src/players/WebCodecsPlayer/types.ts +542 -0
- package/src/players/WebCodecsPlayer/worker/decoder.worker.ts +1360 -0
- package/src/players/WebCodecsPlayer/worker/types.ts +276 -0
- package/src/players/index.ts +22 -0
- package/src/styles/animations.css +21 -0
- package/src/styles/index.ts +52 -0
- package/src/styles/player.css +2126 -0
- package/src/styles/tailwind.css +1015 -0
- package/src/types.ts +421 -0
- package/src/vanilla/FrameWorksPlayer.ts +367 -0
- package/src/vanilla/index.ts +22 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket Manager for MEWS Player
|
|
3
|
+
*
|
|
4
|
+
* Handles WebSocket connection, reconnection with exponential backoff,
|
|
5
|
+
* message sending, and typed message listeners.
|
|
6
|
+
*
|
|
7
|
+
* Ported from reference: mews.js:387-883
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { WebSocketManagerOptions, MewsMessage, MewsMessageListener } from './types';
|
|
11
|
+
|
|
12
|
+
export class WebSocketManager {
|
|
13
|
+
private ws: WebSocket | null = null;
|
|
14
|
+
private url: string;
|
|
15
|
+
private maxReconnectAttempts: number;
|
|
16
|
+
private reconnectAttempts = 0;
|
|
17
|
+
private reconnectTimer: ReturnType<typeof setTimeout> | null = null;
|
|
18
|
+
private wasConnected = false;
|
|
19
|
+
private isDestroyed = false;
|
|
20
|
+
|
|
21
|
+
// Track pending retry timers so they can be cancelled on destroy
|
|
22
|
+
private pendingRetryTimers: Set<ReturnType<typeof setTimeout>> = new Set();
|
|
23
|
+
|
|
24
|
+
// Message listener registry (ported from mews.js:440-451)
|
|
25
|
+
// Allows multiple listeners per message type for proper seek/play sequencing
|
|
26
|
+
private listeners: Record<string, MewsMessageListener[]> = {};
|
|
27
|
+
|
|
28
|
+
private onMessage: (data: ArrayBuffer | string) => void;
|
|
29
|
+
private onOpen: () => void;
|
|
30
|
+
private onClose: () => void;
|
|
31
|
+
private onError: (message: string) => void;
|
|
32
|
+
|
|
33
|
+
constructor(options: WebSocketManagerOptions) {
|
|
34
|
+
this.url = options.url;
|
|
35
|
+
this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;
|
|
36
|
+
this.onMessage = options.onMessage;
|
|
37
|
+
this.onOpen = options.onOpen;
|
|
38
|
+
this.onClose = options.onClose;
|
|
39
|
+
this.onError = options.onError;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
connect(): void {
|
|
43
|
+
if (this.isDestroyed) return;
|
|
44
|
+
|
|
45
|
+
// Protocol mismatch check (non-fatal warning)
|
|
46
|
+
try {
|
|
47
|
+
const pageProto = window.location.protocol.replace(/^http/, 'ws');
|
|
48
|
+
const srcProto = new URL(this.url, window.location.href).protocol;
|
|
49
|
+
if (pageProto !== srcProto) {
|
|
50
|
+
this.onError(`Protocol mismatch ${pageProto} vs ${srcProto}`);
|
|
51
|
+
}
|
|
52
|
+
} catch {}
|
|
53
|
+
|
|
54
|
+
const ws = new WebSocket(this.url);
|
|
55
|
+
ws.binaryType = 'arraybuffer';
|
|
56
|
+
this.ws = ws;
|
|
57
|
+
|
|
58
|
+
ws.onopen = () => {
|
|
59
|
+
this.wasConnected = true;
|
|
60
|
+
this.reconnectAttempts = 0;
|
|
61
|
+
this.clearReconnectTimer();
|
|
62
|
+
this.onOpen();
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
ws.onmessage = (e: MessageEvent<ArrayBuffer | string>) => {
|
|
66
|
+
this.onMessage(e.data);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
ws.onerror = () => {
|
|
70
|
+
this.onError('WebSocket error');
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
ws.onclose = () => {
|
|
74
|
+
if (this.isDestroyed) return;
|
|
75
|
+
|
|
76
|
+
if (this.wasConnected && this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
77
|
+
const backoff = Math.min(5000, 500 * Math.pow(2, this.reconnectAttempts));
|
|
78
|
+
this.reconnectAttempts++;
|
|
79
|
+
this.reconnectTimer = setTimeout(() => {
|
|
80
|
+
if (!this.isDestroyed) {
|
|
81
|
+
this.connect();
|
|
82
|
+
}
|
|
83
|
+
}, backoff);
|
|
84
|
+
} else {
|
|
85
|
+
this.onClose();
|
|
86
|
+
this.onError('WebSocket closed');
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Send a command with retry logic (3.3.6).
|
|
93
|
+
* If not connected, will retry up to 5 times with 500ms delay.
|
|
94
|
+
* If connection is closing/closed, will attempt reconnect then retry.
|
|
95
|
+
*/
|
|
96
|
+
send(cmd: object, retry = 0): boolean {
|
|
97
|
+
const MAX_RETRIES = 5;
|
|
98
|
+
const RETRY_DELAY = 500;
|
|
99
|
+
|
|
100
|
+
// Early exit if destroyed - don't schedule any retries
|
|
101
|
+
if (this.isDestroyed) return false;
|
|
102
|
+
|
|
103
|
+
if (retry > MAX_RETRIES) {
|
|
104
|
+
this.onError('Too many send retries');
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Helper to schedule retry with tracking
|
|
109
|
+
const scheduleRetry = (delay: number) => {
|
|
110
|
+
const timer = setTimeout(() => {
|
|
111
|
+
this.pendingRetryTimers.delete(timer);
|
|
112
|
+
if (!this.isDestroyed) {
|
|
113
|
+
this.send(cmd, retry + 1);
|
|
114
|
+
}
|
|
115
|
+
}, delay);
|
|
116
|
+
this.pendingRetryTimers.add(timer);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
if (!this.ws) {
|
|
120
|
+
// No socket at all, try to connect and retry
|
|
121
|
+
if (!this.isDestroyed && retry < MAX_RETRIES) {
|
|
122
|
+
scheduleRetry(RETRY_DELAY);
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (this.ws.readyState < WebSocket.OPEN) {
|
|
128
|
+
// Still connecting, wait and retry (if not destroyed)
|
|
129
|
+
if (!this.isDestroyed && retry < MAX_RETRIES) {
|
|
130
|
+
scheduleRetry(RETRY_DELAY);
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (this.ws.readyState >= WebSocket.CLOSING) {
|
|
136
|
+
// Closing or closed, trigger reconnect and retry
|
|
137
|
+
if (!this.isDestroyed && retry < MAX_RETRIES) {
|
|
138
|
+
this.connect();
|
|
139
|
+
scheduleRetry(RETRY_DELAY * 2);
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
this.ws.send(JSON.stringify(cmd));
|
|
146
|
+
return true;
|
|
147
|
+
} catch {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private clearReconnectTimer(): void {
|
|
153
|
+
if (this.reconnectTimer) {
|
|
154
|
+
clearTimeout(this.reconnectTimer);
|
|
155
|
+
this.reconnectTimer = null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
destroy(): void {
|
|
160
|
+
console.debug('[WebSocketManager] destroy() called');
|
|
161
|
+
this.isDestroyed = true;
|
|
162
|
+
this.clearReconnectTimer();
|
|
163
|
+
|
|
164
|
+
// Cancel ALL pending retry timers to prevent any scheduled sends
|
|
165
|
+
for (const timer of this.pendingRetryTimers) {
|
|
166
|
+
clearTimeout(timer);
|
|
167
|
+
}
|
|
168
|
+
this.pendingRetryTimers.clear();
|
|
169
|
+
|
|
170
|
+
// Clear all listeners to prevent memory leaks
|
|
171
|
+
this.listeners = {};
|
|
172
|
+
|
|
173
|
+
if (this.ws) {
|
|
174
|
+
try {
|
|
175
|
+
this.ws.close();
|
|
176
|
+
} catch {}
|
|
177
|
+
this.ws = null;
|
|
178
|
+
}
|
|
179
|
+
console.debug('[WebSocketManager] destroy() completed');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
isConnected(): boolean {
|
|
183
|
+
return this.ws?.readyState === WebSocket.OPEN;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Add a listener for a specific message type.
|
|
188
|
+
* Ported from mews.js:441-444
|
|
189
|
+
*
|
|
190
|
+
* @param type - Message type to listen for (e.g., 'on_time', 'codec_data', 'seek')
|
|
191
|
+
* @param callback - Function to call when message is received
|
|
192
|
+
*/
|
|
193
|
+
addListener(type: string, callback: MewsMessageListener): void {
|
|
194
|
+
if (!(type in this.listeners)) {
|
|
195
|
+
this.listeners[type] = [];
|
|
196
|
+
}
|
|
197
|
+
this.listeners[type].push(callback);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Remove a listener for a specific message type.
|
|
202
|
+
* Ported from mews.js:445-450
|
|
203
|
+
*
|
|
204
|
+
* @param type - Message type
|
|
205
|
+
* @param callback - The exact callback function to remove
|
|
206
|
+
* @returns true if listener was found and removed
|
|
207
|
+
*/
|
|
208
|
+
removeListener(type: string, callback: MewsMessageListener): boolean {
|
|
209
|
+
if (!(type in this.listeners)) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
const index = this.listeners[type].indexOf(callback);
|
|
213
|
+
if (index < 0) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
this.listeners[type].splice(index, 1);
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Notify all listeners for a given message type.
|
|
222
|
+
* Called internally when a JSON message is received.
|
|
223
|
+
* Ported from mews.js:795-799
|
|
224
|
+
*
|
|
225
|
+
* @param msg - Parsed message object
|
|
226
|
+
*/
|
|
227
|
+
notifyListeners(msg: MewsMessage): void {
|
|
228
|
+
if (msg.type in this.listeners) {
|
|
229
|
+
// Iterate backwards in case listeners remove themselves
|
|
230
|
+
const callbacks = this.listeners[msg.type];
|
|
231
|
+
for (let i = callbacks.length - 1; i >= 0; i--) {
|
|
232
|
+
try {
|
|
233
|
+
callbacks[i](msg);
|
|
234
|
+
} catch (e) {
|
|
235
|
+
// Don't let one listener crash others
|
|
236
|
+
console.error('MEWS listener error:', e);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|