@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,106 @@
1
+ /**
2
+ * MEWS WebSocket Player Types
3
+ */
4
+
5
+ export interface MewsMessage {
6
+ type: string;
7
+ data?: any;
8
+ }
9
+
10
+ export interface CodecDataMessage extends MewsMessage {
11
+ type: 'codec_data';
12
+ data: {
13
+ codecs: string[];
14
+ };
15
+ }
16
+
17
+ export interface OnTimeMessage extends MewsMessage {
18
+ type: 'on_time';
19
+ data: {
20
+ current: number; // Current playback position (ms)
21
+ end?: number; // End of buffered range (ms)
22
+ begin?: number; // Beginning of buffered range (ms)
23
+ play_rate_curr?: 'auto' | number; // Current server playback rate
24
+ jitter?: number; // Server-estimated jitter (ms)
25
+ tracks?: string[]; // Currently active track IDs
26
+ };
27
+ }
28
+
29
+ export interface TracksMessage extends MewsMessage {
30
+ type: 'tracks';
31
+ data: {
32
+ codecs: string[];
33
+ current?: number; // Switch point timestamp (ms)
34
+ };
35
+ }
36
+
37
+ export interface OnStopMessage extends MewsMessage {
38
+ type: 'on_stop';
39
+ }
40
+
41
+ export interface SeekAckMessage extends MewsMessage {
42
+ type: 'seek';
43
+ }
44
+
45
+ export interface SetSpeedAckMessage extends MewsMessage {
46
+ type: 'set_speed';
47
+ data?: {
48
+ play_rate_curr?: 'auto' | number;
49
+ };
50
+ }
51
+
52
+ export interface PauseMessage extends MewsMessage {
53
+ type: 'pause';
54
+ }
55
+
56
+ export interface MewsCommand {
57
+ type: 'request_codec_data' | 'play' | 'hold' | 'seek' | 'set_speed' | 'tracks';
58
+ [key: string]: any;
59
+ }
60
+
61
+ export interface RequestCodecDataCommand extends MewsCommand {
62
+ type: 'request_codec_data';
63
+ supported_codecs: string[];
64
+ }
65
+
66
+ export interface SeekCommand extends MewsCommand {
67
+ type: 'seek';
68
+ seek_time: number;
69
+ }
70
+
71
+ export interface SetSpeedCommand extends MewsCommand {
72
+ type: 'set_speed';
73
+ play_rate: number | 'auto';
74
+ }
75
+
76
+ export interface TracksCommand extends MewsCommand {
77
+ type: 'tracks';
78
+ video?: string;
79
+ subtitle?: string; // Track index or 'none'
80
+ }
81
+
82
+ /**
83
+ * Callback for WebSocket message listeners.
84
+ * Listeners are registered per message type and receive parsed MewsMessage objects.
85
+ */
86
+ export type MewsMessageListener = (msg: MewsMessage) => void;
87
+
88
+ export interface WebSocketManagerOptions {
89
+ url: string;
90
+ maxReconnectAttempts?: number;
91
+ onMessage: (data: ArrayBuffer | string) => void;
92
+ onOpen: () => void;
93
+ onClose: () => void;
94
+ onError: (message: string) => void;
95
+ }
96
+
97
+ export interface SourceBufferManagerOptions {
98
+ mediaSource: MediaSource;
99
+ videoElement: HTMLVideoElement;
100
+ onError: (message: string) => void;
101
+ }
102
+
103
+ export interface AnalyticsConfig {
104
+ enabled: boolean;
105
+ endpoint: string | null;
106
+ }
@@ -0,0 +1,188 @@
1
+ import { BasePlayer } from '../core/PlayerInterface';
2
+ import type { StreamSource, StreamInfo, PlayerOptions, PlayerCapability } from '../core/PlayerInterface';
3
+
4
+ /**
5
+ * MistPlayerImpl - Legacy fallback player
6
+ *
7
+ * Simple passthrough to MistServer's native player.js embed.
8
+ * No codec preferences or fancy params - just let MistServer handle everything.
9
+ * This is the final fallback when other players fail.
10
+ */
11
+ export class MistPlayerImpl extends BasePlayer {
12
+ readonly capability: PlayerCapability = {
13
+ name: "Legacy",
14
+ shortname: "mist-legacy",
15
+ priority: 99, // Final fallback - lowest priority
16
+ // Single special type - PlayerManager adds this as ONE option
17
+ mimes: ["mist/legacy"]
18
+ };
19
+
20
+ private container: HTMLElement | null = null;
21
+ private mistDiv: HTMLDivElement | null = null;
22
+ private proxyVideo: HTMLVideoElement | null = null;
23
+ private previousContainerOverflow: string | null = null;
24
+ private destroyed = false;
25
+
26
+ isMimeSupported(mimetype: string): boolean {
27
+ // Only match our special type - PlayerManager handles adding us once
28
+ return mimetype === "mist/legacy";
29
+ }
30
+
31
+ isBrowserSupported(mimetype: string, _source: StreamSource, _streamInfo: StreamInfo): boolean | string[] {
32
+ // Only compatible with our special type
33
+ if (mimetype !== "mist/legacy") return false;
34
+ return ['video', 'audio'];
35
+ }
36
+
37
+ async initialize(container: HTMLElement, source: StreamSource, options: PlayerOptions): Promise<HTMLVideoElement> {
38
+ this.destroyed = false;
39
+ this.container = container;
40
+ container.classList.add('fw-player-container');
41
+
42
+ // Generate unique ID for this embed
43
+ const streamName = source.streamName || 'stream';
44
+ const uniqueId = `${streamName.replace(/[^a-zA-Z0-9]/g, '_')}_${Math.random().toString(36).slice(2, 10)}`;
45
+
46
+ // Create the mistvideo div
47
+ this.mistDiv = document.createElement('div');
48
+ this.mistDiv.className = 'mistvideo fw-player-container';
49
+ this.mistDiv.id = uniqueId;
50
+ this.mistDiv.style.width = '100%';
51
+ this.mistDiv.style.height = '100%';
52
+ this.mistDiv.style.overflow = 'hidden'; // Prevent legacy player overflow
53
+ // Also on container, but restore on destroy (don't clobber consumer styles permanently)
54
+ this.previousContainerOverflow = container.style.overflow ?? '';
55
+ container.style.overflow = 'hidden';
56
+ container.appendChild(this.mistDiv);
57
+
58
+ // Derive player.js URL from source URL
59
+ const playerJsUrl = this.getPlayerJsUrl(source);
60
+
61
+ // Load and call mistPlay - simple passthrough, no extra params
62
+ await this.loadAndPlay(streamName, uniqueId, playerJsUrl, options);
63
+
64
+ // Find the video element MistServer created (for compatibility)
65
+ const video = this.findVideoElement() || this.createProxyVideo(container);
66
+ this.videoElement = video;
67
+ this.setupVideoEventListeners(video, options);
68
+
69
+ return video;
70
+ }
71
+
72
+ private getPlayerJsUrl(source: StreamSource): string {
73
+ // Try to derive player.js URL from source
74
+ if (source.mistPlayerUrl) return source.mistPlayerUrl;
75
+
76
+ try {
77
+ const url = new URL(source.url);
78
+ // Use same protocol, different path
79
+ return `${url.protocol}//${url.host}/player.js`;
80
+ } catch {
81
+ // Fallback: relative path
82
+ return '/player.js';
83
+ }
84
+ }
85
+
86
+ private async loadAndPlay(streamName: string, targetId: string, playerJsUrl: string, options: PlayerOptions): Promise<void> {
87
+ const play = () => {
88
+ if (this.destroyed) return;
89
+ if ((window as any).mistPlay) {
90
+ // Let MistServer handle source selection - no forcePriority
91
+ const mistOptions: any = {
92
+ target: document.getElementById(targetId),
93
+ fillSpace: true,
94
+ // MistServer's player.js has its own UI - always enable controls
95
+ controls: true,
96
+ // Use dev skin when devMode is enabled - shows MistServer's source selection UI
97
+ skin: options.devMode ? 'dev' : 'default',
98
+ // Only pass basic playback options
99
+ ...(options.autoplay !== undefined && { autoplay: options.autoplay }),
100
+ ...(options.muted !== undefined && { muted: options.muted }),
101
+ ...(options.poster && { poster: options.poster }),
102
+ };
103
+
104
+ console.debug('[Legacy] mistPlay options:', mistOptions);
105
+ (window as any).mistPlay(streamName, mistOptions);
106
+ }
107
+ };
108
+
109
+ if (!(window as any).mistplayers) {
110
+ // Load player.js
111
+ await new Promise<void>((resolve, reject) => {
112
+ const script = document.createElement('script');
113
+ script.src = playerJsUrl;
114
+ script.onload = () => {
115
+ play();
116
+ resolve();
117
+ };
118
+ script.onerror = () => reject(new Error(`Failed to load MistServer player from ${playerJsUrl}`));
119
+ document.head.appendChild(script);
120
+ });
121
+ } else {
122
+ play();
123
+ }
124
+ }
125
+
126
+ private findVideoElement(): HTMLVideoElement | null {
127
+ if (!this.mistDiv) return null;
128
+ return this.mistDiv.querySelector('video');
129
+ }
130
+
131
+ private createProxyVideo(container: HTMLElement): HTMLVideoElement {
132
+ const video = document.createElement('video');
133
+ video.style.display = 'none';
134
+ container.appendChild(video);
135
+ this.proxyVideo = video;
136
+ return video;
137
+ }
138
+
139
+ async destroy(): Promise<void> {
140
+ this.destroyed = true;
141
+
142
+ // Try to unload via MistServer API
143
+ if (this.mistDiv) {
144
+ try {
145
+ const ref = (this.mistDiv as any).MistVideoObject?.reference;
146
+ if (ref && typeof ref.unload === 'function') {
147
+ ref.unload();
148
+ }
149
+ } catch (e) {
150
+ // Ignore cleanup errors
151
+ }
152
+ try {
153
+ this.mistDiv.remove();
154
+ } catch {
155
+ // Fallback for older DOM implementations
156
+ try {
157
+ this.mistDiv.parentNode?.removeChild(this.mistDiv);
158
+ } catch {}
159
+ }
160
+ this.mistDiv = null;
161
+ }
162
+
163
+ if (this.proxyVideo) {
164
+ try {
165
+ this.proxyVideo.remove();
166
+ } catch {
167
+ try {
168
+ this.proxyVideo.parentNode?.removeChild(this.proxyVideo);
169
+ } catch {}
170
+ }
171
+ this.proxyVideo = null;
172
+ }
173
+
174
+ if (this.container) {
175
+ // Restore container overflow if we changed it.
176
+ try {
177
+ if (this.previousContainerOverflow !== null) {
178
+ this.container.style.overflow = this.previousContainerOverflow;
179
+ }
180
+ } catch {}
181
+ }
182
+
183
+ this.videoElement = null;
184
+ this.container = null;
185
+ this.previousContainerOverflow = null;
186
+ this.listeners.clear();
187
+ }
188
+ }