@livepeer-frameworks/player-core 0.1.0 → 0.1.1

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 (59) hide show
  1. package/README.md +11 -9
  2. package/dist/player.css +182 -42
  3. package/package.json +1 -1
  4. package/src/core/ABRController.ts +38 -36
  5. package/src/core/CodecUtils.ts +49 -46
  6. package/src/core/Disposable.ts +4 -4
  7. package/src/core/EventEmitter.ts +1 -1
  8. package/src/core/GatewayClient.ts +41 -39
  9. package/src/core/InteractionController.ts +89 -82
  10. package/src/core/LiveDurationProxy.ts +14 -15
  11. package/src/core/MetaTrackManager.ts +73 -65
  12. package/src/core/MistReporter.ts +72 -45
  13. package/src/core/MistSignaling.ts +59 -56
  14. package/src/core/PlayerController.ts +527 -384
  15. package/src/core/PlayerInterface.ts +83 -59
  16. package/src/core/PlayerManager.ts +79 -133
  17. package/src/core/PlayerRegistry.ts +59 -42
  18. package/src/core/QualityMonitor.ts +38 -31
  19. package/src/core/ScreenWakeLockManager.ts +8 -9
  20. package/src/core/SeekingUtils.ts +31 -22
  21. package/src/core/StreamStateClient.ts +74 -68
  22. package/src/core/SubtitleManager.ts +24 -22
  23. package/src/core/TelemetryReporter.ts +34 -31
  24. package/src/core/TimeFormat.ts +13 -17
  25. package/src/core/TimerManager.ts +24 -8
  26. package/src/core/UrlUtils.ts +20 -17
  27. package/src/core/detector.ts +44 -44
  28. package/src/core/index.ts +57 -48
  29. package/src/core/scorer.ts +136 -141
  30. package/src/core/selector.ts +2 -6
  31. package/src/global.d.ts +1 -1
  32. package/src/index.ts +46 -35
  33. package/src/players/DashJsPlayer.ts +164 -115
  34. package/src/players/HlsJsPlayer.ts +132 -78
  35. package/src/players/MewsWsPlayer/SourceBufferManager.ts +41 -36
  36. package/src/players/MewsWsPlayer/WebSocketManager.ts +9 -9
  37. package/src/players/MewsWsPlayer/index.ts +192 -152
  38. package/src/players/MewsWsPlayer/types.ts +21 -21
  39. package/src/players/MistPlayer.ts +45 -26
  40. package/src/players/MistWebRTCPlayer/index.ts +175 -129
  41. package/src/players/NativePlayer.ts +203 -143
  42. package/src/players/VideoJsPlayer.ts +170 -118
  43. package/src/players/WebCodecsPlayer/JitterBuffer.ts +6 -7
  44. package/src/players/WebCodecsPlayer/LatencyProfiles.ts +43 -43
  45. package/src/players/WebCodecsPlayer/RawChunkParser.ts +10 -10
  46. package/src/players/WebCodecsPlayer/SyncController.ts +45 -53
  47. package/src/players/WebCodecsPlayer/WebSocketController.ts +66 -68
  48. package/src/players/WebCodecsPlayer/index.ts +263 -221
  49. package/src/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.ts +12 -17
  50. package/src/players/WebCodecsPlayer/types.ts +56 -56
  51. package/src/players/WebCodecsPlayer/worker/decoder.worker.ts +238 -182
  52. package/src/players/WebCodecsPlayer/worker/types.ts +31 -31
  53. package/src/players/index.ts +8 -8
  54. package/src/styles/animations.css +2 -1
  55. package/src/styles/player.css +182 -42
  56. package/src/styles/tailwind.css +473 -159
  57. package/src/types.ts +43 -43
  58. package/src/vanilla/FrameWorksPlayer.ts +29 -14
  59. package/src/vanilla/index.ts +4 -4
@@ -16,7 +16,7 @@
16
16
  * Check if native MediaStreamTrackGenerator is available
17
17
  */
18
18
  export function hasNativeMediaStreamTrackGenerator(): boolean {
19
- return typeof (globalThis as any).MediaStreamTrackGenerator !== 'undefined';
19
+ return typeof (globalThis as any).MediaStreamTrackGenerator !== "undefined";
20
20
  }
21
21
 
22
22
  /**
@@ -34,13 +34,13 @@ export class VideoTrackGeneratorPolyfill {
34
34
 
35
35
  constructor() {
36
36
  // Create offscreen canvas
37
- this.canvas = document.createElement('canvas');
37
+ this.canvas = document.createElement("canvas");
38
38
  this.canvas.width = 1920; // Will be resized on first frame
39
39
  this.canvas.height = 1080;
40
40
 
41
- const ctx = this.canvas.getContext('2d', { desynchronized: true });
41
+ const ctx = this.canvas.getContext("2d", { desynchronized: true });
42
42
  if (!ctx) {
43
- throw new Error('Failed to create canvas 2D context');
43
+ throw new Error("Failed to create canvas 2D context");
44
44
  }
45
45
  this.ctx = ctx;
46
46
 
@@ -48,7 +48,7 @@ export class VideoTrackGeneratorPolyfill {
48
48
  const stream = this.canvas.captureStream();
49
49
  const tracks = stream.getVideoTracks();
50
50
  if (tracks.length === 0) {
51
- throw new Error('Failed to capture stream from canvas');
51
+ throw new Error("Failed to capture stream from canvas");
52
52
  }
53
53
  this.track = tracks[0];
54
54
 
@@ -140,13 +140,13 @@ export class AudioTrackGeneratorPolyfill {
140
140
 
141
141
  constructor() {
142
142
  // Create audio context
143
- this.audioContext = new AudioContext({ latencyHint: 'interactive' });
143
+ this.audioContext = new AudioContext({ latencyHint: "interactive" });
144
144
 
145
145
  // Create destination for MediaStreamTrack
146
146
  this.destination = this.audioContext.createMediaStreamDestination();
147
147
  const tracks = this.destination.stream.getAudioTracks();
148
148
  if (tracks.length === 0) {
149
- throw new Error('Failed to create audio destination');
149
+ throw new Error("Failed to create audio destination");
150
150
  }
151
151
  this.track = tracks[0];
152
152
 
@@ -234,16 +234,13 @@ export class AudioTrackGeneratorPolyfill {
234
234
  registerProcessor('synced-audio-processor', SyncedAudioProcessor);
235
235
  `;
236
236
 
237
- const blob = new Blob([workletCode], { type: 'application/javascript' });
237
+ const blob = new Blob([workletCode], { type: "application/javascript" });
238
238
  const url = URL.createObjectURL(blob);
239
239
 
240
240
  try {
241
241
  await this.audioContext.audioWorklet.addModule(url);
242
242
 
243
- this.workletNode = new AudioWorkletNode(
244
- this.audioContext,
245
- 'synced-audio-processor'
246
- );
243
+ this.workletNode = new AudioWorkletNode(this.audioContext, "synced-audio-processor");
247
244
  this.workletNode.connect(this.destination);
248
245
 
249
246
  this.initialized = true;
@@ -293,7 +290,7 @@ export class AudioTrackGeneratorPolyfill {
293
290
  const samples = this.sampleBuffer.shift();
294
291
  if (samples) {
295
292
  this.workletNode.port.postMessage(
296
- { type: 'samples', samples },
293
+ { type: "samples", samples },
297
294
  { transfer: [samples.buffer] }
298
295
  );
299
296
  }
@@ -340,9 +337,7 @@ export class AudioTrackGeneratorPolyfill {
340
337
  * @param kind - 'video' or 'audio'
341
338
  * @returns Native generator or polyfill
342
339
  */
343
- export function createTrackGenerator(
344
- kind: 'video' | 'audio'
345
- ): {
340
+ export function createTrackGenerator(kind: "video" | "audio"): {
346
341
  writable: WritableStream<VideoFrame | AudioData>;
347
342
  getTrack: () => MediaStreamTrack;
348
343
  close: () => void;
@@ -360,7 +355,7 @@ export function createTrackGenerator(
360
355
  }
361
356
 
362
357
  // Fall back to polyfill
363
- if (kind === 'video') {
358
+ if (kind === "video") {
364
359
  const polyfill = new VideoTrackGeneratorPolyfill();
365
360
  return {
366
361
  writable: polyfill.writable as WritableStream<VideoFrame | AudioData>,
@@ -8,7 +8,7 @@
8
8
  // Latency Profile Types
9
9
  // ============================================================================
10
10
 
11
- export type LatencyProfileName = 'ultra-low' | 'low' | 'balanced' | 'quality';
11
+ export type LatencyProfileName = "ultra-low" | "low" | "balanced" | "quality";
12
12
 
13
13
  export interface LatencyProfile {
14
14
  name: string;
@@ -34,7 +34,7 @@ export interface LatencyProfile {
34
34
  // Raw Chunk Types (12-byte binary header protocol)
35
35
  // ============================================================================
36
36
 
37
- export type ChunkType = 'key' | 'delta' | 'init';
37
+ export type ChunkType = "key" | "delta" | "init";
38
38
 
39
39
  export interface RawChunk {
40
40
  /** Track index from server */
@@ -53,7 +53,7 @@ export interface RawChunk {
53
53
  // Track Types
54
54
  // ============================================================================
55
55
 
56
- export type TrackType = 'video' | 'audio' | 'meta';
56
+ export type TrackType = "video" | "audio" | "meta";
57
57
 
58
58
  export interface TrackInfo {
59
59
  idx: number;
@@ -76,17 +76,17 @@ export interface TrackInfo {
76
76
  // ============================================================================
77
77
 
78
78
  export type ControlMessageType =
79
- | 'codec_data'
80
- | 'info'
81
- | 'on_time'
82
- | 'tracks'
83
- | 'set_speed'
84
- | 'pause'
85
- | 'on_stop'
86
- | 'error';
79
+ | "codec_data"
80
+ | "info"
81
+ | "on_time"
82
+ | "tracks"
83
+ | "set_speed"
84
+ | "pause"
85
+ | "on_stop"
86
+ | "error";
87
87
 
88
88
  export interface CodecDataMessage {
89
- type: 'codec_data';
89
+ type: "codec_data";
90
90
  /** Current stream position in milliseconds */
91
91
  current?: number;
92
92
  /** List of WebCodecs-compatible codec strings (e.g., "avc1.42001f", "mp4a.40.2") */
@@ -100,7 +100,7 @@ export interface CodecDataMessage {
100
100
  * Sent by MistServer with full stream information
101
101
  */
102
102
  export interface InfoMessage {
103
- type: 'info';
103
+ type: "info";
104
104
  /** Stream metadata including tracks */
105
105
  meta?: {
106
106
  tracks?: Record<string, TrackInfo>;
@@ -110,7 +110,7 @@ export interface InfoMessage {
110
110
  }
111
111
 
112
112
  export interface OnTimeMessage {
113
- type: 'on_time';
113
+ type: "on_time";
114
114
  /** Current playback time (seconds) */
115
115
  current: number;
116
116
  /** Total duration (seconds, Infinity for live) */
@@ -122,34 +122,34 @@ export interface OnTimeMessage {
122
122
  /** Server-reported jitter (ms) */
123
123
  jitter?: number;
124
124
  /** Current play rate */
125
- play_rate?: number | 'auto';
125
+ play_rate?: number | "auto";
126
126
  /** Current play rate (alias) */
127
- play_rate_curr?: number | 'auto' | 'fast-forward';
127
+ play_rate_curr?: number | "auto" | "fast-forward";
128
128
  /** Active track indices */
129
129
  tracks?: number[];
130
130
  }
131
131
 
132
132
  export interface TracksMessage {
133
- type: 'tracks';
133
+ type: "tracks";
134
134
  tracks: TrackInfo[];
135
135
  codecs?: string[];
136
136
  }
137
137
 
138
138
  export interface SetSpeedMessage {
139
- type: 'set_speed';
140
- play_rate: number | 'auto';
139
+ type: "set_speed";
140
+ play_rate: number | "auto";
141
141
  }
142
142
 
143
143
  export interface PauseMessage {
144
- type: 'pause';
144
+ type: "pause";
145
145
  }
146
146
 
147
147
  export interface OnStopMessage {
148
- type: 'on_stop';
148
+ type: "on_stop";
149
149
  }
150
150
 
151
151
  export interface ErrorMessage {
152
- type: 'error';
152
+ type: "error";
153
153
  message: string;
154
154
  }
155
155
 
@@ -165,32 +165,32 @@ export type ControlMessage =
165
165
 
166
166
  // Outbound control commands
167
167
  export interface PlayCommand {
168
- type: 'play';
168
+ type: "play";
169
169
  }
170
170
 
171
171
  export interface HoldCommand {
172
- type: 'hold';
172
+ type: "hold";
173
173
  }
174
174
 
175
175
  export interface SeekCommand {
176
- type: 'seek';
176
+ type: "seek";
177
177
  seek_time: number; // milliseconds
178
178
  ff_add?: number; // fast-forward buffer request (ms)
179
179
  }
180
180
 
181
181
  export interface SetSpeedCommand {
182
- type: 'set_speed';
183
- play_rate: number | 'auto';
182
+ type: "set_speed";
183
+ play_rate: number | "auto";
184
184
  }
185
185
 
186
186
  export interface RequestCodecDataCommand {
187
- type: 'request_codec_data';
187
+ type: "request_codec_data";
188
188
  /** Supported codec combinations - array of [video codecs[], audio codecs[]] */
189
189
  supported_combinations?: string[][][];
190
190
  }
191
191
 
192
192
  export interface FastForwardCommand {
193
- type: 'fast_forward';
193
+ type: "fast_forward";
194
194
  ff_add: number; // milliseconds of additional data to request
195
195
  }
196
196
 
@@ -208,29 +208,29 @@ export type ControlCommand =
208
208
 
209
209
  // Main thread -> Worker messages
210
210
  export interface CreatePipelineMessage {
211
- type: 'create';
211
+ type: "create";
212
212
  idx: number;
213
213
  track: TrackInfo;
214
214
  opts: {
215
215
  optimizeForLatency: boolean;
216
216
  /** Payload format: 'avcc' (length-prefixed) or 'annexb' (start-code delimited) */
217
- payloadFormat?: 'avcc' | 'annexb';
217
+ payloadFormat?: "avcc" | "annexb";
218
218
  };
219
219
  uid?: number;
220
220
  }
221
221
 
222
222
  export interface ConfigurePipelineMessage {
223
- type: 'configure';
223
+ type: "configure";
224
224
  idx: number;
225
225
  header: Uint8Array;
226
226
  uid?: number;
227
227
  }
228
228
 
229
229
  export interface ReceiveChunkMessage {
230
- type: 'receive';
230
+ type: "receive";
231
231
  idx: number;
232
232
  chunk: {
233
- type: 'key' | 'delta';
233
+ type: "key" | "delta";
234
234
  timestamp: number; // microseconds
235
235
  data: Uint8Array;
236
236
  };
@@ -238,28 +238,28 @@ export interface ReceiveChunkMessage {
238
238
  }
239
239
 
240
240
  export interface SetWritableMessage {
241
- type: 'setwritable';
241
+ type: "setwritable";
242
242
  idx: number;
243
243
  writable: WritableStream;
244
244
  uid?: number;
245
245
  }
246
246
 
247
247
  export interface CreateGeneratorMessage {
248
- type: 'creategenerator';
248
+ type: "creategenerator";
249
249
  idx: number;
250
250
  uid?: number;
251
251
  }
252
252
 
253
253
  export interface ClosePipelineMessage {
254
- type: 'close';
254
+ type: "close";
255
255
  idx: number;
256
256
  waitEmpty?: boolean;
257
257
  uid?: number;
258
258
  }
259
259
 
260
260
  export interface FrameTimingMessage {
261
- type: 'frametiming';
262
- action: 'setSpeed' | 'reset' | 'setPaused';
261
+ type: "frametiming";
262
+ action: "setSpeed" | "reset" | "setPaused";
263
263
  speed?: number;
264
264
  tweak?: number;
265
265
  paused?: boolean;
@@ -267,28 +267,28 @@ export interface FrameTimingMessage {
267
267
  }
268
268
 
269
269
  export interface SeekWorkerMessage {
270
- type: 'seek';
270
+ type: "seek";
271
271
  seekTime: number; // milliseconds
272
272
  uid?: number;
273
273
  }
274
274
 
275
275
  export interface DebuggingMessage {
276
- type: 'debugging';
277
- value: boolean | 'verbose';
276
+ type: "debugging";
277
+ value: boolean | "verbose";
278
278
  uid?: number;
279
279
  }
280
280
 
281
281
  export interface FrameStepMessage {
282
- type: 'framestep';
282
+ type: "framestep";
283
283
  direction: -1 | 1;
284
284
  uid?: number;
285
285
  }
286
286
 
287
287
  export interface WriteFrameResponseMessage {
288
- type: 'writeframe';
288
+ type: "writeframe";
289
289
  idx: number;
290
290
  uid?: number;
291
- status: 'ok' | 'error';
291
+ status: "ok" | "error";
292
292
  error?: string;
293
293
  }
294
294
 
@@ -307,39 +307,39 @@ export type MainToWorkerMessage =
307
307
 
308
308
  // Worker -> Main thread messages
309
309
  export interface AddTrackMessage {
310
- type: 'addtrack';
310
+ type: "addtrack";
311
311
  idx: number;
312
312
  track?: MediaStreamTrack; // Safari only
313
313
  uid?: number;
314
314
  }
315
315
 
316
316
  export interface RemoveTrackMessage {
317
- type: 'removetrack';
317
+ type: "removetrack";
318
318
  idx: number;
319
319
  uid?: number;
320
320
  }
321
321
 
322
322
  export interface SetPlaybackRateMessage {
323
- type: 'setplaybackrate';
323
+ type: "setplaybackrate";
324
324
  speed: number;
325
325
  uid?: number;
326
326
  }
327
327
 
328
328
  export interface ClosedMessage {
329
- type: 'closed';
329
+ type: "closed";
330
330
  idx: number;
331
331
  uid?: number;
332
332
  }
333
333
 
334
334
  export interface LogMessage {
335
- type: 'log';
335
+ type: "log";
336
336
  msg: string;
337
- level?: 'info' | 'warn' | 'error';
337
+ level?: "info" | "warn" | "error";
338
338
  uid?: number;
339
339
  }
340
340
 
341
341
  export interface SendEventMessage {
342
- type: 'sendevent';
342
+ type: "sendevent";
343
343
  kind: string;
344
344
  message?: string;
345
345
  time?: number;
@@ -348,21 +348,21 @@ export interface SendEventMessage {
348
348
  }
349
349
 
350
350
  export interface StatsMessage {
351
- type: 'stats';
351
+ type: "stats";
352
352
  stats: WorkerStats;
353
353
  uid?: number;
354
354
  }
355
355
 
356
356
  export interface AckMessage {
357
- type: 'ack';
357
+ type: "ack";
358
358
  idx?: number;
359
359
  uid?: number;
360
- status?: 'ok' | 'error';
360
+ status?: "ok" | "error";
361
361
  error?: string;
362
362
  }
363
363
 
364
364
  export interface WriteFrameMessage {
365
- type: 'writeframe';
365
+ type: "writeframe";
366
366
  idx: number;
367
367
  frame: AudioData;
368
368
  uid?: number;