@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,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
|
+
}
|