@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,367 @@
1
+ /**
2
+ * FrameWorksPlayer.ts
3
+ *
4
+ * Vanilla JavaScript wrapper for PlayerController.
5
+ * Use this class in non-React environments (Svelte, Vue, plain HTML, etc.)
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { FrameWorksPlayer } from '@livepeer-frameworks/player/vanilla';
10
+ * import '@livepeer-frameworks/player/player.css';
11
+ *
12
+ * const player = new FrameWorksPlayer('#player', {
13
+ * contentId: 'my-stream',
14
+ * contentType: 'live',
15
+ * gatewayUrl: 'https://gateway.example.com/graphql',
16
+ * onStateChange: (state) => console.log('State:', state),
17
+ * });
18
+ *
19
+ * // Control playback
20
+ * player.play();
21
+ * player.setVolume(0.5);
22
+ *
23
+ * // Clean up
24
+ * player.destroy();
25
+ * ```
26
+ */
27
+
28
+ import { PlayerController, PlayerControllerConfig, PlayerControllerEvents } from '../core/PlayerController';
29
+ import type { PlayerState, PlayerStateContext, StreamState, ContentEndpoints, ContentType } from '../types';
30
+
31
+ // ============================================================================
32
+ // Types
33
+ // ============================================================================
34
+
35
+ export interface FrameWorksPlayerOptions {
36
+ /** Content identifier (stream name) */
37
+ contentId: string;
38
+ /** Content type */
39
+ contentType: ContentType;
40
+
41
+ /** Pre-resolved endpoints (skip gateway) */
42
+ endpoints?: ContentEndpoints;
43
+
44
+ /** Gateway URL (required if endpoints not provided) */
45
+ gatewayUrl?: string;
46
+ /** Auth token for private streams */
47
+ authToken?: string;
48
+
49
+ /** Playback options */
50
+ autoplay?: boolean;
51
+ muted?: boolean;
52
+ controls?: boolean;
53
+ poster?: string;
54
+
55
+ /** Debug logging */
56
+ debug?: boolean;
57
+
58
+ // Event callbacks
59
+ /** Called when player state changes */
60
+ onStateChange?: (state: PlayerState, context?: PlayerStateContext) => void;
61
+ /** Called when stream state changes (for live streams) */
62
+ onStreamStateChange?: (state: StreamState) => void;
63
+ /** Called on time update during playback */
64
+ onTimeUpdate?: (currentTime: number, duration: number) => void;
65
+ /** Called on error */
66
+ onError?: (error: string) => void;
67
+ /** Called when player is ready */
68
+ onReady?: (videoElement: HTMLVideoElement) => void;
69
+ }
70
+
71
+ // Legacy config format for backward compatibility with Svelte wrapper
72
+ interface LegacyConfig {
73
+ contentId: string;
74
+ contentType: ContentType;
75
+ thumbnailUrl?: string | null;
76
+ options?: {
77
+ gatewayUrl?: string;
78
+ autoplay?: boolean;
79
+ muted?: boolean;
80
+ controls?: boolean;
81
+ debug?: boolean;
82
+ authToken?: string;
83
+ };
84
+ }
85
+
86
+ // ============================================================================
87
+ // FrameWorksPlayer Class
88
+ // ============================================================================
89
+
90
+ /**
91
+ * Vanilla JavaScript player class.
92
+ *
93
+ * This is a thin wrapper around PlayerController that provides a
94
+ * constructor-based API suitable for non-React frameworks.
95
+ */
96
+ export class FrameWorksPlayer {
97
+ private controller: PlayerController;
98
+ private container: HTMLElement;
99
+ private cleanupFns: Array<() => void> = [];
100
+ private isDestroyed: boolean = false;
101
+
102
+ /**
103
+ * Create a new player instance.
104
+ *
105
+ * @param container - DOM element or CSS selector to mount the player
106
+ * @param options - Player options and callbacks
107
+ */
108
+ constructor(container: HTMLElement | string | null, options: FrameWorksPlayerOptions | LegacyConfig) {
109
+ // Resolve container
110
+ if (typeof container === 'string') {
111
+ this.container = document.querySelector(container) as HTMLElement;
112
+ } else if (container instanceof HTMLElement) {
113
+ this.container = container;
114
+ } else {
115
+ throw new Error('Container element not found or invalid');
116
+ }
117
+
118
+ if (!this.container) {
119
+ throw new Error('Container element not found');
120
+ }
121
+
122
+ // Normalize options (support both new and legacy config formats)
123
+ const normalizedOptions = this.normalizeOptions(options);
124
+
125
+ // Create controller config
126
+ const config: PlayerControllerConfig = {
127
+ contentId: normalizedOptions.contentId,
128
+ contentType: normalizedOptions.contentType,
129
+ endpoints: normalizedOptions.endpoints,
130
+ gatewayUrl: normalizedOptions.gatewayUrl,
131
+ authToken: normalizedOptions.authToken,
132
+ autoplay: normalizedOptions.autoplay ?? true,
133
+ muted: normalizedOptions.muted ?? true,
134
+ controls: normalizedOptions.controls ?? true,
135
+ poster: normalizedOptions.poster,
136
+ debug: normalizedOptions.debug,
137
+ };
138
+
139
+ // Create controller
140
+ this.controller = new PlayerController(config);
141
+
142
+ // Wire up callbacks
143
+ this.setupCallbacks(normalizedOptions);
144
+
145
+ // Auto-attach to container
146
+ this.controller.attach(this.container).catch((err) => {
147
+ console.error('[FrameWorksPlayer] Failed to attach:', err);
148
+ normalizedOptions.onError?.(err instanceof Error ? err.message : String(err));
149
+ });
150
+ }
151
+
152
+ // ============================================================================
153
+ // Playback Control (delegated to controller)
154
+ // ============================================================================
155
+
156
+ /** Start playback */
157
+ play(): Promise<void> {
158
+ return this.controller.play();
159
+ }
160
+
161
+ /** Pause playback */
162
+ pause(): void {
163
+ this.controller.pause();
164
+ }
165
+
166
+ /** Seek to time in seconds */
167
+ seek(time: number): void {
168
+ this.controller.seek(time);
169
+ }
170
+
171
+ /** Set volume (0-1) */
172
+ setVolume(volume: number): void {
173
+ this.controller.setVolume(volume);
174
+ }
175
+
176
+ /** Set muted state */
177
+ setMuted(muted: boolean): void {
178
+ this.controller.setMuted(muted);
179
+ }
180
+
181
+ /** Set playback rate */
182
+ setPlaybackRate(rate: number): void {
183
+ this.controller.setPlaybackRate(rate);
184
+ }
185
+
186
+ /** Jump to live edge (for live streams) */
187
+ jumpToLive(): void {
188
+ this.controller.jumpToLive();
189
+ }
190
+
191
+ /** Request fullscreen */
192
+ requestFullscreen(): Promise<void> {
193
+ return this.controller.requestFullscreen();
194
+ }
195
+
196
+ /** Request Picture-in-Picture */
197
+ requestPiP(): Promise<void> {
198
+ return this.controller.requestPiP();
199
+ }
200
+
201
+ // ============================================================================
202
+ // State Getters (delegated to controller)
203
+ // ============================================================================
204
+
205
+ /** Get current player state */
206
+ getState(): PlayerState {
207
+ return this.controller.getState();
208
+ }
209
+
210
+ /** Get current stream state (for live streams) */
211
+ getStreamState(): StreamState | null {
212
+ return this.controller.getStreamState();
213
+ }
214
+
215
+ /** Get video element (null if not ready) */
216
+ getVideoElement(): HTMLVideoElement | null {
217
+ return this.controller.getVideoElement();
218
+ }
219
+
220
+ /** Check if player is ready */
221
+ isReady(): boolean {
222
+ return this.controller.isReady();
223
+ }
224
+
225
+ /** Get current time in seconds */
226
+ getCurrentTime(): number {
227
+ return this.controller.getCurrentTime();
228
+ }
229
+
230
+ /** Get duration in seconds */
231
+ getDuration(): number {
232
+ return this.controller.getDuration();
233
+ }
234
+
235
+ /** Check if paused */
236
+ isPaused(): boolean {
237
+ return this.controller.isPaused();
238
+ }
239
+
240
+ /** Check if muted */
241
+ isMuted(): boolean {
242
+ return this.controller.isMuted();
243
+ }
244
+
245
+ // ============================================================================
246
+ // Advanced Control
247
+ // ============================================================================
248
+
249
+ /** Retry playback after error */
250
+ retry(): Promise<void> {
251
+ return this.controller.retry();
252
+ }
253
+
254
+ /** Get content metadata (title, description, duration, viewers, etc.) */
255
+ getMetadata() {
256
+ return this.controller.getMetadata();
257
+ }
258
+
259
+ /** Get playback statistics */
260
+ getStats(): Promise<unknown> {
261
+ return this.controller.getStats();
262
+ }
263
+
264
+ /** Get current latency (for live streams) */
265
+ getLatency(): Promise<unknown> {
266
+ return this.controller.getLatency();
267
+ }
268
+
269
+ // ============================================================================
270
+ // Event Subscription
271
+ // ============================================================================
272
+
273
+ /**
274
+ * Subscribe to a player event.
275
+ * @param event - Event name
276
+ * @param listener - Callback function
277
+ * @returns Unsubscribe function
278
+ */
279
+ on<K extends keyof PlayerControllerEvents>(
280
+ event: K,
281
+ listener: (data: PlayerControllerEvents[K]) => void
282
+ ): () => void {
283
+ return this.controller.on(event, listener);
284
+ }
285
+
286
+ // ============================================================================
287
+ // Cleanup
288
+ // ============================================================================
289
+
290
+ /** Destroy the player and clean up resources */
291
+ destroy(): void {
292
+ if (this.isDestroyed) return;
293
+
294
+ this.cleanupFns.forEach((fn) => {
295
+ try {
296
+ fn();
297
+ } catch {}
298
+ });
299
+ this.cleanupFns = [];
300
+
301
+ this.controller.destroy();
302
+ this.isDestroyed = true;
303
+ }
304
+
305
+ // ============================================================================
306
+ // Private Methods
307
+ // ============================================================================
308
+
309
+ private normalizeOptions(options: FrameWorksPlayerOptions | LegacyConfig): FrameWorksPlayerOptions {
310
+ // Check if it's legacy format (has nested `options` property)
311
+ if ('options' in options && typeof options.options === 'object') {
312
+ const legacy = options as LegacyConfig;
313
+ return {
314
+ contentId: legacy.contentId,
315
+ contentType: legacy.contentType,
316
+ poster: legacy.thumbnailUrl || undefined,
317
+ gatewayUrl: legacy.options?.gatewayUrl,
318
+ authToken: legacy.options?.authToken,
319
+ autoplay: legacy.options?.autoplay,
320
+ muted: legacy.options?.muted,
321
+ controls: legacy.options?.controls,
322
+ debug: legacy.options?.debug,
323
+ };
324
+ }
325
+
326
+ return options as FrameWorksPlayerOptions;
327
+ }
328
+
329
+ private setupCallbacks(options: FrameWorksPlayerOptions): void {
330
+ if (options.onStateChange) {
331
+ const unsub = this.controller.on('stateChange', ({ state, context }) => {
332
+ options.onStateChange!(state, context);
333
+ });
334
+ this.cleanupFns.push(unsub);
335
+ }
336
+
337
+ if (options.onStreamStateChange) {
338
+ const unsub = this.controller.on('streamStateChange', ({ state }) => {
339
+ options.onStreamStateChange!(state);
340
+ });
341
+ this.cleanupFns.push(unsub);
342
+ }
343
+
344
+ if (options.onTimeUpdate) {
345
+ const unsub = this.controller.on('timeUpdate', ({ currentTime, duration }) => {
346
+ options.onTimeUpdate!(currentTime, duration);
347
+ });
348
+ this.cleanupFns.push(unsub);
349
+ }
350
+
351
+ if (options.onError) {
352
+ const unsub = this.controller.on('error', ({ error }) => {
353
+ options.onError!(error);
354
+ });
355
+ this.cleanupFns.push(unsub);
356
+ }
357
+
358
+ if (options.onReady) {
359
+ const unsub = this.controller.on('ready', ({ videoElement }) => {
360
+ options.onReady!(videoElement);
361
+ });
362
+ this.cleanupFns.push(unsub);
363
+ }
364
+ }
365
+ }
366
+
367
+ export default FrameWorksPlayer;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Vanilla JS exports for non-React environments.
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * import { FrameWorksPlayer } from '@livepeer-frameworks/player/vanilla';
7
+ * import '@livepeer-frameworks/player/player.css';
8
+ *
9
+ * const player = new FrameWorksPlayer('#player', {
10
+ * contentId: 'my-stream',
11
+ * contentType: 'live',
12
+ * gatewayUrl: 'https://gateway.example.com/graphql',
13
+ * });
14
+ * ```
15
+ */
16
+
17
+ export { FrameWorksPlayer, default } from './FrameWorksPlayer';
18
+ export type { FrameWorksPlayerOptions } from './FrameWorksPlayer';
19
+
20
+ // Re-export useful types from core
21
+ export type { PlayerControllerEvents } from '../core/PlayerController';
22
+ export type { PlayerState, PlayerStateContext, StreamState, ContentEndpoints } from '../types';