@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,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MistSignaling - WebSocket signaling for MistServer's native WebRTC protocol
|
|
3
|
+
*
|
|
4
|
+
* Protocol messages (from MistServer):
|
|
5
|
+
* - on_connected: WebSocket opened successfully
|
|
6
|
+
* - on_disconnected: WebSocket closed
|
|
7
|
+
* - on_answer_sdp: SDP answer received, { result: boolean, answer_sdp: string }
|
|
8
|
+
* - on_time: Time update { current: ms, end: ms, begin: ms, tracks: string[] }
|
|
9
|
+
* - on_stop: Stream ended
|
|
10
|
+
* - on_error: Error occurred { message: string }
|
|
11
|
+
*
|
|
12
|
+
* Protocol messages (to MistServer):
|
|
13
|
+
* - offer_sdp: SDP offer { offer_sdp: string }
|
|
14
|
+
* - seek: Seek to position { seek_time: number | "live" }
|
|
15
|
+
* - hold: Pause playback
|
|
16
|
+
* - stop: Stop playback
|
|
17
|
+
* - tracks: Select tracks { video: string, audio: string }
|
|
18
|
+
* - set_speed: Set playback rate { play_rate: number | "auto" }
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { TypedEventEmitter } from './EventEmitter';
|
|
22
|
+
|
|
23
|
+
export interface MistSignalingConfig {
|
|
24
|
+
/** WebSocket URL (will convert http to ws) */
|
|
25
|
+
url: string;
|
|
26
|
+
/** Connection timeout in ms (default: 5000) */
|
|
27
|
+
timeout?: number;
|
|
28
|
+
/** Callback for debug logging */
|
|
29
|
+
onLog?: (message: string) => void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface MistTimeUpdate {
|
|
33
|
+
/** Current playback position in ms */
|
|
34
|
+
current: number;
|
|
35
|
+
/** End position in ms (0 for live) */
|
|
36
|
+
end: number;
|
|
37
|
+
/** Begin position in ms (buffer start) */
|
|
38
|
+
begin: number;
|
|
39
|
+
/** Currently active track IDs */
|
|
40
|
+
tracks?: string[];
|
|
41
|
+
/** Whether playback is paused */
|
|
42
|
+
paused?: boolean;
|
|
43
|
+
/** Whether at live point */
|
|
44
|
+
live_point?: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface MistSignalingEvents {
|
|
48
|
+
/** Connection established */
|
|
49
|
+
'connected': void;
|
|
50
|
+
/** Connection closed */
|
|
51
|
+
'disconnected': { code: number };
|
|
52
|
+
/** SDP answer received */
|
|
53
|
+
'answer_sdp': { result: boolean; answer_sdp: string };
|
|
54
|
+
/** Time/track update */
|
|
55
|
+
'time_update': MistTimeUpdate;
|
|
56
|
+
/** Seek completed */
|
|
57
|
+
'seeked': { live_point?: boolean };
|
|
58
|
+
/** Playback speed changed */
|
|
59
|
+
'speed_changed': { play_rate: number; play_rate_curr: number };
|
|
60
|
+
/** Stream ended */
|
|
61
|
+
'stopped': void;
|
|
62
|
+
/** Error occurred */
|
|
63
|
+
'error': { message: string };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type MistSignalingState = 'connecting' | 'connected' | 'disconnected' | 'closed';
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* MistSignaling handles WebSocket communication with MistServer for WebRTC
|
|
70
|
+
*/
|
|
71
|
+
export class MistSignaling extends TypedEventEmitter<MistSignalingEvents> {
|
|
72
|
+
private ws: WebSocket | null = null;
|
|
73
|
+
private url: string;
|
|
74
|
+
private timeout: number;
|
|
75
|
+
private timeoutId: ReturnType<typeof setTimeout> | null = null;
|
|
76
|
+
private onLog: (message: string) => void;
|
|
77
|
+
private _state: MistSignalingState = 'disconnected';
|
|
78
|
+
|
|
79
|
+
// Promise for seek operation
|
|
80
|
+
public seekPromise: {
|
|
81
|
+
resolve: (msg: string) => void;
|
|
82
|
+
reject: (msg: string) => void;
|
|
83
|
+
} | null = null;
|
|
84
|
+
|
|
85
|
+
constructor(config: MistSignalingConfig) {
|
|
86
|
+
super();
|
|
87
|
+
// Convert http(s) to ws(s)
|
|
88
|
+
this.url = config.url.replace(/^http/, 'ws');
|
|
89
|
+
this.timeout = config.timeout ?? 5000;
|
|
90
|
+
this.onLog = config.onLog ?? (() => {});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get current connection state
|
|
95
|
+
*/
|
|
96
|
+
get state(): MistSignalingState {
|
|
97
|
+
return this._state;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Check if connected
|
|
102
|
+
*/
|
|
103
|
+
get isConnected(): boolean {
|
|
104
|
+
return this._state === 'connected';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Connect to MistServer WebSocket
|
|
109
|
+
*/
|
|
110
|
+
connect(): void {
|
|
111
|
+
if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) {
|
|
112
|
+
this.onLog('Already connected or connecting');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this._state = 'connecting';
|
|
117
|
+
this.onLog(`Connecting to ${this.url}`);
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
this.ws = new WebSocket(this.url);
|
|
121
|
+
} catch (e) {
|
|
122
|
+
this.onLog(`Failed to create WebSocket: ${e}`);
|
|
123
|
+
this._state = 'disconnected';
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Connection timeout
|
|
128
|
+
this.timeoutId = setTimeout(() => {
|
|
129
|
+
if (this.ws && this.ws.readyState === WebSocket.CONNECTING) {
|
|
130
|
+
this.onLog('WebSocket connection timeout');
|
|
131
|
+
this.ws.close();
|
|
132
|
+
this._state = 'disconnected';
|
|
133
|
+
this.emit('error', { message: 'Connection timeout' });
|
|
134
|
+
}
|
|
135
|
+
}, this.timeout);
|
|
136
|
+
|
|
137
|
+
this.ws.onopen = () => {
|
|
138
|
+
if (this.timeoutId) {
|
|
139
|
+
clearTimeout(this.timeoutId);
|
|
140
|
+
this.timeoutId = null;
|
|
141
|
+
}
|
|
142
|
+
this._state = 'connected';
|
|
143
|
+
this.onLog('WebSocket connected');
|
|
144
|
+
this.emit('connected', undefined);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
this.ws.onmessage = (event) => {
|
|
148
|
+
try {
|
|
149
|
+
const cmd = JSON.parse(event.data);
|
|
150
|
+
this.handleMessage(cmd);
|
|
151
|
+
} catch (err) {
|
|
152
|
+
this.onLog(`Failed to parse message: ${err}`);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
this.ws.onclose = (event) => {
|
|
157
|
+
if (this.timeoutId) {
|
|
158
|
+
clearTimeout(this.timeoutId);
|
|
159
|
+
this.timeoutId = null;
|
|
160
|
+
}
|
|
161
|
+
this._state = 'closed';
|
|
162
|
+
this.onLog(`WebSocket closed (code: ${event.code})`);
|
|
163
|
+
this.emit('disconnected', { code: event.code });
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
this.ws.onerror = (event) => {
|
|
167
|
+
this.onLog(`WebSocket error: ${event}`);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Handle incoming message from MistServer
|
|
173
|
+
*/
|
|
174
|
+
private handleMessage(cmd: Record<string, unknown>): void {
|
|
175
|
+
const type = cmd.type as string;
|
|
176
|
+
|
|
177
|
+
switch (type) {
|
|
178
|
+
case 'on_connected':
|
|
179
|
+
// Already handled by onopen
|
|
180
|
+
break;
|
|
181
|
+
|
|
182
|
+
case 'on_disconnected':
|
|
183
|
+
this._state = 'disconnected';
|
|
184
|
+
this.emit('disconnected', { code: (cmd.code as number) || 0 });
|
|
185
|
+
break;
|
|
186
|
+
|
|
187
|
+
case 'on_answer_sdp':
|
|
188
|
+
this.emit('answer_sdp', {
|
|
189
|
+
result: cmd.result as boolean,
|
|
190
|
+
answer_sdp: cmd.answer_sdp as string,
|
|
191
|
+
});
|
|
192
|
+
break;
|
|
193
|
+
|
|
194
|
+
case 'on_time':
|
|
195
|
+
this.emit('time_update', {
|
|
196
|
+
current: cmd.current as number,
|
|
197
|
+
end: cmd.end as number,
|
|
198
|
+
begin: cmd.begin as number,
|
|
199
|
+
tracks: cmd.tracks as string[] | undefined,
|
|
200
|
+
paused: cmd.paused as boolean | undefined,
|
|
201
|
+
live_point: cmd.live_point as boolean | undefined,
|
|
202
|
+
});
|
|
203
|
+
break;
|
|
204
|
+
|
|
205
|
+
case 'seek':
|
|
206
|
+
this.emit('seeked', {
|
|
207
|
+
live_point: (cmd as Record<string, unknown>).live_point as boolean | undefined,
|
|
208
|
+
});
|
|
209
|
+
// Resolve seek promise if pending
|
|
210
|
+
if (this.seekPromise) {
|
|
211
|
+
this.seekPromise.resolve('Seeked');
|
|
212
|
+
this.seekPromise = null;
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
|
|
216
|
+
case 'set_speed':
|
|
217
|
+
this.emit('speed_changed', {
|
|
218
|
+
play_rate: (cmd as Record<string, unknown>).play_rate as number,
|
|
219
|
+
play_rate_curr: (cmd as Record<string, unknown>).play_rate_curr as number,
|
|
220
|
+
});
|
|
221
|
+
break;
|
|
222
|
+
|
|
223
|
+
case 'on_stop':
|
|
224
|
+
this.emit('stopped', undefined);
|
|
225
|
+
break;
|
|
226
|
+
|
|
227
|
+
case 'on_error':
|
|
228
|
+
this.emit('error', { message: cmd.message as string });
|
|
229
|
+
break;
|
|
230
|
+
|
|
231
|
+
default:
|
|
232
|
+
this.onLog(`Unhandled message type: ${type}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Send a message to MistServer
|
|
238
|
+
*/
|
|
239
|
+
send(cmd: Record<string, unknown>): boolean {
|
|
240
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
241
|
+
this.onLog('Cannot send: WebSocket not connected');
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
this.ws.send(JSON.stringify(cmd));
|
|
247
|
+
return true;
|
|
248
|
+
} catch (e) {
|
|
249
|
+
this.onLog(`Failed to send message: ${e}`);
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Send SDP offer to MistServer
|
|
256
|
+
*/
|
|
257
|
+
sendOfferSDP(sdp: string): boolean {
|
|
258
|
+
return this.send({ type: 'offer_sdp', offer_sdp: sdp });
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Seek to position (in seconds or "live")
|
|
263
|
+
*/
|
|
264
|
+
seek(time: number | 'live'): Promise<string> {
|
|
265
|
+
return new Promise((resolve, reject) => {
|
|
266
|
+
if (!this.isConnected) {
|
|
267
|
+
reject('Not connected');
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Cancel previous seek if pending
|
|
272
|
+
if (this.seekPromise) {
|
|
273
|
+
this.seekPromise.reject('New seek requested');
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Send seek command (time in ms for MistServer)
|
|
277
|
+
const seekTime = time === 'live' ? 'live' : time * 1000;
|
|
278
|
+
this.send({ type: 'seek', seek_time: seekTime });
|
|
279
|
+
|
|
280
|
+
// Store promise handlers
|
|
281
|
+
this.seekPromise = { resolve, reject };
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Pause playback (hold)
|
|
287
|
+
*/
|
|
288
|
+
pause(): boolean {
|
|
289
|
+
return this.send({ type: 'hold' });
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Stop playback
|
|
294
|
+
*/
|
|
295
|
+
stop(): boolean {
|
|
296
|
+
return this.send({ type: 'stop' });
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Set track selection
|
|
301
|
+
* @param video - Video track selection (e.g., "~1080x720", "|500000", "none")
|
|
302
|
+
* @param audio - Audio track selection (e.g., "eng", "none")
|
|
303
|
+
*/
|
|
304
|
+
setTracks(options: { video?: string; audio?: string }): boolean {
|
|
305
|
+
return this.send({ type: 'tracks', ...options });
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Set playback speed
|
|
310
|
+
* @param rate - Playback rate (1.0 normal, "auto" for live catch-up)
|
|
311
|
+
*/
|
|
312
|
+
setSpeed(rate: number | 'auto'): boolean {
|
|
313
|
+
return this.send({ type: 'set_speed', play_rate: rate });
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Close the connection
|
|
318
|
+
*/
|
|
319
|
+
close(): void {
|
|
320
|
+
if (this.timeoutId) {
|
|
321
|
+
clearTimeout(this.timeoutId);
|
|
322
|
+
this.timeoutId = null;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (this.seekPromise) {
|
|
326
|
+
this.seekPromise.reject('Connection closed');
|
|
327
|
+
this.seekPromise = null;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (this.ws) {
|
|
331
|
+
this._state = 'closed';
|
|
332
|
+
this.ws.close();
|
|
333
|
+
this.ws = null;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Destroy and cleanup
|
|
339
|
+
*/
|
|
340
|
+
destroy(): void {
|
|
341
|
+
this.close();
|
|
342
|
+
this.removeAllListeners();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export default MistSignaling;
|