stormcloud-video-player 0.7.49 → 0.8.0
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/README.md +269 -228
- package/dist/stormcloud-vp.min.js +1 -1
- package/lib/index.cjs +5197 -6741
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +196 -195
- package/lib/index.d.ts +196 -195
- package/lib/index.js +5326 -6862
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +4802 -3170
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +113 -70
- package/lib/players/FilePlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +4810 -3179
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +4877 -3246
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +1021 -0
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -0
- package/lib/sdk/hlsAdPlayer.d.cts +10 -0
- package/lib/sdk/pal.cjs +358 -0
- package/lib/sdk/pal.cjs.map +1 -0
- package/lib/sdk/pal.d.cts +28 -0
- package/lib/{types-CIHDHY7A.d.cts → types-DDwAfBLt.d.cts} +11 -10
- package/lib/ui/StormcloudVideoPlayer.cjs +5070 -6603
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.d.cts +1 -14
- package/lib/utils/browserCompat.cjs +10 -114
- package/lib/utils/browserCompat.cjs.map +1 -1
- package/lib/utils/browserCompat.d.cts +3 -7
- package/lib/utils/polyfills.cjs.map +1 -1
- package/lib/utils/tracking.cjs +179 -150
- package/lib/utils/tracking.cjs.map +1 -1
- package/lib/utils/tracking.d.cts +11 -6
- package/package.json +1 -2
- package/lib/sdk/adstormPlayer.cjs +0 -1567
- package/lib/sdk/adstormPlayer.cjs.map +0 -1
- package/lib/sdk/adstormPlayer.d.cts +0 -23
- package/lib/sdk/vastParser.cjs +0 -517
- package/lib/sdk/vastParser.cjs.map +0 -1
- package/lib/sdk/vastParser.d.cts +0 -45
- package/lib/ui/OverlayRenderer.cjs +0 -2370
- package/lib/ui/OverlayRenderer.cjs.map +0 -1
- package/lib/ui/OverlayRenderer.d.cts +0 -17
- package/lib/utils/adcision.cjs +0 -282
- package/lib/utils/adcision.cjs.map +0 -1
- package/lib/utils/adcision.d.cts +0 -31
- package/lib/utils/overlays.cjs +0 -354
- package/lib/utils/overlays.cjs.map +0 -1
- package/lib/utils/overlays.d.cts +0 -70
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import { S as StormcloudVideoPlayerConfig } from '../types-
|
|
1
|
+
import { S as StormcloudVideoPlayerConfig } from '../types-DDwAfBLt.cjs';
|
|
2
2
|
|
|
3
|
-
type DebugLogLevel = "info" | "warn" | "error";
|
|
4
3
|
declare class StormcloudVideoPlayer {
|
|
5
4
|
private readonly video;
|
|
6
5
|
private readonly config;
|
|
7
6
|
private hls?;
|
|
8
|
-
private
|
|
9
|
-
private pendingNextAdBids;
|
|
10
|
-
private continuousFetchLoopPromise;
|
|
7
|
+
private adPlayer;
|
|
11
8
|
private attached;
|
|
12
9
|
private inAdBreak;
|
|
13
10
|
private currentAdBreakStartWallClockMs;
|
|
14
11
|
private expectedAdBreakDurationMs;
|
|
15
12
|
private adStopTimerId;
|
|
13
|
+
private adStartTimerId;
|
|
16
14
|
private adFailsafeTimerId;
|
|
15
|
+
private ptsDriftEmaMs;
|
|
17
16
|
private adPodQueue;
|
|
17
|
+
private apiVastTagUrl;
|
|
18
|
+
private apiNumberAds;
|
|
19
|
+
private vmapBreaks;
|
|
20
|
+
private consumedVmapBreakIds;
|
|
18
21
|
private lastHeartbeatTime;
|
|
19
22
|
private heartbeatInterval;
|
|
20
23
|
private currentAdIndex;
|
|
@@ -26,115 +29,164 @@ declare class StormcloudVideoPlayer {
|
|
|
26
29
|
private bufferedSegmentsCount;
|
|
27
30
|
private shouldAutoplayAfterBuffering;
|
|
28
31
|
private hasInitialBufferCompleted;
|
|
32
|
+
private adRequestTokenCounter;
|
|
29
33
|
private activeAdRequestToken;
|
|
30
34
|
private adRequestWatchdogId;
|
|
31
35
|
private adRequestWatchdogToken;
|
|
32
36
|
private adFailsafeToken;
|
|
37
|
+
private failedVastUrls;
|
|
38
|
+
private temporaryFailureUrls;
|
|
39
|
+
private readonly temporaryFailureCooldownMs;
|
|
33
40
|
private continuousFetchingActive;
|
|
34
|
-
private
|
|
41
|
+
private adRequestQueue;
|
|
35
42
|
private maxPlaceholderDurationMs;
|
|
36
43
|
private isShowingPlaceholder;
|
|
37
44
|
private timeUpdateHandler?;
|
|
38
45
|
private emptiedHandler?;
|
|
39
|
-
private
|
|
40
|
-
private
|
|
41
|
-
private
|
|
42
|
-
private
|
|
46
|
+
private readonly tsScte35Pids;
|
|
47
|
+
private readonly pmtPids;
|
|
48
|
+
private readonly processedTsScte35Sections;
|
|
49
|
+
private readonly pendingScte35Cues;
|
|
50
|
+
private readonly recentScte35CueKeys;
|
|
51
|
+
private readonly recentScte35CueLimit;
|
|
52
|
+
private pendingScte35CueKey;
|
|
53
|
+
private activeScte35BreakKey;
|
|
54
|
+
private scheduledScte35BreakKey;
|
|
43
55
|
private totalAdRequestsInBreak;
|
|
44
56
|
private readonly maxTotalAdRequestsPerBreak;
|
|
45
57
|
private pendingAdBreak;
|
|
46
58
|
private prefetchTimerId;
|
|
47
|
-
private savedMutedStateBeforeAd;
|
|
48
|
-
private adLayerInitialized;
|
|
49
59
|
private consecutiveFailures;
|
|
50
60
|
private readonly maxConsecutiveFailures;
|
|
51
61
|
private lastAdRequestTime;
|
|
52
62
|
private readonly minAdRequestIntervalMs;
|
|
53
63
|
private readonly backoffBaseMs;
|
|
54
64
|
private readonly maxBackoffMs;
|
|
55
|
-
private
|
|
56
|
-
private
|
|
57
|
-
private readonly
|
|
58
|
-
private
|
|
59
|
-
private readonly
|
|
60
|
-
private
|
|
61
|
-
private
|
|
62
|
-
private
|
|
63
|
-
private
|
|
64
|
-
private
|
|
65
|
+
private placeholderContainer;
|
|
66
|
+
private globalConsecutiveNoFills;
|
|
67
|
+
private readonly globalNoFillThreshold;
|
|
68
|
+
private globalNoFillCooldownUntil;
|
|
69
|
+
private readonly globalNoFillBackoffBaseMs;
|
|
70
|
+
private readonly globalNoFillBackoffMaxMs;
|
|
71
|
+
private globalLastGamRequestTime;
|
|
72
|
+
private readonly globalMinGamIntervalMs;
|
|
73
|
+
private preloadPool;
|
|
74
|
+
private readonly maxPreloadPoolSize;
|
|
75
|
+
private preloadPoolActive;
|
|
76
|
+
private preloadPoolLoopRunning;
|
|
77
|
+
private adDetectSentForCurrentBreak;
|
|
78
|
+
private palNonce;
|
|
79
|
+
private palPlaybackStarted;
|
|
65
80
|
constructor(config: StormcloudVideoPlayerConfig);
|
|
66
|
-
private
|
|
81
|
+
private createAdPlayer;
|
|
67
82
|
load(): Promise<void>;
|
|
68
|
-
private
|
|
69
|
-
private
|
|
70
|
-
private
|
|
83
|
+
private attachImaEventListeners;
|
|
84
|
+
private recreateAdController;
|
|
85
|
+
private ensurePlaceholderContainer;
|
|
71
86
|
private showPlaceholderLayer;
|
|
72
87
|
private hidePlaceholderLayer;
|
|
73
|
-
private startFillerBreakTimer;
|
|
74
|
-
private stopFillerBreakTimer;
|
|
75
88
|
private attach;
|
|
76
89
|
private shouldUseNativeHls;
|
|
90
|
+
private onId3Tag;
|
|
91
|
+
private parseScte35FromId3;
|
|
92
|
+
private decodeId3ValueToText;
|
|
93
|
+
private createScte35CueContext;
|
|
94
|
+
private getFragmentStartSeconds;
|
|
95
|
+
private onScte35Cue;
|
|
96
|
+
private createScte35Cue;
|
|
97
|
+
private getScte35CueKey;
|
|
98
|
+
private getPendingScte35CueKey;
|
|
99
|
+
private getScte35MarkerRaw;
|
|
100
|
+
private toIdentityString;
|
|
101
|
+
private isStrongScte35CueKey;
|
|
102
|
+
private hasRecentlyHandledScte35Cue;
|
|
103
|
+
private markScte35CueHandled;
|
|
104
|
+
private trimRecentScte35CueMaps;
|
|
105
|
+
private shouldAcceptScte35EndCue;
|
|
106
|
+
private activatePendingScte35CuesForFragment;
|
|
107
|
+
private onScte35Marker;
|
|
108
|
+
private startScte35AdBreak;
|
|
109
|
+
private parseCueOutDuration;
|
|
110
|
+
private parseCueOutCont;
|
|
111
|
+
private parseAttributeList;
|
|
112
|
+
private toNumber;
|
|
113
|
+
private isManifestBasedMarker;
|
|
114
|
+
private normalizeFragmentPayload;
|
|
115
|
+
private processFragmentScte35Payload;
|
|
116
|
+
private parseScte35FromTsPackets;
|
|
117
|
+
private detectTsPacketFormat;
|
|
118
|
+
private parsePatSection;
|
|
119
|
+
private parsePmtSection;
|
|
120
|
+
private descriptorsIdentifyScte35;
|
|
121
|
+
private collectScte35SectionsFromPayload;
|
|
122
|
+
private appendScte35Bytes;
|
|
123
|
+
private addScte35SectionMarker;
|
|
124
|
+
private hasProcessedTsScte35Section;
|
|
125
|
+
private getPsiSectionStart;
|
|
126
|
+
private getPsiSectionLength;
|
|
127
|
+
private parseScte35Binary;
|
|
128
|
+
private parseScte35SegmentationDescriptors;
|
|
129
|
+
private parseScte35SegmentationDescriptor;
|
|
130
|
+
private markerTypeFromSegmentationTypeId;
|
|
77
131
|
private initializeTracking;
|
|
78
132
|
private sendHeartbeatIfNeeded;
|
|
133
|
+
private fetchAdConfiguration;
|
|
134
|
+
private fetchAndParseVmap;
|
|
135
|
+
private parseVmapToBreaks;
|
|
136
|
+
private parseVmapTimeOffsetToMs;
|
|
137
|
+
private getAdBreakKey;
|
|
138
|
+
private resolveBreakStartMs;
|
|
79
139
|
getCurrentAdIndex(): number;
|
|
80
140
|
getTotalAdsInBreak(): number;
|
|
81
|
-
|
|
141
|
+
getAdRemainingMs(): number;
|
|
142
|
+
private generateVastUrlsWithCorrelators;
|
|
82
143
|
isAdPlaying(): boolean;
|
|
83
144
|
isShowingAds(): boolean;
|
|
84
|
-
isInAdBreak(): boolean;
|
|
85
|
-
private initializeAdLayer;
|
|
86
|
-
setDisableAds(disabled: boolean): void;
|
|
87
|
-
private syncMainContentAudioWhenVisible;
|
|
88
145
|
getStreamType(): "hls" | "other";
|
|
89
146
|
shouldShowNativeControls(): boolean;
|
|
90
147
|
private shouldContinueLiveStreamDuringAds;
|
|
91
148
|
private startAdPrefetch;
|
|
92
|
-
private runAdPrefetch;
|
|
93
149
|
private clearPendingAdBreak;
|
|
94
|
-
private
|
|
95
|
-
private
|
|
96
|
-
private
|
|
97
|
-
private
|
|
98
|
-
private
|
|
99
|
-
private extractTsFilename;
|
|
100
|
-
private fragmentMatchesSegment;
|
|
101
|
-
private clearAdInsertionOffsetTimer;
|
|
102
|
-
private startContinuousFetchLoop;
|
|
103
|
-
private runContinuousFetchLoop;
|
|
150
|
+
private startPreloadPool;
|
|
151
|
+
private preloadAdIntoPool;
|
|
152
|
+
private preloadPoolLoop;
|
|
153
|
+
private getPreloadedAd;
|
|
154
|
+
private stopPreloadPool;
|
|
104
155
|
private handleAdStart;
|
|
156
|
+
private continuousFetchLoopRunning;
|
|
157
|
+
private startContinuousFetching;
|
|
158
|
+
private continuousFetchLoop;
|
|
105
159
|
private stopContinuousFetching;
|
|
106
160
|
private tryNextAvailableAdWithRateLimit;
|
|
107
161
|
private tryNextAvailableAd;
|
|
108
162
|
private showPlaceholderAndWaitForAds;
|
|
163
|
+
private findCurrentOrNextBreak;
|
|
109
164
|
private onTimeUpdate;
|
|
165
|
+
private handleMidAdJoin;
|
|
110
166
|
private scheduleAdStopCountdown;
|
|
111
167
|
private clearAdStopTimer;
|
|
112
168
|
private ensureAdStoppedByTimer;
|
|
169
|
+
private scheduleAdStartIn;
|
|
170
|
+
private clearAdStartTimer;
|
|
171
|
+
private updatePtsDrift;
|
|
172
|
+
private isTemporaryAdError;
|
|
173
|
+
private isUrlInCooldown;
|
|
174
|
+
private cleanupTemporaryFailures;
|
|
175
|
+
private isGamInCooldown;
|
|
176
|
+
private recordGamNoFill;
|
|
177
|
+
private resetGamNoFillCounter;
|
|
178
|
+
private enforceGlobalRateLimit;
|
|
179
|
+
private playSingleAd;
|
|
113
180
|
private handleAdPodComplete;
|
|
114
181
|
private handleAdFailure;
|
|
115
182
|
private startAdRequestWatchdog;
|
|
116
183
|
private clearAdRequestWatchdog;
|
|
117
184
|
private startAdFailsafeTimer;
|
|
118
185
|
private clearAdFailsafeTimer;
|
|
186
|
+
private selectVastTagsForBreak;
|
|
119
187
|
private logAdState;
|
|
120
188
|
private getRemainingAdMs;
|
|
121
|
-
private
|
|
122
|
-
private pushAdInsertionDebug;
|
|
123
|
-
getAdInsertionDebugLog(): ReadonlyArray<{
|
|
124
|
-
timestampMs: number;
|
|
125
|
-
event: string;
|
|
126
|
-
segmentName: string;
|
|
127
|
-
offsetSeconds?: number;
|
|
128
|
-
updatedAt?: string;
|
|
129
|
-
detail?: string;
|
|
130
|
-
}>;
|
|
131
|
-
getDebugLogs(): ReadonlyArray<{
|
|
132
|
-
timestampMs: number;
|
|
133
|
-
level: DebugLogLevel;
|
|
134
|
-
category: string;
|
|
135
|
-
message: string;
|
|
136
|
-
details?: Record<string, unknown>;
|
|
137
|
-
}>;
|
|
189
|
+
private findBreakForTime;
|
|
138
190
|
toggleMute(): void;
|
|
139
191
|
toggleFullscreen(): Promise<void>;
|
|
140
192
|
isMuted(): boolean;
|
|
@@ -143,15 +195,6 @@ declare class StormcloudVideoPlayer {
|
|
|
143
195
|
getVolume(): number;
|
|
144
196
|
isFullscreen(): boolean;
|
|
145
197
|
isLive(): boolean;
|
|
146
|
-
getMinHlsResolution(): {
|
|
147
|
-
width: number;
|
|
148
|
-
height: number;
|
|
149
|
-
} | null;
|
|
150
|
-
getMaxHlsResolution(): {
|
|
151
|
-
width: number;
|
|
152
|
-
height: number;
|
|
153
|
-
} | null;
|
|
154
|
-
getCurrentHlsSegmentDurationMs(): number | null;
|
|
155
198
|
get videoElement(): HTMLVideoElement;
|
|
156
199
|
resize(): void;
|
|
157
200
|
destroy(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/players/FilePlayer.cjs"],"names":[
|
|
1
|
+
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/players/FilePlayer.cjs"],"names":[],"mappings":"AAAA","sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/players/FilePlayer.tsx\nvar FilePlayer_exports = {};\n__export(FilePlayer_exports, {\n default: () => FilePlayer\n});\nmodule.exports = __toCommonJS(FilePlayer_exports);\nvar import_react = require(\"react\");\n\n// src/patterns.ts\nvar HLS_EXTENSIONS = /\\.(m3u8)($|\\?)/i;\nvar HLS_PATHS = /\\/hls\\//i;\nvar DASH_EXTENSIONS = /\\.(mpd)($|\\?)/i;\nvar VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\\?)/i;\nvar AUDIO_EXTENSIONS = /\\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\\?)/i;\nvar canPlay = {\n hls: (url) => {\n if (!url || typeof url !== \"string\") return false;\n return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);\n },\n dash: (url) => {\n if (!url || typeof url !== \"string\") return false;\n return DASH_EXTENSIONS.test(url);\n },\n video: (url) => {\n if (!url || typeof url !== \"string\") return false;\n return VIDEO_EXTENSIONS.test(url);\n },\n audio: (url) => {\n if (!url || typeof url !== \"string\") return false;\n return AUDIO_EXTENSIONS.test(url);\n },\n file: (url) => {\n if (!url || typeof url !== \"string\") return false;\n return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);\n }\n};\n\n// src/players/FilePlayer.tsx\nvar FilePlayer = class extends import_react.Component {\n constructor() {\n super(...arguments);\n this.mounted = false;\n this.ready = false;\n this.load = () => {\n if (!this.props.videoElement || !this.props.src) return;\n const video = this.props.videoElement;\n const handleLoadedMetadata = () => {\n if (this.mounted && !this.ready) {\n this.ready = true;\n this.props.onReady?.();\n }\n };\n const handlePlay = () => {\n if (this.mounted) {\n this.props.onPlay?.();\n }\n };\n const handlePause = () => {\n if (this.mounted) {\n this.props.onPause?.();\n }\n };\n const handleEnded = () => {\n if (this.mounted) {\n this.props.onEnded?.();\n }\n };\n const handleError = (error) => {\n if (this.mounted) {\n this.props.onError?.(error);\n }\n };\n const handleLoadedData = () => {\n if (this.mounted) {\n this.props.onLoaded?.();\n }\n };\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"play\", handlePlay);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n video.addEventListener(\"error\", handleError);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.src = this.props.src;\n if (this.props.autoplay !== void 0) video.autoplay = this.props.autoplay;\n if (this.props.muted !== void 0) video.muted = this.props.muted;\n if (this.props.loop !== void 0) video.loop = this.props.loop;\n if (this.props.controls !== void 0) video.controls = this.props.controls;\n if (this.props.playsInline !== void 0)\n video.playsInline = this.props.playsInline;\n if (this.props.preload !== void 0)\n video.preload = this.props.preload;\n if (this.props.poster !== void 0) video.poster = this.props.poster;\n this.props.onMount?.(this);\n return () => {\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"play\", handlePlay);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n video.removeEventListener(\"error\", handleError);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n };\n };\n this.play = () => {\n if (this.props.videoElement) {\n const video = this.props.videoElement;\n const hasValidSource = video.src || video.currentSrc && video.currentSrc !== \"\" || video.readyState >= 1;\n if (hasValidSource) {\n video.play()?.catch((error) => {\n console.error(\"[FilePlayer] Failed to play:\", error);\n this.props.onError?.(error);\n });\n } else {\n console.warn(\"[FilePlayer] Cannot play: video has no valid source\");\n }\n }\n };\n this.pause = () => {\n if (this.props.videoElement) {\n this.props.videoElement.pause();\n }\n };\n this.stop = () => {\n this.pause();\n if (this.props.videoElement) {\n this.props.videoElement.currentTime = 0;\n }\n };\n this.seekTo = (seconds, keepPlaying) => {\n if (this.props.videoElement) {\n this.props.videoElement.currentTime = seconds;\n if (!keepPlaying) {\n this.pause();\n }\n }\n };\n this.setVolume = (volume) => {\n if (this.props.videoElement) {\n this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n }\n };\n this.mute = () => {\n if (this.props.videoElement) {\n this.props.videoElement.muted = true;\n }\n };\n this.unmute = () => {\n if (this.props.videoElement) {\n this.props.videoElement.muted = false;\n }\n };\n this.setPlaybackRate = (rate) => {\n if (this.props.videoElement && rate > 0) {\n this.props.videoElement.playbackRate = rate;\n }\n };\n this.setLoop = (loop) => {\n if (this.props.videoElement) {\n this.props.videoElement.loop = loop;\n }\n };\n this.getDuration = () => {\n if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n return this.props.videoElement.duration;\n }\n return null;\n };\n this.getCurrentTime = () => {\n if (this.props.videoElement && isFinite(this.props.videoElement.currentTime)) {\n return this.props.videoElement.currentTime;\n }\n return null;\n };\n this.getSecondsLoaded = () => {\n if (this.props.videoElement && this.props.videoElement.buffered.length > 0) {\n return this.props.videoElement.buffered.end(\n this.props.videoElement.buffered.length - 1\n );\n }\n return null;\n };\n this.getInternalPlayer = (key = \"player\") => {\n if (key === \"video\") return this.props.videoElement;\n return null;\n };\n this.enablePIP = async () => {\n if (this.props.videoElement && \"requestPictureInPicture\" in this.props.videoElement) {\n try {\n await this.props.videoElement.requestPictureInPicture();\n } catch (error) {\n console.warn(\"Picture-in-Picture failed:\", error);\n }\n }\n };\n this.disablePIP = async () => {\n if (document.pictureInPictureElement) {\n try {\n await document.exitPictureInPicture();\n } catch (error) {\n console.warn(\"Exit Picture-in-Picture failed:\", error);\n }\n }\n };\n }\n componentDidMount() {\n this.mounted = true;\n this.load();\n }\n componentWillUnmount() {\n this.mounted = false;\n }\n componentDidUpdate(prevProps) {\n if (prevProps.src !== this.props.src) {\n this.load();\n }\n }\n render() {\n return null;\n }\n};\nFilePlayer.displayName = \"FilePlayer\";\nFilePlayer.canPlay = canPlay.file;\n"]}
|