@livepeer-frameworks/player-core 0.0.4 → 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 (82) hide show
  1. package/README.md +21 -6
  2. package/dist/cjs/index.js +792 -146
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/esm/index.js +792 -146
  5. package/dist/esm/index.js.map +1 -1
  6. package/dist/player.css +185 -373
  7. package/dist/types/core/GatewayClient.d.ts +3 -4
  8. package/dist/types/core/InteractionController.d.ts +12 -0
  9. package/dist/types/core/MetaTrackManager.d.ts +1 -1
  10. package/dist/types/core/PlayerController.d.ts +18 -2
  11. package/dist/types/core/PlayerInterface.d.ts +10 -0
  12. package/dist/types/core/SeekingUtils.d.ts +3 -1
  13. package/dist/types/core/StreamStateClient.d.ts +1 -1
  14. package/dist/types/players/HlsJsPlayer.d.ts +8 -0
  15. package/dist/types/players/MewsWsPlayer/index.d.ts +1 -1
  16. package/dist/types/players/VideoJsPlayer.d.ts +12 -4
  17. package/dist/types/players/WebCodecsPlayer/SyncController.d.ts +1 -1
  18. package/dist/types/players/WebCodecsPlayer/index.d.ts +11 -0
  19. package/dist/types/players/WebCodecsPlayer/types.d.ts +25 -3
  20. package/dist/types/players/WebCodecsPlayer/worker/types.d.ts +20 -2
  21. package/dist/types/types.d.ts +32 -1
  22. package/dist/types/vanilla/FrameWorksPlayer.d.ts +5 -5
  23. package/dist/types/vanilla/index.d.ts +3 -3
  24. package/dist/workers/decoder.worker.js +183 -6
  25. package/dist/workers/decoder.worker.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/core/ABRController.ts +38 -36
  28. package/src/core/CodecUtils.ts +50 -47
  29. package/src/core/Disposable.ts +4 -4
  30. package/src/core/EventEmitter.ts +1 -1
  31. package/src/core/GatewayClient.ts +48 -48
  32. package/src/core/InteractionController.ts +89 -82
  33. package/src/core/LiveDurationProxy.ts +14 -16
  34. package/src/core/MetaTrackManager.ts +74 -66
  35. package/src/core/MistReporter.ts +72 -45
  36. package/src/core/MistSignaling.ts +59 -56
  37. package/src/core/PlayerController.ts +724 -375
  38. package/src/core/PlayerInterface.ts +89 -59
  39. package/src/core/PlayerManager.ts +118 -123
  40. package/src/core/PlayerRegistry.ts +59 -42
  41. package/src/core/QualityMonitor.ts +38 -31
  42. package/src/core/ScreenWakeLockManager.ts +8 -9
  43. package/src/core/SeekingUtils.ts +31 -22
  44. package/src/core/StreamStateClient.ts +75 -69
  45. package/src/core/SubtitleManager.ts +25 -23
  46. package/src/core/TelemetryReporter.ts +34 -31
  47. package/src/core/TimeFormat.ts +13 -17
  48. package/src/core/TimerManager.ts +25 -9
  49. package/src/core/UrlUtils.ts +20 -17
  50. package/src/core/detector.ts +44 -44
  51. package/src/core/index.ts +57 -48
  52. package/src/core/scorer.ts +137 -138
  53. package/src/core/selector.ts +2 -6
  54. package/src/global.d.ts +1 -1
  55. package/src/index.ts +46 -35
  56. package/src/players/DashJsPlayer.ts +175 -114
  57. package/src/players/HlsJsPlayer.ts +154 -76
  58. package/src/players/MewsWsPlayer/SourceBufferManager.ts +44 -39
  59. package/src/players/MewsWsPlayer/WebSocketManager.ts +9 -10
  60. package/src/players/MewsWsPlayer/index.ts +196 -154
  61. package/src/players/MewsWsPlayer/types.ts +21 -21
  62. package/src/players/MistPlayer.ts +46 -27
  63. package/src/players/MistWebRTCPlayer/index.ts +175 -129
  64. package/src/players/NativePlayer.ts +203 -143
  65. package/src/players/VideoJsPlayer.ts +200 -146
  66. package/src/players/WebCodecsPlayer/JitterBuffer.ts +6 -7
  67. package/src/players/WebCodecsPlayer/LatencyProfiles.ts +43 -43
  68. package/src/players/WebCodecsPlayer/RawChunkParser.ts +10 -10
  69. package/src/players/WebCodecsPlayer/SyncController.ts +46 -55
  70. package/src/players/WebCodecsPlayer/WebSocketController.ts +67 -69
  71. package/src/players/WebCodecsPlayer/index.ts +280 -220
  72. package/src/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.ts +12 -17
  73. package/src/players/WebCodecsPlayer/types.ts +81 -53
  74. package/src/players/WebCodecsPlayer/worker/decoder.worker.ts +255 -192
  75. package/src/players/WebCodecsPlayer/worker/types.ts +33 -29
  76. package/src/players/index.ts +8 -8
  77. package/src/styles/animations.css +2 -1
  78. package/src/styles/player.css +182 -356
  79. package/src/styles/tailwind.css +473 -159
  80. package/src/types.ts +75 -33
  81. package/src/vanilla/FrameWorksPlayer.ts +34 -19
  82. package/src/vanilla/index.ts +7 -7
@@ -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,27 +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
+ /** Payload format: 'avcc' (length-prefixed) or 'annexb' (start-code delimited) */
217
+ payloadFormat?: "avcc" | "annexb";
216
218
  };
217
219
  uid?: number;
218
220
  }
219
221
 
220
222
  export interface ConfigurePipelineMessage {
221
- type: 'configure';
223
+ type: "configure";
222
224
  idx: number;
223
225
  header: Uint8Array;
224
226
  uid?: number;
225
227
  }
226
228
 
227
229
  export interface ReceiveChunkMessage {
228
- type: 'receive';
230
+ type: "receive";
229
231
  idx: number;
230
232
  chunk: {
231
- type: 'key' | 'delta';
233
+ type: "key" | "delta";
232
234
  timestamp: number; // microseconds
233
235
  data: Uint8Array;
234
236
  };
@@ -236,45 +238,60 @@ export interface ReceiveChunkMessage {
236
238
  }
237
239
 
238
240
  export interface SetWritableMessage {
239
- type: 'setwritable';
241
+ type: "setwritable";
240
242
  idx: number;
241
243
  writable: WritableStream;
242
244
  uid?: number;
243
245
  }
244
246
 
245
247
  export interface CreateGeneratorMessage {
246
- type: 'creategenerator';
248
+ type: "creategenerator";
247
249
  idx: number;
248
250
  uid?: number;
249
251
  }
250
252
 
251
253
  export interface ClosePipelineMessage {
252
- type: 'close';
254
+ type: "close";
253
255
  idx: number;
254
256
  waitEmpty?: boolean;
255
257
  uid?: number;
256
258
  }
257
259
 
258
260
  export interface FrameTimingMessage {
259
- type: 'frametiming';
260
- action: 'setSpeed' | 'reset';
261
+ type: "frametiming";
262
+ action: "setSpeed" | "reset" | "setPaused";
261
263
  speed?: number;
262
264
  tweak?: number;
265
+ paused?: boolean;
263
266
  uid?: number;
264
267
  }
265
268
 
266
269
  export interface SeekWorkerMessage {
267
- type: 'seek';
270
+ type: "seek";
268
271
  seekTime: number; // milliseconds
269
272
  uid?: number;
270
273
  }
271
274
 
272
275
  export interface DebuggingMessage {
273
- type: 'debugging';
274
- value: boolean | 'verbose';
276
+ type: "debugging";
277
+ value: boolean | "verbose";
275
278
  uid?: number;
276
279
  }
277
280
 
281
+ export interface FrameStepMessage {
282
+ type: "framestep";
283
+ direction: -1 | 1;
284
+ uid?: number;
285
+ }
286
+
287
+ export interface WriteFrameResponseMessage {
288
+ type: "writeframe";
289
+ idx: number;
290
+ uid?: number;
291
+ status: "ok" | "error";
292
+ error?: string;
293
+ }
294
+
278
295
  export type MainToWorkerMessage =
279
296
  | CreatePipelineMessage
280
297
  | ConfigurePipelineMessage
@@ -284,63 +301,73 @@ export type MainToWorkerMessage =
284
301
  | ClosePipelineMessage
285
302
  | FrameTimingMessage
286
303
  | SeekWorkerMessage
287
- | DebuggingMessage;
304
+ | DebuggingMessage
305
+ | FrameStepMessage
306
+ | WriteFrameResponseMessage;
288
307
 
289
308
  // Worker -> Main thread messages
290
309
  export interface AddTrackMessage {
291
- type: 'addtrack';
310
+ type: "addtrack";
292
311
  idx: number;
293
312
  track?: MediaStreamTrack; // Safari only
294
313
  uid?: number;
295
314
  }
296
315
 
297
316
  export interface RemoveTrackMessage {
298
- type: 'removetrack';
317
+ type: "removetrack";
299
318
  idx: number;
300
319
  uid?: number;
301
320
  }
302
321
 
303
322
  export interface SetPlaybackRateMessage {
304
- type: 'setplaybackrate';
323
+ type: "setplaybackrate";
305
324
  speed: number;
306
325
  uid?: number;
307
326
  }
308
327
 
309
328
  export interface ClosedMessage {
310
- type: 'closed';
329
+ type: "closed";
311
330
  idx: number;
312
331
  uid?: number;
313
332
  }
314
333
 
315
334
  export interface LogMessage {
316
- type: 'log';
335
+ type: "log";
317
336
  msg: string;
318
- level?: 'info' | 'warn' | 'error';
337
+ level?: "info" | "warn" | "error";
319
338
  uid?: number;
320
339
  }
321
340
 
322
341
  export interface SendEventMessage {
323
- type: 'sendevent';
342
+ type: "sendevent";
324
343
  kind: string;
325
344
  message?: string;
345
+ time?: number;
326
346
  idx?: number;
327
347
  uid?: number;
328
348
  }
329
349
 
330
350
  export interface StatsMessage {
331
- type: 'stats';
351
+ type: "stats";
332
352
  stats: WorkerStats;
333
353
  uid?: number;
334
354
  }
335
355
 
336
356
  export interface AckMessage {
337
- type: 'ack';
357
+ type: "ack";
338
358
  idx?: number;
339
359
  uid?: number;
340
- status?: 'ok' | 'error';
360
+ status?: "ok" | "error";
341
361
  error?: string;
342
362
  }
343
363
 
364
+ export interface WriteFrameMessage {
365
+ type: "writeframe";
366
+ idx: number;
367
+ frame: AudioData;
368
+ uid?: number;
369
+ }
370
+
344
371
  export type WorkerToMainMessage =
345
372
  | AddTrackMessage
346
373
  | RemoveTrackMessage
@@ -349,7 +376,8 @@ export type WorkerToMainMessage =
349
376
  | LogMessage
350
377
  | SendEventMessage
351
378
  | StatsMessage
352
- | AckMessage;
379
+ | AckMessage
380
+ | WriteFrameMessage;
353
381
 
354
382
  // ============================================================================
355
383
  // Stats Types