stormcloud-video-player 0.3.16 → 0.4.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 (38) hide show
  1. package/README.md +158 -112
  2. package/dist/stormcloud-vp.min.js +1 -10
  3. package/lib/index.cjs +3805 -6041
  4. package/lib/index.cjs.map +1 -1
  5. package/lib/index.d.cts +19 -102
  6. package/lib/index.d.ts +19 -102
  7. package/lib/index.js +3814 -6042
  8. package/lib/index.js.map +1 -1
  9. package/lib/player/StormcloudVideoPlayer.cjs +1497 -4885
  10. package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
  11. package/lib/player/StormcloudVideoPlayer.d.cts +9 -78
  12. package/lib/players/FilePlayer.cjs.map +1 -1
  13. package/lib/players/HlsPlayer.cjs +1497 -4885
  14. package/lib/players/HlsPlayer.cjs.map +1 -1
  15. package/lib/players/HlsPlayer.d.cts +1 -1
  16. package/lib/players/index.cjs +1499 -4887
  17. package/lib/players/index.cjs.map +1 -1
  18. package/lib/sdk/adstormPlayer.cjs +908 -0
  19. package/lib/sdk/adstormPlayer.cjs.map +1 -0
  20. package/lib/sdk/adstormPlayer.d.cts +9 -0
  21. package/lib/sdk/hlsAdPlayer.cjs +84 -74
  22. package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
  23. package/lib/sdk/hlsAdPlayer.d.cts +2 -2
  24. package/lib/{types-CryTJVCC.d.cts → types-Ca4ZDaWw.d.cts} +3 -8
  25. package/lib/ui/StormcloudVideoPlayer.cjs +1499 -4895
  26. package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
  27. package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
  28. package/lib/utils/browserCompat.cjs +1 -52
  29. package/lib/utils/browserCompat.cjs.map +1 -1
  30. package/lib/utils/browserCompat.d.cts +1 -6
  31. package/lib/utils/polyfills.cjs.map +1 -1
  32. package/lib/utils/tracking.cjs.map +1 -1
  33. package/lib/utils/tracking.d.cts +1 -1
  34. package/package.json +5 -1
  35. package/rollup.config.js +22 -0
  36. package/lib/sdk/ima.cjs +0 -1100
  37. package/lib/sdk/ima.cjs.map +0 -1
  38. package/lib/sdk/ima.d.cts +0 -12
@@ -1,56 +1,24 @@
1
- import { S as StormcloudVideoPlayerConfig } from '../types-CryTJVCC.cjs';
1
+ import { S as StormcloudVideoPlayerConfig } from '../types-Ca4ZDaWw.cjs';
2
2
 
3
3
  declare class StormcloudVideoPlayer {
4
4
  private readonly video;
5
5
  private readonly config;
6
6
  private hls?;
7
- private ima;
7
+ private adPlayer;
8
8
  private attached;
9
9
  private inAdBreak;
10
- private currentAdBreakStartWallClockMs;
11
10
  private expectedAdBreakDurationMs;
12
11
  private adStopTimerId;
13
- private adStartTimerId;
14
- private adFailsafeTimerId;
15
12
  private ptsDriftEmaMs;
16
- private adPodQueue;
17
- private apiVastTagUrl;
18
- private apiNumberAds;
19
- private lastHeartbeatTime;
20
- private heartbeatInterval;
21
- private currentAdIndex;
22
- private totalAdsInBreak;
23
- private showAds;
24
13
  private isLiveStream;
25
14
  private nativeHlsMode;
26
15
  private videoSrcProtection;
27
16
  private bufferedSegmentsCount;
28
17
  private shouldAutoplayAfterBuffering;
29
18
  private hasInitialBufferCompleted;
30
- private adPodAllUrls;
31
- private preloadingAdUrls;
32
- private vastToMediaUrlMap;
33
- private preloadedMediaUrls;
34
- private preloadingMediaUrls;
35
- private adRequestTokenCounter;
36
- private activeAdRequestToken;
37
- private adRequestWatchdogId;
38
- private adRequestWatchdogToken;
39
- private adFailsafeToken;
40
- private fetchedAdDurations;
41
- private targetAdBreakDurationMs;
42
- private isAdaptiveMode;
43
- private failedVastUrls;
44
- private continuousFetchingActive;
45
- private adRequestQueue;
46
- private successfulAdRequests;
47
- private maxPlaceholderDurationMs;
48
- private placeholderStartTimeMs;
49
- private isShowingPlaceholder;
50
19
  private timeUpdateHandler?;
51
20
  private emptiedHandler?;
52
21
  constructor(config: StormcloudVideoPlayerConfig);
53
- private createAdPlayer;
54
22
  load(): Promise<void>;
55
23
  private attach;
56
24
  private shouldUseNativeHls;
@@ -58,58 +26,19 @@ declare class StormcloudVideoPlayer {
58
26
  private parseScte35FromId3;
59
27
  private decodeId3ValueToText;
60
28
  private onScte35Marker;
29
+ private handleAdStart;
61
30
  private parseCueOutDuration;
62
31
  private parseCueOutCont;
63
32
  private parseAttributeList;
64
33
  private toNumber;
65
- private isManifestBasedMarker;
66
- private parseScte35Binary;
67
- private initializeTracking;
68
- private sendHeartbeatIfNeeded;
69
- private fetchAdConfiguration;
70
- getCurrentAdIndex(): number;
71
- getTotalAdsInBreak(): number;
72
- private generateVastUrlsWithCorrelators;
73
- isAdPlaying(): boolean;
74
- isShowingAds(): boolean;
75
- getStreamType(): "hls" | "other";
76
- shouldShowNativeControls(): boolean;
77
- private shouldContinueLiveStreamDuringAds;
78
- private handleAdStart;
79
- private startContinuousFetching;
80
- private continuousFetchLoop;
81
- private stopContinuousFetching;
82
- private tryNextAvailableAd;
83
- private showPlaceholderAndWaitForAds;
84
- private findCurrentOrNextBreak;
85
- private onTimeUpdate;
86
- private handleMidAdJoin;
87
34
  private scheduleAdStopCountdown;
88
35
  private clearAdStopTimer;
89
- private ensureAdStoppedByTimer;
90
- private scheduleAdStartIn;
91
- private clearAdStartTimer;
92
36
  private updatePtsDrift;
93
- private playSingleAd;
94
37
  private handleAdPodComplete;
95
- private handleAdFailure;
96
- private startAdRequestWatchdog;
97
- private clearAdRequestWatchdog;
98
- private startAdFailsafeTimer;
99
- private clearAdFailsafeTimer;
100
- private selectVastTagsForBreak;
101
- private logAdState;
102
- private fetchAndParseVastXml;
103
- private extractMediaUrlsFromVast;
104
- private fetchVastDuration;
105
- private calculateAdditionalAdsNeeded;
106
- private addAdaptiveAdsToQueue;
107
- private preloadMediaFile;
108
- private preloadAllAdsInBackground;
109
- private preloadSingleAd;
110
- private findNextPreloadedAd;
111
- private getRemainingAdMs;
112
- private findBreakForTime;
38
+ isAdPlaying(): boolean;
39
+ isShowingAds(): boolean;
40
+ getStreamType(): "hls" | "other";
41
+ shouldShowNativeControls(): boolean;
113
42
  toggleMute(): void;
114
43
  toggleFullscreen(): Promise<void>;
115
44
  isMuted(): boolean;
@@ -120,6 +49,8 @@ declare class StormcloudVideoPlayer {
120
49
  get videoElement(): HTMLVideoElement;
121
50
  resize(): void;
122
51
  destroy(): void;
52
+ getCurrentAdIndex(): number;
53
+ getTotalAdsInBreak(): number;
123
54
  }
124
55
 
125
56
  export { StormcloudVideoPlayer };
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/ubuntu24/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"]}
1
+ {"version":3,"sources":["/home/ubuntu24/Dev/stormcloud-vp/lib/players/FilePlayer.cjs"],"names":["__getOwnPropNames","Object","getOwnPropertyNames","__export","target","all","name","__defProp","get","enumerable","__copyProps","to","from","except","desc","key","__hasOwnProp","call","__getOwnPropDesc"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAGIA,oBAAoBC,OAAOC,mBAAmB;;;;;;YAElD,KAAA;mBAAA,SAAA,EAAIC,WAAW,SAACC,QAAQC;gBACtB,IAAK,CAAA,GAAIC,IAAAA,GAAAA,CAAQD,IACfE,UAAUH,QAAQE,MAAM;oBAAEE,CAAAA,IAAKH,GAAG,CAACC,KAAK;kBAAEG,YAAY;;;;8BAAK;gBAC/D,IAAA,CAAA,OAAA,GAAA;YACA,EAAIC,cAAc,SAACC,IAAIC,MAAMC,QAAQC;;;cACnC,IAAIF,QAAQ,CAAA;+CAAA,GAAOA,MAAAA,+BAAP,SAAOA,KAAG,MAAM,YAAY,OAAOA,SAAS,YAAY;wBAC7D,MAAA,GAAA,KAAA,IAAA,CAAA,KAAA,CAAA,GAAA,EAAA,IAAA,2BAAA;;;0BAAA,IAAIG,MAAJ;;;0BACH,IAAI,CAACC,aAAaC,IAAI,CAACN,IAAII,QAAQA,QAAQF,QACzCN,UAAUI,IAAII,KAAK;;gCAAEP,KAAK;yCAAMI,IAAI,CAACG,IAAI;;;;;oBAAEN,EAAAA,GAAAA,OAAY,CAAEK,CAAAA,OAAOI,iBAAiBN,MAAMG,IAAG,KAAMD,KAAKL,UAAU;gBAAC,EAAA,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"]}