boss-web-player-sdk 1.0.2
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/LICENSE +21 -0
- package/README.md +339 -0
- package/dist/boss-web-player-sdk.css +2 -0
- package/dist/core.cjs +2 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.d.ts +569 -0
- package/dist/core.js +16 -0
- package/dist/core.js.map +1 -0
- package/dist/dash.all.min-CkVT4O2X.cjs +19 -0
- package/dist/dash.all.min-CkVT4O2X.cjs.map +1 -0
- package/dist/dash.all.min-srqAFNy2.js +38600 -0
- package/dist/dash.all.min-srqAFNy2.js.map +1 -0
- package/dist/index.cjs +33 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +897 -0
- package/dist/index.js +3638 -0
- package/dist/index.js.map +1 -0
- package/dist/src-B8eoxemB.js +19809 -0
- package/dist/src-B8eoxemB.js.map +1 -0
- package/dist/src-BXp0h90r.cjs +49 -0
- package/dist/src-BXp0h90r.cjs.map +1 -0
- package/package.json +68 -0
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
export declare type AnalyticsCallback = (event: AnalyticsEvent) => void;
|
|
2
|
+
|
|
3
|
+
export declare interface AnalyticsEvent {
|
|
4
|
+
eventType: 'play' | 'pause' | 'seek' | 'ended' | 'complete' | 'buffering_start' | 'buffering_end' | 'stall' | 'quality_change' | 'audio_track_change' | 'volume_change' | 'speed_change' | 'subtitle_change' | 'mute' | 'fast_forward' | 'fast_backward' | 'key_moments' | 'pip_toggle' | 'fullscreen_enter' | 'fullscreen_exit' | 'cast_start' | 'cast_stop' | 'error' | 'network_error' | 'session_start' | 'video_loaded' | 'first_quartile' | 'midpoint' | 'third_quartile' | 'heartbeat' | 'watch_progress' | 'streaming_time';
|
|
5
|
+
timestamp: number;
|
|
6
|
+
currentTime: number;
|
|
7
|
+
duration: number;
|
|
8
|
+
bitrate?: number;
|
|
9
|
+
rendition?: string;
|
|
10
|
+
fromRendition?: string;
|
|
11
|
+
volume?: number;
|
|
12
|
+
speed?: number;
|
|
13
|
+
errorMessage?: string;
|
|
14
|
+
errorCode?: number;
|
|
15
|
+
isRecoverable?: boolean;
|
|
16
|
+
sessionId?: string;
|
|
17
|
+
videoId?: string;
|
|
18
|
+
deviceType?: string;
|
|
19
|
+
networkType?: string;
|
|
20
|
+
watchPercentage?: number;
|
|
21
|
+
totalWatchTime?: number;
|
|
22
|
+
streamingTime?: number;
|
|
23
|
+
adWatchTime?: number;
|
|
24
|
+
bufferingCount?: number;
|
|
25
|
+
totalBufferingTime?: number;
|
|
26
|
+
seekFrom?: number;
|
|
27
|
+
seekTo?: number;
|
|
28
|
+
isMuted?: boolean;
|
|
29
|
+
skipSeconds?: number;
|
|
30
|
+
momentTitle?: string;
|
|
31
|
+
momentTime?: number;
|
|
32
|
+
pipState?: 'entered' | 'exited';
|
|
33
|
+
audioTrack?: string;
|
|
34
|
+
subtitleLanguage?: string;
|
|
35
|
+
subtitleEnabled?: boolean;
|
|
36
|
+
isAutoSwitch?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export declare class AnalyticsModule {
|
|
40
|
+
private callback?;
|
|
41
|
+
private heartbeatInterval?;
|
|
42
|
+
private watchProgressTimer?;
|
|
43
|
+
private isBuffering;
|
|
44
|
+
private sessionId;
|
|
45
|
+
private videoId;
|
|
46
|
+
private deviceType;
|
|
47
|
+
private networkType;
|
|
48
|
+
private adBreaks;
|
|
49
|
+
private isFirstPlay;
|
|
50
|
+
private watchStartTime;
|
|
51
|
+
private totalWatchTime;
|
|
52
|
+
private streamingWindowStart;
|
|
53
|
+
private streamingTime;
|
|
54
|
+
private isInAdBreak;
|
|
55
|
+
private adWatchWindowStart;
|
|
56
|
+
private adWatchTime;
|
|
57
|
+
private bufferingCount;
|
|
58
|
+
private totalBufferingTime;
|
|
59
|
+
private bufferingStartTime;
|
|
60
|
+
private milestonesHit;
|
|
61
|
+
private lastHeartbeatPosition;
|
|
62
|
+
private lastHeartbeatAt;
|
|
63
|
+
constructor(callback?: AnalyticsCallback, src?: string, seed?: AnalyticsSessionSnapshot, videoId?: string);
|
|
64
|
+
getSessionSnapshot(): AnalyticsSessionSnapshot;
|
|
65
|
+
registerCallback(callback: AnalyticsCallback): void;
|
|
66
|
+
setAdBreaks(adBreaks: Array<{
|
|
67
|
+
startTime: number;
|
|
68
|
+
endTime: number;
|
|
69
|
+
}>): void;
|
|
70
|
+
private getTotalAdDuration;
|
|
71
|
+
private getElapsedAdTime;
|
|
72
|
+
track(eventType: AnalyticsEvent['eventType'], videoEl: HTMLVideoElement, extra?: Partial<AnalyticsEvent>): void;
|
|
73
|
+
startHeartbeat(videoEl: HTMLVideoElement, getExtra: () => Partial<AnalyticsEvent>, watchProgressInterval?: number): void;
|
|
74
|
+
stopHeartbeat(): void;
|
|
75
|
+
setBuffering(isBuffering: boolean, videoEl: HTMLVideoElement, getExtra: () => Partial<AnalyticsEvent>): void;
|
|
76
|
+
setAdBreak(inAdBreak: boolean, videoEl: HTMLVideoElement): void;
|
|
77
|
+
private checkMilestones;
|
|
78
|
+
private checkStall;
|
|
79
|
+
private getTotalWatchTime;
|
|
80
|
+
private getStreamingTime;
|
|
81
|
+
private getAdWatchTime;
|
|
82
|
+
private dispatchRaw;
|
|
83
|
+
private generateSessionId;
|
|
84
|
+
private extractVideoId;
|
|
85
|
+
private getDeviceType;
|
|
86
|
+
private getNetworkType;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
declare interface AnalyticsSessionSnapshot {
|
|
90
|
+
sessionId: string;
|
|
91
|
+
/** True once session_start has fired — a seeded module must not fire it again. */
|
|
92
|
+
sessionStartFired: boolean;
|
|
93
|
+
totalWatchTime: number;
|
|
94
|
+
streamingTime: number;
|
|
95
|
+
adWatchTime: number;
|
|
96
|
+
bufferingCount: number;
|
|
97
|
+
totalBufferingTime: number;
|
|
98
|
+
/** Quartile milestones already dispatched ('first_quartile' | 'midpoint' | 'third_quartile'). */
|
|
99
|
+
milestonesHit: string[];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export declare abstract class BasePlayerPlugin implements PlayerPlugin {
|
|
103
|
+
abstract id: string;
|
|
104
|
+
abstract name: string;
|
|
105
|
+
protected player: any;
|
|
106
|
+
install(player: any): void;
|
|
107
|
+
protected abstract onInstall(): void;
|
|
108
|
+
destroy(): void;
|
|
109
|
+
protected onDestroy(): void;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export declare class CastingModule {
|
|
113
|
+
private isCasting;
|
|
114
|
+
private castDeviceName;
|
|
115
|
+
private onCastStateChangeCallback?;
|
|
116
|
+
private onRemoteStateChangeCallback?;
|
|
117
|
+
private castContext;
|
|
118
|
+
private remotePlayer;
|
|
119
|
+
private remotePlayerController;
|
|
120
|
+
constructor();
|
|
121
|
+
private initCastApi;
|
|
122
|
+
getCastingState(): {
|
|
123
|
+
isCasting: boolean;
|
|
124
|
+
deviceName: string;
|
|
125
|
+
};
|
|
126
|
+
getRemoteState(): RemoteCastState | null;
|
|
127
|
+
/**
|
|
128
|
+
* Derives the Cast MediaInfo content type from the stream URL so HLS/DASH manifests
|
|
129
|
+
* aren't sent to the receiver mislabeled as video/mp4, which causes load failures.
|
|
130
|
+
*/
|
|
131
|
+
private getContentType;
|
|
132
|
+
/**
|
|
133
|
+
* Prompts the native Google Cast device picker overlay, then loads media on the remote device.
|
|
134
|
+
* The caller is responsible for pausing local playback before/after this resolves.
|
|
135
|
+
*/
|
|
136
|
+
requestSession(currentSrc: string, currentTime: number): Promise<void>;
|
|
137
|
+
/**
|
|
138
|
+
* Disconnects the current cast session.
|
|
139
|
+
*/
|
|
140
|
+
stopCasting(): void;
|
|
141
|
+
remotePlayPause(): void;
|
|
142
|
+
remoteSeek(time: number): void;
|
|
143
|
+
remoteSetVolume(volume: number): void;
|
|
144
|
+
remoteSetMute(muted: boolean): void;
|
|
145
|
+
onCastStateChange(callback: (isCasting: boolean, deviceName: string) => void): void;
|
|
146
|
+
onRemoteStateChange(callback: (state: RemoteCastState) => void): void;
|
|
147
|
+
requestAirPlaySession(videoElement: HTMLVideoElement): void;
|
|
148
|
+
stopAirPlay(videoElement: HTMLVideoElement): void;
|
|
149
|
+
isAirPlayAvailable(): boolean;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export declare interface Chapter {
|
|
153
|
+
title: string;
|
|
154
|
+
startTime: number;
|
|
155
|
+
endTime: number;
|
|
156
|
+
thumbnail?: string;
|
|
157
|
+
description?: string;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export declare class ChaptersModule extends KeyMomentsModule {
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export declare interface DRMConfig {
|
|
164
|
+
widevineLicenseUrl?: string;
|
|
165
|
+
playreadyLicenseUrl?: string;
|
|
166
|
+
fairplayLicenseUrl?: string;
|
|
167
|
+
authToken?: string;
|
|
168
|
+
authHeader?: string;
|
|
169
|
+
allowedDomains?: string[];
|
|
170
|
+
watermarkText?: string;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export declare class DRMModule {
|
|
174
|
+
private config?;
|
|
175
|
+
private watermarkElement?;
|
|
176
|
+
private floatInterval?;
|
|
177
|
+
constructor(config?: DRMConfig);
|
|
178
|
+
/**
|
|
179
|
+
* Validates if the active origin domain is permitted to load this stream asset.
|
|
180
|
+
*/
|
|
181
|
+
validateDomain(currentDomain: string): boolean;
|
|
182
|
+
getAuthToken(): string | undefined;
|
|
183
|
+
getAuthHeader(): string | undefined;
|
|
184
|
+
getRequestHeaders(): Record<string, string>;
|
|
185
|
+
/**
|
|
186
|
+
* Injects an animated floating watermark on top of the media container to obstruct piracy or recording.
|
|
187
|
+
*/
|
|
188
|
+
setupWatermark(container: HTMLElement): void;
|
|
189
|
+
/**
|
|
190
|
+
* Cleans up active watermarks.
|
|
191
|
+
*/
|
|
192
|
+
removeWatermark(): void;
|
|
193
|
+
isDRMProtected(): boolean;
|
|
194
|
+
getDRMDetails(): {
|
|
195
|
+
widevine: string | null;
|
|
196
|
+
playready: string | null;
|
|
197
|
+
fairplay: string | null;
|
|
198
|
+
authTokenPresent: boolean;
|
|
199
|
+
allowedDomains: string[];
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Sends all player analytics events to Firebase Analytics (GA4).
|
|
205
|
+
*
|
|
206
|
+
* Events appear in:
|
|
207
|
+
* Firebase Console → Analytics → Events (24-48 hr aggregated view)
|
|
208
|
+
* Firebase Console → Analytics → DebugView (real-time while testing)
|
|
209
|
+
* Google Analytics 4 → Reports → Realtime (within a few minutes)
|
|
210
|
+
*
|
|
211
|
+
* No Firestore / database setup required — Firebase Analytics handles all storage.
|
|
212
|
+
*/
|
|
213
|
+
export declare class FirebaseAnalyticsProvider {
|
|
214
|
+
private analytics;
|
|
215
|
+
private logEventFn;
|
|
216
|
+
private pendingEvents;
|
|
217
|
+
constructor(config: FirebaseConfig);
|
|
218
|
+
private init;
|
|
219
|
+
private flushPending;
|
|
220
|
+
createCallback(): AnalyticsCallback;
|
|
221
|
+
private handleEvent;
|
|
222
|
+
private logToFirebase;
|
|
223
|
+
private buildParams;
|
|
224
|
+
destroy(): Promise<void>;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export declare interface FirebaseConfig {
|
|
228
|
+
apiKey: string;
|
|
229
|
+
authDomain: string;
|
|
230
|
+
projectId: string;
|
|
231
|
+
storageBucket: string;
|
|
232
|
+
messagingSenderId: string;
|
|
233
|
+
appId: string;
|
|
234
|
+
measurementId?: string;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export declare type KeyMoment = Chapter;
|
|
238
|
+
|
|
239
|
+
export declare class KeyMomentsModule {
|
|
240
|
+
private keyMoments;
|
|
241
|
+
private currentMomentIndex;
|
|
242
|
+
private onMomentChangeCallback?;
|
|
243
|
+
constructor(keyMoments?: KeyMoment[]);
|
|
244
|
+
/**
|
|
245
|
+
* Sorts and stores the key moments.
|
|
246
|
+
*/
|
|
247
|
+
setKeyMoments(keyMoments: KeyMoment[]): void;
|
|
248
|
+
getKeyMoments(): KeyMoment[];
|
|
249
|
+
/**
|
|
250
|
+
* Locates the key moment corresponding to the active playback timestamp.
|
|
251
|
+
*/
|
|
252
|
+
getCurrentMoment(currentTime: number): {
|
|
253
|
+
keyMoment: KeyMoment | null;
|
|
254
|
+
index: number;
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* Evaluates if playback has crossed a key moment boundary.
|
|
258
|
+
*/
|
|
259
|
+
updateTime(currentTime: number): void;
|
|
260
|
+
/**
|
|
261
|
+
* Subscribes a callback to change events.
|
|
262
|
+
*/
|
|
263
|
+
onMomentChange(callback: (keyMoment: KeyMoment | null, index: number) => void): void;
|
|
264
|
+
setChapters(chapters: KeyMoment[]): void;
|
|
265
|
+
getChapters(): KeyMoment[];
|
|
266
|
+
getCurrentChapter(currentTime: number): {
|
|
267
|
+
chapter: KeyMoment | null;
|
|
268
|
+
index: number;
|
|
269
|
+
};
|
|
270
|
+
onChapterChange(callback: (chapter: KeyMoment | null, index: number) => void): void;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export declare interface PlayerPlugin {
|
|
274
|
+
id: string;
|
|
275
|
+
name: string;
|
|
276
|
+
install(player: any): void;
|
|
277
|
+
destroy?(): void;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export declare interface PlayerSDKOptions {
|
|
281
|
+
container: HTMLElement;
|
|
282
|
+
src: string;
|
|
283
|
+
autoplay?: boolean;
|
|
284
|
+
muted?: boolean;
|
|
285
|
+
controls?: boolean;
|
|
286
|
+
chapters?: Chapter[];
|
|
287
|
+
keyMoments?: KeyMoment[];
|
|
288
|
+
subtitles?: SubtitleTrack[];
|
|
289
|
+
thumbnails?: ThumbnailConfig;
|
|
290
|
+
drm?: DRMConfig;
|
|
291
|
+
analyticsCallback?: AnalyticsCallback;
|
|
292
|
+
videoId?: string;
|
|
293
|
+
analyticsSessionSeed?: AnalyticsSessionSnapshot;
|
|
294
|
+
watchProgressInterval?: number;
|
|
295
|
+
themeColor?: string;
|
|
296
|
+
watermark?: string;
|
|
297
|
+
/**
|
|
298
|
+
* Optional URL transformer applied to every HLS segment/manifest request.
|
|
299
|
+
* Use this to route requests through a CORS proxy without hardcoding domains.
|
|
300
|
+
* Example: (url) => url.replace('https://cdn.example.com', '/my-proxy')
|
|
301
|
+
*/
|
|
302
|
+
urlTransformer?: (url: string) => string;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
declare interface RemoteCastState {
|
|
306
|
+
currentTime: number;
|
|
307
|
+
duration: number;
|
|
308
|
+
isPaused: boolean;
|
|
309
|
+
volumeLevel: number;
|
|
310
|
+
isMuted: boolean;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export declare class SubtitlesModule {
|
|
314
|
+
private tracks;
|
|
315
|
+
private activeTrackId;
|
|
316
|
+
private currentCues;
|
|
317
|
+
private activeText;
|
|
318
|
+
private onSubtitleChangeCallback?;
|
|
319
|
+
private onTrackSwitchCallback?;
|
|
320
|
+
constructor(tracks?: SubtitleTrack[]);
|
|
321
|
+
getTracks(): SubtitleTrack[];
|
|
322
|
+
getActiveTrackId(): string;
|
|
323
|
+
setHlsTracks(hlsTracks: SubtitleTrack[]): void;
|
|
324
|
+
addTrack(track: SubtitleTrack): void;
|
|
325
|
+
onTrackSwitch(callback: (track: SubtitleTrack | null) => void): void;
|
|
326
|
+
setCustomSubtitleText(text: string): void;
|
|
327
|
+
/**
|
|
328
|
+
* Switches the active track. Fetches external tracks if they need loading.
|
|
329
|
+
*/
|
|
330
|
+
setActiveTrack(trackId: string): Promise<void>;
|
|
331
|
+
/**
|
|
332
|
+
* Scans the subtitle cues for the current playback position.
|
|
333
|
+
*/
|
|
334
|
+
updateTime(currentTime: number): void;
|
|
335
|
+
/**
|
|
336
|
+
* Triggers the text update callback if a change in caption is detected.
|
|
337
|
+
*/
|
|
338
|
+
private updateActiveText;
|
|
339
|
+
onSubtitleChange(callback: (text: string) => void): void;
|
|
340
|
+
/**
|
|
341
|
+
* Robust parser supporting WebVTT and SRT formats.
|
|
342
|
+
*/
|
|
343
|
+
private parseVttOrSrt;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export declare interface SubtitleTrack {
|
|
347
|
+
id: string;
|
|
348
|
+
label: string;
|
|
349
|
+
lang: string;
|
|
350
|
+
src?: string;
|
|
351
|
+
isDefault?: boolean;
|
|
352
|
+
cues?: Array<{
|
|
353
|
+
startTime: number;
|
|
354
|
+
endTime: number;
|
|
355
|
+
text: string;
|
|
356
|
+
}>;
|
|
357
|
+
isHls?: boolean;
|
|
358
|
+
hlsTrackId?: number;
|
|
359
|
+
isNative?: boolean;
|
|
360
|
+
nativeTrackIndex?: number;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export declare interface ThumbnailConfig {
|
|
364
|
+
spriteUrl: string;
|
|
365
|
+
tileWidth: number;
|
|
366
|
+
tileHeight: number;
|
|
367
|
+
columns: number;
|
|
368
|
+
rows: number;
|
|
369
|
+
interval: number;
|
|
370
|
+
totalCount: number;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export declare class ThumbnailsModule {
|
|
374
|
+
private config?;
|
|
375
|
+
constructor(config?: ThumbnailConfig);
|
|
376
|
+
/**
|
|
377
|
+
* Calculates the position offset inside the sprite sheet for a given seek hover time.
|
|
378
|
+
*/
|
|
379
|
+
getThumbnail(time: number): {
|
|
380
|
+
url: string;
|
|
381
|
+
x: number;
|
|
382
|
+
y: number;
|
|
383
|
+
width: number;
|
|
384
|
+
height: number;
|
|
385
|
+
} | null;
|
|
386
|
+
hasThumbnails(): boolean;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export declare class VideoPlayerSDK {
|
|
390
|
+
private options;
|
|
391
|
+
private videoElement;
|
|
392
|
+
private hlsInstance;
|
|
393
|
+
private dashInstance;
|
|
394
|
+
private activeQuality;
|
|
395
|
+
private qualityLevels;
|
|
396
|
+
analytics: AnalyticsModule;
|
|
397
|
+
keyMoments: KeyMomentsModule;
|
|
398
|
+
chapters: ChaptersModule;
|
|
399
|
+
subtitles: SubtitlesModule;
|
|
400
|
+
drm: DRMModule;
|
|
401
|
+
casting: CastingModule;
|
|
402
|
+
thumbnails: ThumbnailsModule;
|
|
403
|
+
private hlsSubtitleCues;
|
|
404
|
+
private hlsActiveSubtitleKey;
|
|
405
|
+
private audioTrackList;
|
|
406
|
+
private adBreaks;
|
|
407
|
+
private isAdBreak;
|
|
408
|
+
private adBreaksFromAvails;
|
|
409
|
+
private contentPlaybackRate;
|
|
410
|
+
private networkErrorRetries;
|
|
411
|
+
private mediaErrorRecovered;
|
|
412
|
+
private static readonly MAX_NETWORK_RETRIES;
|
|
413
|
+
private static readonly TERMINAL_HTTP_STATUSES;
|
|
414
|
+
private static readonly STALL_TIMEOUT_MS;
|
|
415
|
+
private stallTimer;
|
|
416
|
+
private isBuffering;
|
|
417
|
+
private progressTick;
|
|
418
|
+
private hasFailed;
|
|
419
|
+
private lastPlaybackPos;
|
|
420
|
+
private pendingSeekAttribution;
|
|
421
|
+
private eventListeners;
|
|
422
|
+
constructor(options: PlayerSDKOptions);
|
|
423
|
+
/**
|
|
424
|
+
* Builds the video DOM hierarchy, binds events, validates domain restrictions, and mounts DRM watermarks.
|
|
425
|
+
*/
|
|
426
|
+
private initializePlayer;
|
|
427
|
+
/**
|
|
428
|
+
* Binds direct event listeners to the native HTML5 Video tag, routing them to our sub-packages.
|
|
429
|
+
*/
|
|
430
|
+
private bindMediaEvents;
|
|
431
|
+
private rewriteToProxy;
|
|
432
|
+
/**
|
|
433
|
+
* Initializes HLS adaptive streaming through Hls.js or falls back to native browser playback.
|
|
434
|
+
*/
|
|
435
|
+
private loadSource;
|
|
436
|
+
/**
|
|
437
|
+
* Sets up global lock-screen metadata and media control keys (Media Session API).
|
|
438
|
+
*/
|
|
439
|
+
private setupBackgroundControls;
|
|
440
|
+
play(): void;
|
|
441
|
+
pause(): void;
|
|
442
|
+
seek(seconds: number): void;
|
|
443
|
+
/**
|
|
444
|
+
* Attributes the NEXT seek to a specific user gesture so telemetry reports it as
|
|
445
|
+
* `fast_forward` / `fast_backward` / `key_moments` instead of a generic `seek`.
|
|
446
|
+
* Call immediately before triggering the seek. The attribution expires after a
|
|
447
|
+
* short window so it can never leak onto an unrelated later seek.
|
|
448
|
+
*/
|
|
449
|
+
attributeNextSeek(eventType: 'fast_forward' | 'fast_backward' | 'key_moments', extras?: Partial<AnalyticsEvent>): void;
|
|
450
|
+
setVolume(volume: number): void;
|
|
451
|
+
setMute(muted: boolean): void;
|
|
452
|
+
setPlaybackRate(rate: number): void;
|
|
453
|
+
/**
|
|
454
|
+
* Sets manual video quality rendition or switches back to auto bitrate scaling.
|
|
455
|
+
*/
|
|
456
|
+
setQuality(qualityId: number): void;
|
|
457
|
+
/**
|
|
458
|
+
* Activates native Picture-in-Picture floating viewport.
|
|
459
|
+
*/
|
|
460
|
+
togglePictureInPicture(): Promise<boolean>;
|
|
461
|
+
/**
|
|
462
|
+
* Requests element-level fullscreen.
|
|
463
|
+
*/
|
|
464
|
+
toggleFullscreen(): void;
|
|
465
|
+
getVideoElement(): HTMLVideoElement;
|
|
466
|
+
getCurrentTime(): number;
|
|
467
|
+
getDuration(): number;
|
|
468
|
+
getVolume(): number;
|
|
469
|
+
isMuted(): boolean;
|
|
470
|
+
getPlaybackRate(): number;
|
|
471
|
+
getActiveQuality(): VideoQuality;
|
|
472
|
+
getQualityLevels(): VideoQuality[];
|
|
473
|
+
getBufferLength(): number;
|
|
474
|
+
getBufferedRanges(): Array<{
|
|
475
|
+
start: number;
|
|
476
|
+
end: number;
|
|
477
|
+
}>;
|
|
478
|
+
/**
|
|
479
|
+
* Returns true if the browser can decode at least one of the manifest's renditions.
|
|
480
|
+
*
|
|
481
|
+
* Deliberately conservative to avoid ever blocking a valid stream:
|
|
482
|
+
* - A codec that isn't declared is treated as playable (we never assume unsupported).
|
|
483
|
+
* - Any failure to verify (no MediaSource, isTypeSupported throws) returns true.
|
|
484
|
+
* - The stream is "playable" if even one rendition's declared codecs are all supported,
|
|
485
|
+
* matching how HLS.js itself selects a level.
|
|
486
|
+
* Returns false only when the browser explicitly reports every declared codec as
|
|
487
|
+
* undecodable (e.g. Dolby EC-3/AC-3 in Chrome).
|
|
488
|
+
*/
|
|
489
|
+
private hasPlayableLevel;
|
|
490
|
+
private getAnalyticsPayload;
|
|
491
|
+
on(event: string, callback: (...args: any[]) => void): void;
|
|
492
|
+
off(event: string, callback: (...args: any[]) => void): void;
|
|
493
|
+
private emit;
|
|
494
|
+
private extractSubtitlesFromManifest;
|
|
495
|
+
private extractKeyMomentsFromManifest;
|
|
496
|
+
private extractAdBreaksFromManifest;
|
|
497
|
+
private buildManifestUrl;
|
|
498
|
+
private findFirstVariantUri;
|
|
499
|
+
private resolveUrl;
|
|
500
|
+
private static readonly AD_HOST_PATTERNS;
|
|
501
|
+
private static readonly AD_STITCHER_PATH_PATTERNS;
|
|
502
|
+
private static readonly AD_PATH_HINT_PATTERNS;
|
|
503
|
+
private parseSegmentUrl;
|
|
504
|
+
private isKnownAdSegment;
|
|
505
|
+
private hasAdPathHint;
|
|
506
|
+
private classifyAdGroups;
|
|
507
|
+
private mergeAdjacentRanges;
|
|
508
|
+
private parseAdBreaksFromFragments;
|
|
509
|
+
private parseAdBreaksFromPlaylist;
|
|
510
|
+
private sameAdBreaks;
|
|
511
|
+
private isTimeInAdBreak;
|
|
512
|
+
/**
|
|
513
|
+
* Syncs isAdBreak/playbackRate/ad-mode UI state against `time` and emits
|
|
514
|
+
* adbreakchange on transitions. Called from timeupdate, but also called
|
|
515
|
+
* eagerly as soon as ad breaks or metadata become known — timeupdate alone
|
|
516
|
+
* doesn't fire until playback actually starts, which left a preroll ad's
|
|
517
|
+
* first frame briefly showing content controls (rewind/forward, etc.)
|
|
518
|
+
* while autoplay was blocked or the source was still buffering.
|
|
519
|
+
*/
|
|
520
|
+
private refreshAdBreakState;
|
|
521
|
+
/**
|
|
522
|
+
* Converts raw (stitched) video time to content-only time by subtracting the
|
|
523
|
+
* ad time elapsed before `time`. During an ad break the result is frozen at
|
|
524
|
+
* the content timestamp where the break started. Identity when no ad breaks
|
|
525
|
+
* are known. Mirrors the seekbar mapping in the UI layer.
|
|
526
|
+
*/
|
|
527
|
+
private videoTimeToContentTime;
|
|
528
|
+
getAdBreaks(): Array<{
|
|
529
|
+
startTime: number;
|
|
530
|
+
endTime: number;
|
|
531
|
+
}>;
|
|
532
|
+
setAdBreaks(breaks: Array<{
|
|
533
|
+
startTime: number;
|
|
534
|
+
endTime: number;
|
|
535
|
+
}>): void;
|
|
536
|
+
isInAdBreak(): boolean;
|
|
537
|
+
getAudioTracks(): Array<{
|
|
538
|
+
id: number;
|
|
539
|
+
label: string;
|
|
540
|
+
lang: string;
|
|
541
|
+
}>;
|
|
542
|
+
setAudioTrack(id: number): void;
|
|
543
|
+
/**
|
|
544
|
+
* Arms a one-shot timer while buffering. If the timer fires and no data has
|
|
545
|
+
* arrived since it was armed (progressTick unchanged) and we're still
|
|
546
|
+
* buffering, the stream is considered dead. If data did arrive but we're still
|
|
547
|
+
* buffering (slow connection), it re-arms for another window rather than
|
|
548
|
+
* failing — so slow internet never trips it.
|
|
549
|
+
*/
|
|
550
|
+
private armStallWatchdog;
|
|
551
|
+
private clearStallWatchdog;
|
|
552
|
+
/**
|
|
553
|
+
* Terminal error path: emit 'error' (which drives the error screen) and tear
|
|
554
|
+
* down the player. Guarded so it runs at most once, no matter how many error
|
|
555
|
+
* events fire during teardown.
|
|
556
|
+
*/
|
|
557
|
+
private fail;
|
|
558
|
+
destroy(): void;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
export declare interface VideoQuality {
|
|
562
|
+
id: number;
|
|
563
|
+
height: number;
|
|
564
|
+
width: number;
|
|
565
|
+
bitrate: number;
|
|
566
|
+
label: string;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
export { }
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c } from "./src-B8eoxemB.js";
|
|
2
|
+
//#region ../plugins/src/plugins.ts
|
|
3
|
+
var l = class {
|
|
4
|
+
player;
|
|
5
|
+
install(e) {
|
|
6
|
+
this.player = e, this.onInstall();
|
|
7
|
+
}
|
|
8
|
+
destroy() {
|
|
9
|
+
this.onDestroy();
|
|
10
|
+
}
|
|
11
|
+
onDestroy() {}
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { r as AnalyticsModule, l as BasePlayerPlugin, o as CastingModule, a as ChaptersModule, n as DRMModule, t as FirebaseAnalyticsProvider, s as KeyMomentsModule, e as SubtitlesModule, i as ThumbnailsModule, c as VideoPlayerSDK };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","names":[],"sources":["../../plugins/src/plugins.ts"],"sourcesContent":["export interface PlayerPlugin {\r\n id: string;\r\n name: string;\r\n install(player: any): void;\r\n destroy?(): void;\r\n}\r\n\r\nexport abstract class BasePlayerPlugin implements PlayerPlugin {\r\n public abstract id: string;\r\n public abstract name: string;\r\n protected player: any;\r\n\r\n public install(player: any): void {\r\n this.player = player;\r\n this.onInstall();\r\n }\r\n\r\n protected abstract onInstall(): void;\r\n\r\n public destroy(): void {\r\n this.onDestroy();\r\n }\r\n\r\n protected onDestroy(): void {}\r\n}\r\n"],"mappings":";;AAOA,IAAsB,IAAtB,MAA+D;CAG7D;CAEA,QAAe,GAAmB;EAEhC,AADA,KAAK,SAAS,GACd,KAAK,UAAU;CACjB;CAIA,UAAuB;EACrB,KAAK,UAAU;CACjB;CAEA,YAA4B,CAAC;AAC/B"}
|