stormcloud-video-player 0.7.50 → 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.
Files changed (50) hide show
  1. package/README.md +269 -228
  2. package/dist/stormcloud-vp.min.js +1 -1
  3. package/lib/index.cjs +5197 -6747
  4. package/lib/index.cjs.map +1 -1
  5. package/lib/index.d.cts +196 -195
  6. package/lib/index.d.ts +196 -195
  7. package/lib/index.js +5321 -6863
  8. package/lib/index.js.map +1 -1
  9. package/lib/player/StormcloudVideoPlayer.cjs +4802 -3170
  10. package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
  11. package/lib/player/StormcloudVideoPlayer.d.cts +113 -70
  12. package/lib/players/FilePlayer.cjs.map +1 -1
  13. package/lib/players/HlsPlayer.cjs +4810 -3179
  14. package/lib/players/HlsPlayer.cjs.map +1 -1
  15. package/lib/players/HlsPlayer.d.cts +1 -1
  16. package/lib/players/index.cjs +4877 -3246
  17. package/lib/players/index.cjs.map +1 -1
  18. package/lib/sdk/hlsAdPlayer.cjs +1021 -0
  19. package/lib/sdk/hlsAdPlayer.cjs.map +1 -0
  20. package/lib/sdk/hlsAdPlayer.d.cts +10 -0
  21. package/lib/sdk/pal.cjs +358 -0
  22. package/lib/sdk/pal.cjs.map +1 -0
  23. package/lib/sdk/pal.d.cts +28 -0
  24. package/lib/{types-CIHDHY7A.d.cts → types-DDwAfBLt.d.cts} +11 -10
  25. package/lib/ui/StormcloudVideoPlayer.cjs +5070 -6609
  26. package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
  27. package/lib/ui/StormcloudVideoPlayer.d.cts +1 -14
  28. package/lib/utils/browserCompat.cjs +10 -114
  29. package/lib/utils/browserCompat.cjs.map +1 -1
  30. package/lib/utils/browserCompat.d.cts +3 -7
  31. package/lib/utils/polyfills.cjs.map +1 -1
  32. package/lib/utils/tracking.cjs +179 -150
  33. package/lib/utils/tracking.cjs.map +1 -1
  34. package/lib/utils/tracking.d.cts +11 -6
  35. package/package.json +1 -2
  36. package/lib/sdk/adstormPlayer.cjs +0 -1567
  37. package/lib/sdk/adstormPlayer.cjs.map +0 -1
  38. package/lib/sdk/adstormPlayer.d.cts +0 -23
  39. package/lib/sdk/vastParser.cjs +0 -517
  40. package/lib/sdk/vastParser.cjs.map +0 -1
  41. package/lib/sdk/vastParser.d.cts +0 -45
  42. package/lib/ui/OverlayRenderer.cjs +0 -2376
  43. package/lib/ui/OverlayRenderer.cjs.map +0 -1
  44. package/lib/ui/OverlayRenderer.d.cts +0 -17
  45. package/lib/utils/adcision.cjs +0 -282
  46. package/lib/utils/adcision.cjs.map +0 -1
  47. package/lib/utils/adcision.d.cts +0 -31
  48. package/lib/utils/overlays.cjs +0 -354
  49. package/lib/utils/overlays.cjs.map +0 -1
  50. package/lib/utils/overlays.d.cts +0 -70
@@ -1,20 +1,23 @@
1
- import { S as StormcloudVideoPlayerConfig } from '../types-CIHDHY7A.cjs';
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 adLayer;
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 isInAdTransition;
41
+ private adRequestQueue;
35
42
  private maxPlaceholderDurationMs;
36
43
  private isShowingPlaceholder;
37
44
  private timeUpdateHandler?;
38
45
  private emptiedHandler?;
39
- private adInsertionPollingId;
40
- private lastAdInsertionPoint;
41
- private processedAdInsertionUpdatedAt;
42
- private adInsertionOffsetTimerId;
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 readonly adTransitionGapMs;
56
- private readonly MIN_AD_REMAINING_MS;
57
- private readonly adRequestTimeoutMs;
58
- private readonly adRequestMaxRetries;
59
- private readonly adRequestRetryBackoffMs;
60
- private preloadedTokens;
61
- private fillerVideo;
62
- private fillerBreakTimerId;
63
- private debugLogEntries;
64
- private adInsertionDebugHistory;
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 adRequest;
81
+ private createAdPlayer;
67
82
  load(): Promise<void>;
68
- private getAdSource;
69
- private attachAdLayerEventListeners;
70
- private ensureFillerVideo;
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
- getRemainingAdSeconds(): number;
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 cancelAndClearPreloadedTokens;
95
- private startAdInsertionPolling;
96
- private stopAdInsertionPolling;
97
- private fetchAdInsertionPoint;
98
- private checkAdInsertionInManifest;
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 pushDebugLog;
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":["__defProp","Object","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","name","all","target","enumerable","__copyProps","to","from","except","desc","key","call"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YACIA,OAAAA,GAAYC,OAAOC,cAAc;QACjCC,mBAAmBF,OAAOG,wBAAwB;QAClDC,MAAAA,SAAAA,GAAAA,GAAoBJ,OAAOK,mBAAmB;;;;;;iCAC9CC,CAAAA,OAAAA,IAAeN,CAAAA,CAAAA,KAAOO,OAAAA,EAAS,CAACC,CAAAA,aAAc,gBAAA,OAAA,KAAA,CAAA,YAAA,GAA9CF;;;;;;;;;;;;4BAEG;;gCAAIG,IAAQC,GAAAA,GACfX,EAAAA,CAAAA,OAAUY,KAAAA,CAAAA,EAAQF,MAAM,eAAA;;;4BADrB,EAAIA;;;;;;4BAC4BA,KAAK;4BAAEG,QAAAA,EAAY,EAAA,CAAA,8BAAA;;;;;;;;;;;YAEtDC,cAAc,qBAACC,IAAIC,MAAMC,QAAQC;;QACnC,IAAIF,EAAAA,OAAQ,CAAA,EAAA,GAAA,EAAOA,qCAAP,SAAOA,KAAG,MAAM,YAAY,OAAOA,SAAS,YAAY;;oBAC7D;;;;0CAAA,uBAAA,IAAA,2BAAA;;;;;;;;;;;;;;;;;;;;;;;4BAAA,GAAIG,MAAJ;kCACH,EAAA,EAAI,CAACZ,CAAAA,CAAAA,WAAaa,IAAI,CAACL,IAAII,QAAQA,OAAAA,CAAQF,QACzCjB,UAAUe,IAAII,KAAK;;;;;;;;;;;;;;;;;;0CAA6F;;wBAFpH,CAAA,OAAK,YAAWd,kBAAkBW,0BAA7B,SAAA,6BAAA,QAAA,yBAAA;;;;;sCAAA;wBAAA,IAAA,GAAA;;;;;;iCAAA,KAAA,IAAA,CAAA,KAAA,CAAA,GAAA,EAAA,QAAA;kCAAA;;;;;mCAAA;;sCAAA;;;;;;;IAGP,OAAA,OAAA,GAAA,QAAA,IAAA","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"]}
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"]}