@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,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker-specific Types for WebCodecs Player
|
|
3
|
+
*
|
|
4
|
+
* These types define the message protocol between main thread and worker.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { TrackInfo, FrameTimingStats, PipelineStats } from '../types';
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Main Thread -> Worker Messages
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
export interface CreateMessage {
|
|
14
|
+
type: 'create';
|
|
15
|
+
idx: number;
|
|
16
|
+
track: TrackInfo;
|
|
17
|
+
opts: {
|
|
18
|
+
optimizeForLatency: boolean;
|
|
19
|
+
};
|
|
20
|
+
uid: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ConfigureMessage {
|
|
24
|
+
type: 'configure';
|
|
25
|
+
idx: number;
|
|
26
|
+
header: Uint8Array;
|
|
27
|
+
uid: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ReceiveMessage {
|
|
31
|
+
type: 'receive';
|
|
32
|
+
idx: number;
|
|
33
|
+
chunk: {
|
|
34
|
+
type: 'key' | 'delta';
|
|
35
|
+
timestamp: number; // microseconds
|
|
36
|
+
data: Uint8Array;
|
|
37
|
+
};
|
|
38
|
+
uid: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface SetWritableMessage {
|
|
42
|
+
type: 'setwritable';
|
|
43
|
+
idx: number;
|
|
44
|
+
writable: WritableStream<VideoFrame | AudioData>;
|
|
45
|
+
uid: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface CreateGeneratorMessage {
|
|
49
|
+
type: 'creategenerator';
|
|
50
|
+
idx: number;
|
|
51
|
+
uid: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface CloseMessage {
|
|
55
|
+
type: 'close';
|
|
56
|
+
idx: number;
|
|
57
|
+
waitEmpty?: boolean;
|
|
58
|
+
uid: number;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface FrameTimingMessage {
|
|
62
|
+
type: 'frametiming';
|
|
63
|
+
action: 'setSpeed' | 'reset' | 'setPaused';
|
|
64
|
+
speed?: number;
|
|
65
|
+
tweak?: number;
|
|
66
|
+
paused?: boolean;
|
|
67
|
+
uid: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface SeekMessage {
|
|
71
|
+
type: 'seek';
|
|
72
|
+
seekTime: number; // milliseconds
|
|
73
|
+
uid: number;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface FrameStepMessage {
|
|
77
|
+
type: 'framestep';
|
|
78
|
+
direction: -1 | 1;
|
|
79
|
+
uid: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface DebuggingMessage {
|
|
83
|
+
type: 'debugging';
|
|
84
|
+
value: boolean | 'verbose';
|
|
85
|
+
uid: number;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type MainToWorkerMessage =
|
|
89
|
+
| CreateMessage
|
|
90
|
+
| ConfigureMessage
|
|
91
|
+
| ReceiveMessage
|
|
92
|
+
| SetWritableMessage
|
|
93
|
+
| CreateGeneratorMessage
|
|
94
|
+
| CloseMessage
|
|
95
|
+
| FrameTimingMessage
|
|
96
|
+
| SeekMessage
|
|
97
|
+
| FrameStepMessage
|
|
98
|
+
| DebuggingMessage;
|
|
99
|
+
|
|
100
|
+
// ============================================================================
|
|
101
|
+
// Worker -> Main Thread Messages
|
|
102
|
+
// ============================================================================
|
|
103
|
+
|
|
104
|
+
export interface AddTrackMessage {
|
|
105
|
+
type: 'addtrack';
|
|
106
|
+
idx: number;
|
|
107
|
+
track?: MediaStreamTrack; // Only for Safari's MediaStreamTrackGenerator in Worker
|
|
108
|
+
uid: number;
|
|
109
|
+
status: 'ok';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface RemoveTrackMessage {
|
|
113
|
+
type: 'removetrack';
|
|
114
|
+
idx: number;
|
|
115
|
+
uid: number;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface SetPlaybackRateMessage {
|
|
119
|
+
type: 'setplaybackrate';
|
|
120
|
+
speed: number;
|
|
121
|
+
uid: number;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface ClosedMessage {
|
|
125
|
+
type: 'closed';
|
|
126
|
+
idx: number;
|
|
127
|
+
uid: number;
|
|
128
|
+
status: 'ok';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface LogMessage {
|
|
132
|
+
type: 'log';
|
|
133
|
+
msg: string;
|
|
134
|
+
level?: 'info' | 'warn' | 'error';
|
|
135
|
+
uid: number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface SendEventMessage {
|
|
139
|
+
type: 'sendevent';
|
|
140
|
+
kind: string;
|
|
141
|
+
message?: string;
|
|
142
|
+
time?: number;
|
|
143
|
+
idx?: number;
|
|
144
|
+
uid: number;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface StatsUpdateMessage {
|
|
148
|
+
type: 'stats';
|
|
149
|
+
stats: {
|
|
150
|
+
frameTiming: FrameTimingStats;
|
|
151
|
+
pipelines: Record<number, PipelineStats>;
|
|
152
|
+
};
|
|
153
|
+
uid: number;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface AckMessage {
|
|
157
|
+
type: 'ack';
|
|
158
|
+
idx?: number;
|
|
159
|
+
uid: number;
|
|
160
|
+
status: 'ok' | 'error';
|
|
161
|
+
error?: string;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Safari audio: worker sends frames to main thread for writing */
|
|
165
|
+
export interface WriteFrameMessage {
|
|
166
|
+
type: 'writeframe';
|
|
167
|
+
idx: number;
|
|
168
|
+
frame: AudioData;
|
|
169
|
+
uid: number;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export type WorkerToMainMessage =
|
|
173
|
+
| AddTrackMessage
|
|
174
|
+
| RemoveTrackMessage
|
|
175
|
+
| SetPlaybackRateMessage
|
|
176
|
+
| ClosedMessage
|
|
177
|
+
| LogMessage
|
|
178
|
+
| SendEventMessage
|
|
179
|
+
| StatsUpdateMessage
|
|
180
|
+
| AckMessage
|
|
181
|
+
| WriteFrameMessage;
|
|
182
|
+
|
|
183
|
+
// ============================================================================
|
|
184
|
+
// Internal Worker Types
|
|
185
|
+
// ============================================================================
|
|
186
|
+
|
|
187
|
+
export interface FrameTiming {
|
|
188
|
+
/** When frame entered decoder (microseconds, performance.now() * 1000) */
|
|
189
|
+
in: number;
|
|
190
|
+
/** When frame exited decoder (microseconds) */
|
|
191
|
+
decoded: number;
|
|
192
|
+
/** When frame was written to output (microseconds) */
|
|
193
|
+
out: number;
|
|
194
|
+
speed: {
|
|
195
|
+
main: number;
|
|
196
|
+
tweak: number;
|
|
197
|
+
combined: number;
|
|
198
|
+
};
|
|
199
|
+
seeking: boolean;
|
|
200
|
+
paused: boolean;
|
|
201
|
+
/** Server-sent current time */
|
|
202
|
+
serverTime: number;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface DecodedFrame {
|
|
206
|
+
frame: VideoFrame | AudioData;
|
|
207
|
+
timestamp: number; // microseconds
|
|
208
|
+
decodedAt: number; // performance.now() when decoded
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface PipelineState {
|
|
212
|
+
idx: number;
|
|
213
|
+
track: TrackInfo;
|
|
214
|
+
configured: boolean;
|
|
215
|
+
closed: boolean;
|
|
216
|
+
decoder: VideoDecoder | AudioDecoder | null;
|
|
217
|
+
writable: WritableStream<VideoFrame | AudioData> | null;
|
|
218
|
+
writer: WritableStreamDefaultWriter<VideoFrame | AudioData> | null;
|
|
219
|
+
inputQueue: Array<{
|
|
220
|
+
type: 'key' | 'delta';
|
|
221
|
+
timestamp: number;
|
|
222
|
+
data: Uint8Array;
|
|
223
|
+
}>;
|
|
224
|
+
outputQueue: DecodedFrame[];
|
|
225
|
+
/** Recent video frames for backward/forward stepping (video only) */
|
|
226
|
+
frameHistory?: Array<{ frame: VideoFrame; timestamp: number }>;
|
|
227
|
+
/** Cursor into frameHistory for step navigation */
|
|
228
|
+
historyCursor?: number | null;
|
|
229
|
+
stats: {
|
|
230
|
+
framesIn: number;
|
|
231
|
+
framesDecoded: number;
|
|
232
|
+
framesOut: number;
|
|
233
|
+
framesDropped: number; // Phase 2B: Track dropped frames
|
|
234
|
+
lastInputTimestamp: number;
|
|
235
|
+
lastOutputTimestamp: number;
|
|
236
|
+
decoderQueueSize: number;
|
|
237
|
+
// Debug info for error diagnosis
|
|
238
|
+
lastChunkType: string;
|
|
239
|
+
lastChunkSize: number;
|
|
240
|
+
lastChunkBytes: string;
|
|
241
|
+
};
|
|
242
|
+
optimizeForLatency: boolean;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// ============================================================================
|
|
246
|
+
// Frame Scheduling Types
|
|
247
|
+
// ============================================================================
|
|
248
|
+
|
|
249
|
+
export interface ScheduleResult {
|
|
250
|
+
/** Whether frame should be output now */
|
|
251
|
+
shouldOutput: boolean;
|
|
252
|
+
/** How early/late frame is (negative = late) in ms */
|
|
253
|
+
earliness: number;
|
|
254
|
+
/** Suggested delay before next check (ms) */
|
|
255
|
+
checkDelayMs: number;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// ============================================================================
|
|
259
|
+
// Codec Configuration Types
|
|
260
|
+
// ============================================================================
|
|
261
|
+
|
|
262
|
+
export interface VideoDecoderInit {
|
|
263
|
+
codec: string;
|
|
264
|
+
codedWidth?: number;
|
|
265
|
+
codedHeight?: number;
|
|
266
|
+
description?: Uint8Array;
|
|
267
|
+
hardwareAcceleration?: 'no-preference' | 'prefer-hardware' | 'prefer-software';
|
|
268
|
+
optimizeForLatency?: boolean;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface AudioDecoderInit {
|
|
272
|
+
codec: string;
|
|
273
|
+
sampleRate: number;
|
|
274
|
+
numberOfChannels: number;
|
|
275
|
+
description?: Uint8Array;
|
|
276
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Player Implementations
|
|
3
|
+
*
|
|
4
|
+
* Framework-agnostic player implementations that extend BasePlayer.
|
|
5
|
+
* These are used by PlayerRegistry for dynamic player selection.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Direct playback players
|
|
9
|
+
export { NativePlayerImpl, DirectPlaybackPlayerImpl } from './NativePlayer';
|
|
10
|
+
|
|
11
|
+
// Adaptive streaming players
|
|
12
|
+
export { HlsJsPlayerImpl } from './HlsJsPlayer';
|
|
13
|
+
export { DashJsPlayerImpl } from './DashJsPlayer';
|
|
14
|
+
export { VideoJsPlayerImpl } from './VideoJsPlayer';
|
|
15
|
+
|
|
16
|
+
// MistServer-specific players
|
|
17
|
+
export { MistPlayerImpl } from './MistPlayer';
|
|
18
|
+
export { MewsWsPlayerImpl } from './MewsWsPlayer';
|
|
19
|
+
export { MistWebRTCPlayerImpl } from './MistWebRTCPlayer';
|
|
20
|
+
|
|
21
|
+
// Low-latency WebCodecs player (WebSocket + WebCodecs API)
|
|
22
|
+
export { WebCodecsPlayerImpl } from './WebCodecsPlayer';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
@keyframes float {
|
|
2
|
+
0%, 100% {
|
|
3
|
+
transform: translateY(0px) scale(1);
|
|
4
|
+
}
|
|
5
|
+
50% {
|
|
6
|
+
transform: translateY(-12px) scale(0.95);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@keyframes spin-slow {
|
|
11
|
+
from {
|
|
12
|
+
transform: rotate(0deg);
|
|
13
|
+
}
|
|
14
|
+
to {
|
|
15
|
+
transform: rotate(360deg);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.animate-spin-slow {
|
|
20
|
+
animation: spin-slow 18s linear infinite;
|
|
21
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
let stylesInjected = false;
|
|
2
|
+
const STYLE_URL = "player.css";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Ensures the compiled player stylesheet is imported once. When bundling with
|
|
6
|
+
* tools that respect package `style` fields, simply importing the module is enough.
|
|
7
|
+
* For host environments that do not, calling this helper will inject a link tag.
|
|
8
|
+
*/
|
|
9
|
+
export function ensurePlayerStyles(): void {
|
|
10
|
+
if (typeof document === "undefined") return;
|
|
11
|
+
if (stylesInjected) return;
|
|
12
|
+
const existing = document.querySelector<HTMLLinkElement>('link[data-fw-player-style="true"]');
|
|
13
|
+
if (existing) {
|
|
14
|
+
stylesInjected = true;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const link = document.createElement("link");
|
|
19
|
+
link.rel = "stylesheet";
|
|
20
|
+
link.href = getStylesheetUrl();
|
|
21
|
+
link.setAttribute("data-fw-player-style", "true");
|
|
22
|
+
document.head.appendChild(link);
|
|
23
|
+
stylesInjected = true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* For SSR-first apps, inject the CSS manually and mark it as applied.
|
|
28
|
+
*/
|
|
29
|
+
export function injectPlayerStyles(href?: string): void {
|
|
30
|
+
if (typeof document === "undefined") return;
|
|
31
|
+
stylesInjected = true;
|
|
32
|
+
const link = document.createElement("link");
|
|
33
|
+
link.rel = "stylesheet";
|
|
34
|
+
link.href = href ?? getStylesheetUrl();
|
|
35
|
+
link.setAttribute("data-fw-player-style", "true");
|
|
36
|
+
document.head.appendChild(link);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getStylesheetUrl(): string {
|
|
40
|
+
const current = typeof document !== "undefined" ? document.currentScript : null;
|
|
41
|
+
const src = current && "src" in current ? (current as HTMLScriptElement).src : undefined;
|
|
42
|
+
if (!src) return STYLE_URL;
|
|
43
|
+
try {
|
|
44
|
+
const url = new URL(src);
|
|
45
|
+
url.pathname = url.pathname.replace(/\/[^/]*$/, `/${STYLE_URL}`);
|
|
46
|
+
return url.toString();
|
|
47
|
+
} catch {
|
|
48
|
+
return STYLE_URL;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default ensurePlayerStyles;
|