stormcloud-video-player 0.2.14 → 0.2.16

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.
@@ -21,6 +21,8 @@ declare class StormcloudVideoPlayer {
21
21
  private totalAdsInBreak;
22
22
  private showAds;
23
23
  private isLiveStream;
24
+ private nativeHlsMode;
25
+ private videoSrcProtection;
24
26
  constructor(config: StormcloudVideoPlayerConfig);
25
27
  private createAdPlayer;
26
28
  load(): Promise<void>;
@@ -128,8 +128,19 @@ var FilePlayer = class extends import_react.Component {
128
128
  };
129
129
  };
130
130
  this.play = () => {
131
+ var _a;
131
132
  if (this.props.videoElement) {
132
- this.props.videoElement.play();
133
+ const video = this.props.videoElement;
134
+ const hasValidSource = video.src || video.currentSrc && video.currentSrc !== "" || video.readyState >= 1;
135
+ if (hasValidSource) {
136
+ (_a = video.play()) == null ? void 0 : _a.catch((error) => {
137
+ var _a2, _b;
138
+ console.error("[FilePlayer] Failed to play:", error);
139
+ (_b = (_a2 = this.props).onError) == null ? void 0 : _b.call(_a2, error);
140
+ });
141
+ } else {
142
+ console.warn("[FilePlayer] Cannot play: video has no valid source");
143
+ }
133
144
  }
134
145
  };
135
146
  this.pause = () => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/players/FilePlayer.tsx","../../src/patterns.ts"],"sourcesContent":["import { Component } from \"react\";\nimport { canPlay } from \"../patterns\";\n\nexport interface FilePlayerProps {\n src: string;\n videoElement?: HTMLVideoElement;\n onMount?: (player: any) => void;\n onReady?: () => void;\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onLoaded?: () => void;\n onError?: (error: any) => void;\n autoplay?: boolean;\n muted?: boolean;\n loop?: boolean;\n controls?: boolean;\n playsInline?: boolean;\n preload?: string;\n poster?: string;\n}\n\nexport default class FilePlayer extends Component<FilePlayerProps> {\n static displayName = \"FilePlayer\";\n\n static canPlay = canPlay.file;\n\n private mounted = false;\n private ready = false;\n\n componentDidMount() {\n this.mounted = true;\n this.load();\n }\n\n componentWillUnmount() {\n this.mounted = false;\n }\n\n componentDidUpdate(prevProps: FilePlayerProps) {\n if (prevProps.src !== this.props.src) {\n this.load();\n }\n }\n\n load = () => {\n if (!this.props.videoElement || !this.props.src) return;\n\n const video = this.props.videoElement;\n\n const handleLoadedMetadata = () => {\n if (this.mounted && !this.ready) {\n this.ready = true;\n this.props.onReady?.();\n }\n };\n\n const handlePlay = () => {\n if (this.mounted) {\n this.props.onPlay?.();\n }\n };\n\n const handlePause = () => {\n if (this.mounted) {\n this.props.onPause?.();\n }\n };\n\n const handleEnded = () => {\n if (this.mounted) {\n this.props.onEnded?.();\n }\n };\n\n const handleError = (error: any) => {\n if (this.mounted) {\n this.props.onError?.(error);\n }\n };\n\n const handleLoadedData = () => {\n if (this.mounted) {\n this.props.onLoaded?.();\n }\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\n video.src = this.props.src;\n if (this.props.autoplay !== undefined) video.autoplay = this.props.autoplay;\n if (this.props.muted !== undefined) video.muted = this.props.muted;\n if (this.props.loop !== undefined) video.loop = this.props.loop;\n if (this.props.controls !== undefined) video.controls = this.props.controls;\n if (this.props.playsInline !== undefined)\n video.playsInline = this.props.playsInline;\n if (this.props.preload !== undefined)\n video.preload = this.props.preload as \"\" | \"metadata\" | \"none\" | \"auto\";\n if (this.props.poster !== undefined) video.poster = this.props.poster;\n\n this.props.onMount?.(this);\n\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\n play = () => {\n if (this.props.videoElement) {\n this.props.videoElement.play();\n }\n };\n\n pause = () => {\n if (this.props.videoElement) {\n this.props.videoElement.pause();\n }\n };\n\n stop = () => {\n this.pause();\n if (this.props.videoElement) {\n this.props.videoElement.currentTime = 0;\n }\n };\n\n seekTo = (seconds: number, keepPlaying?: boolean) => {\n if (this.props.videoElement) {\n this.props.videoElement.currentTime = seconds;\n if (!keepPlaying) {\n this.pause();\n }\n }\n };\n\n setVolume = (volume: number) => {\n if (this.props.videoElement) {\n this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n }\n };\n\n mute = () => {\n if (this.props.videoElement) {\n this.props.videoElement.muted = true;\n }\n };\n\n unmute = () => {\n if (this.props.videoElement) {\n this.props.videoElement.muted = false;\n }\n };\n\n setPlaybackRate = (rate: number) => {\n if (this.props.videoElement && rate > 0) {\n this.props.videoElement.playbackRate = rate;\n }\n };\n\n setLoop = (loop: boolean) => {\n if (this.props.videoElement) {\n this.props.videoElement.loop = loop;\n }\n };\n\n getDuration = (): number | null => {\n if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n return this.props.videoElement.duration;\n }\n return null;\n };\n\n getCurrentTime = (): number | null => {\n if (\n this.props.videoElement &&\n isFinite(this.props.videoElement.currentTime)\n ) {\n return this.props.videoElement.currentTime;\n }\n return null;\n };\n\n getSecondsLoaded = (): number | null => {\n if (\n this.props.videoElement &&\n this.props.videoElement.buffered.length > 0\n ) {\n return this.props.videoElement.buffered.end(\n this.props.videoElement.buffered.length - 1\n );\n }\n return null;\n };\n\n getInternalPlayer = (key = \"player\") => {\n if (key === \"video\") return this.props.videoElement;\n return null;\n };\n\n enablePIP = async () => {\n if (\n this.props.videoElement &&\n \"requestPictureInPicture\" in this.props.videoElement\n ) {\n try {\n await (this.props.videoElement as any).requestPictureInPicture();\n } catch (error) {\n console.warn(\"Picture-in-Picture failed:\", error);\n }\n }\n };\n\n 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 render() {\n return null;\n }\n}\n","export const HLS_EXTENSIONS = /\\.(m3u8)($|\\?)/i;\nexport const HLS_PATHS = /\\/hls\\//i;\nexport const DASH_EXTENSIONS = /\\.(mpd)($|\\?)/i;\nexport const VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\\?)/i;\nexport const AUDIO_EXTENSIONS = /\\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\\?)/i;\n\nexport const canPlay = {\n hls: (url: string): boolean => {\n if (!url || typeof url !== \"string\") return false;\n return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);\n },\n\n dash: (url: string): boolean => {\n if (!url || typeof url !== \"string\") return false;\n return DASH_EXTENSIONS.test(url);\n },\n\n video: (url: string): boolean => {\n if (!url || typeof url !== \"string\") return false;\n return VIDEO_EXTENSIONS.test(url);\n },\n\n audio: (url: string): boolean => {\n if (!url || typeof url !== \"string\") return false;\n return AUDIO_EXTENSIONS.test(url);\n },\n\n file: (url: string): boolean => {\n if (!url || typeof url !== \"string\") return false;\n return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);\n },\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0B;;;ACAnB,IAAM,iBAAiB;AACvB,IAAM,YAAY;AAClB,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AAEzB,IAAM,UAAU;AAAA,EACrB,KAAK,CAAC,QAAyB;AAC7B,QAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,WAAO,eAAe,KAAK,GAAG,KAAK,UAAU,KAAK,GAAG;AAAA,EACvD;AAAA,EAEA,MAAM,CAAC,QAAyB;AAC9B,QAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,WAAO,gBAAgB,KAAK,GAAG;AAAA,EACjC;AAAA,EAEA,OAAO,CAAC,QAAyB;AAC/B,QAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,WAAO,iBAAiB,KAAK,GAAG;AAAA,EAClC;AAAA,EAEA,OAAO,CAAC,QAAyB;AAC/B,QAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,WAAO,iBAAiB,KAAK,GAAG;AAAA,EAClC;AAAA,EAEA,MAAM,CAAC,QAAyB;AAC9B,QAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,WAAO,iBAAiB,KAAK,GAAG,KAAK,iBAAiB,KAAK,GAAG;AAAA,EAChE;AACF;;;ADTA,IAAqB,aAArB,cAAwC,uBAA2B;AAAA,EAAnE;AAAA;AAKE,SAAQ,UAAU;AAClB,SAAQ,QAAQ;AAiBhB,gBAAO,MAAM;AA7Cf;AA8CI,UAAI,CAAC,KAAK,MAAM,gBAAgB,CAAC,KAAK,MAAM,IAAK;AAEjD,YAAM,QAAQ,KAAK,MAAM;AAEzB,YAAM,uBAAuB,MAAM;AAlDvC,YAAAA,KAAAC;AAmDM,YAAI,KAAK,WAAW,CAAC,KAAK,OAAO;AAC/B,eAAK,QAAQ;AACb,WAAAA,OAAAD,MAAA,KAAK,OAAM,YAAX,gBAAAC,IAAA,KAAAD;AAAA,QACF;AAAA,MACF;AAEA,YAAM,aAAa,MAAM;AAzD7B,YAAAA,KAAAC;AA0DM,YAAI,KAAK,SAAS;AAChB,WAAAA,OAAAD,MAAA,KAAK,OAAM,WAAX,gBAAAC,IAAA,KAAAD;AAAA,QACF;AAAA,MACF;AAEA,YAAM,cAAc,MAAM;AA/D9B,YAAAA,KAAAC;AAgEM,YAAI,KAAK,SAAS;AAChB,WAAAA,OAAAD,MAAA,KAAK,OAAM,YAAX,gBAAAC,IAAA,KAAAD;AAAA,QACF;AAAA,MACF;AAEA,YAAM,cAAc,MAAM;AArE9B,YAAAA,KAAAC;AAsEM,YAAI,KAAK,SAAS;AAChB,WAAAA,OAAAD,MAAA,KAAK,OAAM,YAAX,gBAAAC,IAAA,KAAAD;AAAA,QACF;AAAA,MACF;AAEA,YAAM,cAAc,CAAC,UAAe;AA3ExC,YAAAA,KAAAC;AA4EM,YAAI,KAAK,SAAS;AAChB,WAAAA,OAAAD,MAAA,KAAK,OAAM,YAAX,gBAAAC,IAAA,KAAAD,KAAqB;AAAA,QACvB;AAAA,MACF;AAEA,YAAM,mBAAmB,MAAM;AAjFnC,YAAAA,KAAAC;AAkFM,YAAI,KAAK,SAAS;AAChB,WAAAA,OAAAD,MAAA,KAAK,OAAM,aAAX,gBAAAC,IAAA,KAAAD;AAAA,QACF;AAAA,MACF;AAEA,YAAM,iBAAiB,kBAAkB,oBAAoB;AAC7D,YAAM,iBAAiB,QAAQ,UAAU;AACzC,YAAM,iBAAiB,SAAS,WAAW;AAC3C,YAAM,iBAAiB,SAAS,WAAW;AAC3C,YAAM,iBAAiB,SAAS,WAAW;AAC3C,YAAM,iBAAiB,cAAc,gBAAgB;AAErD,YAAM,MAAM,KAAK,MAAM;AACvB,UAAI,KAAK,MAAM,aAAa,OAAW,OAAM,WAAW,KAAK,MAAM;AACnE,UAAI,KAAK,MAAM,UAAU,OAAW,OAAM,QAAQ,KAAK,MAAM;AAC7D,UAAI,KAAK,MAAM,SAAS,OAAW,OAAM,OAAO,KAAK,MAAM;AAC3D,UAAI,KAAK,MAAM,aAAa,OAAW,OAAM,WAAW,KAAK,MAAM;AACnE,UAAI,KAAK,MAAM,gBAAgB;AAC7B,cAAM,cAAc,KAAK,MAAM;AACjC,UAAI,KAAK,MAAM,YAAY;AACzB,cAAM,UAAU,KAAK,MAAM;AAC7B,UAAI,KAAK,MAAM,WAAW,OAAW,OAAM,SAAS,KAAK,MAAM;AAE/D,uBAAK,OAAM,YAAX,4BAAqB;AAErB,aAAO,MAAM;AACX,cAAM,oBAAoB,kBAAkB,oBAAoB;AAChE,cAAM,oBAAoB,QAAQ,UAAU;AAC5C,cAAM,oBAAoB,SAAS,WAAW;AAC9C,cAAM,oBAAoB,SAAS,WAAW;AAC9C,cAAM,oBAAoB,SAAS,WAAW;AAC9C,cAAM,oBAAoB,cAAc,gBAAgB;AAAA,MAC1D;AAAA,IACF;AAEA,gBAAO,MAAM;AACX,UAAI,KAAK,MAAM,cAAc;AAC3B,aAAK,MAAM,aAAa,KAAK;AAAA,MAC/B;AAAA,IACF;AAEA,iBAAQ,MAAM;AACZ,UAAI,KAAK,MAAM,cAAc;AAC3B,aAAK,MAAM,aAAa,MAAM;AAAA,MAChC;AAAA,IACF;AAEA,gBAAO,MAAM;AACX,WAAK,MAAM;AACX,UAAI,KAAK,MAAM,cAAc;AAC3B,aAAK,MAAM,aAAa,cAAc;AAAA,MACxC;AAAA,IACF;AAEA,kBAAS,CAAC,SAAiB,gBAA0B;AACnD,UAAI,KAAK,MAAM,cAAc;AAC3B,aAAK,MAAM,aAAa,cAAc;AACtC,YAAI,CAAC,aAAa;AAChB,eAAK,MAAM;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAEA,qBAAY,CAAC,WAAmB;AAC9B,UAAI,KAAK,MAAM,cAAc;AAC3B,aAAK,MAAM,aAAa,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC;AAAA,MAClE;AAAA,IACF;AAEA,gBAAO,MAAM;AACX,UAAI,KAAK,MAAM,cAAc;AAC3B,aAAK,MAAM,aAAa,QAAQ;AAAA,MAClC;AAAA,IACF;AAEA,kBAAS,MAAM;AACb,UAAI,KAAK,MAAM,cAAc;AAC3B,aAAK,MAAM,aAAa,QAAQ;AAAA,MAClC;AAAA,IACF;AAEA,2BAAkB,CAAC,SAAiB;AAClC,UAAI,KAAK,MAAM,gBAAgB,OAAO,GAAG;AACvC,aAAK,MAAM,aAAa,eAAe;AAAA,MACzC;AAAA,IACF;AAEA,mBAAU,CAAC,SAAkB;AAC3B,UAAI,KAAK,MAAM,cAAc;AAC3B,aAAK,MAAM,aAAa,OAAO;AAAA,MACjC;AAAA,IACF;AAEA,uBAAc,MAAqB;AACjC,UAAI,KAAK,MAAM,gBAAgB,SAAS,KAAK,MAAM,aAAa,QAAQ,GAAG;AACzE,eAAO,KAAK,MAAM,aAAa;AAAA,MACjC;AACA,aAAO;AAAA,IACT;AAEA,0BAAiB,MAAqB;AACpC,UACE,KAAK,MAAM,gBACX,SAAS,KAAK,MAAM,aAAa,WAAW,GAC5C;AACA,eAAO,KAAK,MAAM,aAAa;AAAA,MACjC;AACA,aAAO;AAAA,IACT;AAEA,4BAAmB,MAAqB;AACtC,UACE,KAAK,MAAM,gBACX,KAAK,MAAM,aAAa,SAAS,SAAS,GAC1C;AACA,eAAO,KAAK,MAAM,aAAa,SAAS;AAAA,UACtC,KAAK,MAAM,aAAa,SAAS,SAAS;AAAA,QAC5C;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,6BAAoB,CAAC,MAAM,aAAa;AACtC,UAAI,QAAQ,QAAS,QAAO,KAAK,MAAM;AACvC,aAAO;AAAA,IACT;AAEA,qBAAY,YAAY;AACtB,UACE,KAAK,MAAM,gBACX,6BAA6B,KAAK,MAAM,cACxC;AACA,YAAI;AACF,gBAAO,KAAK,MAAM,aAAqB,wBAAwB;AAAA,QACjE,SAAS,OAAO;AACd,kBAAQ,KAAK,8BAA8B,KAAK;AAAA,QAClD;AAAA,MACF;AAAA,IACF;AAEA,sBAAa,YAAY;AACvB,UAAI,SAAS,yBAAyB;AACpC,YAAI;AACF,gBAAM,SAAS,qBAAqB;AAAA,QACtC,SAAS,OAAO;AACd,kBAAQ,KAAK,mCAAmC,KAAK;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAAA;AAAA,EAxMA,oBAAoB;AAClB,SAAK,UAAU;AACf,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,uBAAuB;AACrB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,mBAAmB,WAA4B;AAC7C,QAAI,UAAU,QAAQ,KAAK,MAAM,KAAK;AACpC,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA,EA6LA,SAAS;AACP,WAAO;AAAA,EACT;AACF;AArNqB,WACZ,cAAc;AADF,WAGZ,UAAU,QAAQ;","names":["_a","_b"]}
1
+ {"version":3,"sources":["../../src/players/FilePlayer.tsx","../../src/patterns.ts"],"sourcesContent":["import { Component } from \"react\";\nimport { canPlay } from \"../patterns\";\n\nexport interface FilePlayerProps {\n src: string;\n videoElement?: HTMLVideoElement;\n onMount?: (player: any) => void;\n onReady?: () => void;\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onLoaded?: () => void;\n onError?: (error: any) => void;\n autoplay?: boolean;\n muted?: boolean;\n loop?: boolean;\n controls?: boolean;\n playsInline?: boolean;\n preload?: string;\n poster?: string;\n}\n\nexport default class FilePlayer extends Component<FilePlayerProps> {\n static displayName = \"FilePlayer\";\n\n static canPlay = canPlay.file;\n\n private mounted = false;\n private ready = false;\n\n componentDidMount() {\n this.mounted = true;\n this.load();\n }\n\n componentWillUnmount() {\n this.mounted = false;\n }\n\n componentDidUpdate(prevProps: FilePlayerProps) {\n if (prevProps.src !== this.props.src) {\n this.load();\n }\n }\n\n load = () => {\n if (!this.props.videoElement || !this.props.src) return;\n\n const video = this.props.videoElement;\n\n const handleLoadedMetadata = () => {\n if (this.mounted && !this.ready) {\n this.ready = true;\n this.props.onReady?.();\n }\n };\n\n const handlePlay = () => {\n if (this.mounted) {\n this.props.onPlay?.();\n }\n };\n\n const handlePause = () => {\n if (this.mounted) {\n this.props.onPause?.();\n }\n };\n\n const handleEnded = () => {\n if (this.mounted) {\n this.props.onEnded?.();\n }\n };\n\n const handleError = (error: any) => {\n if (this.mounted) {\n this.props.onError?.(error);\n }\n };\n\n const handleLoadedData = () => {\n if (this.mounted) {\n this.props.onLoaded?.();\n }\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\n video.src = this.props.src;\n if (this.props.autoplay !== undefined) video.autoplay = this.props.autoplay;\n if (this.props.muted !== undefined) video.muted = this.props.muted;\n if (this.props.loop !== undefined) video.loop = this.props.loop;\n if (this.props.controls !== undefined) video.controls = this.props.controls;\n if (this.props.playsInline !== undefined)\n video.playsInline = this.props.playsInline;\n if (this.props.preload !== undefined)\n video.preload = this.props.preload as \"\" | \"metadata\" | \"none\" | \"auto\";\n if (this.props.poster !== undefined) video.poster = this.props.poster;\n\n this.props.onMount?.(this);\n\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\n play = () => {\n if (this.props.videoElement) {\n const video = this.props.videoElement;\n const hasValidSource =\n video.src ||\n (video.currentSrc && video.currentSrc !== \"\") ||\n video.readyState >= 1;\n\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\n pause = () => {\n if (this.props.videoElement) {\n this.props.videoElement.pause();\n }\n };\n\n stop = () => {\n this.pause();\n if (this.props.videoElement) {\n this.props.videoElement.currentTime = 0;\n }\n };\n\n seekTo = (seconds: number, keepPlaying?: boolean) => {\n if (this.props.videoElement) {\n this.props.videoElement.currentTime = seconds;\n if (!keepPlaying) {\n this.pause();\n }\n }\n };\n\n setVolume = (volume: number) => {\n if (this.props.videoElement) {\n this.props.videoElement.volume = Math.max(0, Math.min(1, volume));\n }\n };\n\n mute = () => {\n if (this.props.videoElement) {\n this.props.videoElement.muted = true;\n }\n };\n\n unmute = () => {\n if (this.props.videoElement) {\n this.props.videoElement.muted = false;\n }\n };\n\n setPlaybackRate = (rate: number) => {\n if (this.props.videoElement && rate > 0) {\n this.props.videoElement.playbackRate = rate;\n }\n };\n\n setLoop = (loop: boolean) => {\n if (this.props.videoElement) {\n this.props.videoElement.loop = loop;\n }\n };\n\n getDuration = (): number | null => {\n if (this.props.videoElement && isFinite(this.props.videoElement.duration)) {\n return this.props.videoElement.duration;\n }\n return null;\n };\n\n getCurrentTime = (): number | null => {\n if (\n this.props.videoElement &&\n isFinite(this.props.videoElement.currentTime)\n ) {\n return this.props.videoElement.currentTime;\n }\n return null;\n };\n\n getSecondsLoaded = (): number | null => {\n if (\n this.props.videoElement &&\n this.props.videoElement.buffered.length > 0\n ) {\n return this.props.videoElement.buffered.end(\n this.props.videoElement.buffered.length - 1\n );\n }\n return null;\n };\n\n getInternalPlayer = (key = \"player\") => {\n if (key === \"video\") return this.props.videoElement;\n return null;\n };\n\n enablePIP = async () => {\n if (\n this.props.videoElement &&\n \"requestPictureInPicture\" in this.props.videoElement\n ) {\n try {\n await (this.props.videoElement as any).requestPictureInPicture();\n } catch (error) {\n console.warn(\"Picture-in-Picture failed:\", error);\n }\n }\n };\n\n 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 render() {\n return null;\n }\n}\n","export const HLS_EXTENSIONS = /\\.(m3u8)($|\\?)/i;\nexport const HLS_PATHS = /\\/hls\\//i;\nexport const DASH_EXTENSIONS = /\\.(mpd)($|\\?)/i;\nexport const VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|avi|mov|wmv|flv|mkv)($|\\?)/i;\nexport const AUDIO_EXTENSIONS = /\\.(mp3|wav|ogg|aac|wma|flac|m4a)($|\\?)/i;\n\nexport const canPlay = {\n hls: (url: string): boolean => {\n if (!url || typeof url !== \"string\") return false;\n return HLS_EXTENSIONS.test(url) || HLS_PATHS.test(url);\n },\n\n dash: (url: string): boolean => {\n if (!url || typeof url !== \"string\") return false;\n return DASH_EXTENSIONS.test(url);\n },\n\n video: (url: string): boolean => {\n if (!url || typeof url !== \"string\") return false;\n return VIDEO_EXTENSIONS.test(url);\n },\n\n audio: (url: string): boolean => {\n if (!url || typeof url !== \"string\") return false;\n return AUDIO_EXTENSIONS.test(url);\n },\n\n file: (url: string): boolean => {\n if (!url || typeof url !== \"string\") return false;\n return VIDEO_EXTENSIONS.test(url) || AUDIO_EXTENSIONS.test(url);\n },\n};\n"],"mappings":"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","names":["_a","_b"]}
@@ -853,7 +853,7 @@ function createHlsAdPlayer(contentVideo, options) {
853
853
  const xmlDoc = parser.parseFromString(xmlString, "text/xml");
854
854
  const parserError = xmlDoc.querySelector("parsererror");
855
855
  if (parserError) {
856
- console.error("[HlsAdPlayer] XML parsing error:", parserError.textContent);
856
+ console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
857
857
  return null;
858
858
  }
859
859
  const adElement = xmlDoc.querySelector("Ad");
@@ -863,28 +863,45 @@ function createHlsAdPlayer(contentVideo, options) {
863
863
  }
864
864
  const adId = adElement.getAttribute("id") || "unknown";
865
865
  const title = ((_a = xmlDoc.querySelector("AdTitle")) == null ? void 0 : _a.textContent) || "Ad";
866
+ const isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
866
867
  const durationText = ((_b = xmlDoc.querySelector("Duration")) == null ? void 0 : _b.textContent) || "00:00:30";
867
868
  const durationParts = durationText.split(":");
868
869
  const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
869
870
  const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
870
871
  const mediaFiles = [];
871
- mediaFileElements.forEach((mf) => {
872
+ console.log(`[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`);
873
+ mediaFileElements.forEach((mf, index) => {
872
874
  var _a2;
873
875
  const type = mf.getAttribute("type") || "";
876
+ const url = ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "";
877
+ const width = mf.getAttribute("width") || "";
878
+ const height = mf.getAttribute("height") || "";
879
+ console.log(`[HlsAdPlayer] MediaFile ${index}: type="${type}", url="${url}", width="${width}", height="${height}"`);
874
880
  if (type === "application/x-mpegURL" || type.includes("m3u8")) {
881
+ if (!url) {
882
+ console.warn(`[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`);
883
+ return;
884
+ }
875
885
  const bitrateAttr = mf.getAttribute("bitrate");
876
886
  const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
877
887
  mediaFiles.push({
878
- url: ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "",
888
+ url,
879
889
  type,
880
- width: parseInt(mf.getAttribute("width") || "1920", 10),
881
- height: parseInt(mf.getAttribute("height") || "1080", 10),
890
+ width: parseInt(width || "1920", 10),
891
+ height: parseInt(height || "1080", 10),
882
892
  bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
883
893
  });
894
+ console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);
895
+ } else {
896
+ console.log(`[HlsAdPlayer] MediaFile ${index} ignored (type="${type}" is not HLS)`);
884
897
  }
885
898
  });
886
899
  if (mediaFiles.length === 0) {
887
- console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
900
+ if (isNoAdAvailable) {
901
+ console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
902
+ } else {
903
+ console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
904
+ }
888
905
  return null;
889
906
  }
890
907
  const trackingUrls = {
@@ -1072,9 +1089,11 @@ function createHlsAdPlayer(contentVideo, options) {
1072
1089
  }
1073
1090
  const vastXml = await response.text();
1074
1091
  console.log("[HlsAdPlayer] VAST XML received");
1092
+ console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
1075
1093
  const ad = parseVastXml(vastXml);
1076
1094
  if (!ad) {
1077
- throw new Error("Failed to parse VAST XML or no ads available");
1095
+ console.warn("[HlsAdPlayer] No ads available from VAST response");
1096
+ return Promise.resolve();
1078
1097
  }
1079
1098
  currentAd = ad;
1080
1099
  console.log(`[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`);
@@ -1089,7 +1108,7 @@ function createHlsAdPlayer(contentVideo, options) {
1089
1108
  },
1090
1109
  async play() {
1091
1110
  if (!currentAd) {
1092
- console.warn("[HlsAdPlayer] Cannot play: No ad loaded");
1111
+ console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
1093
1112
  return Promise.reject(new Error("No ad loaded"));
1094
1113
  }
1095
1114
  console.log("[HlsAdPlayer] Starting ad playback");
@@ -1720,6 +1739,8 @@ var StormcloudVideoPlayer = class {
1720
1739
  this.totalAdsInBreak = 0;
1721
1740
  this.showAds = false;
1722
1741
  this.isLiveStream = false;
1742
+ this.nativeHlsMode = false;
1743
+ this.videoSrcProtection = null;
1723
1744
  initializePolyfills();
1724
1745
  const browserOverrides = getBrowserConfigOverrides();
1725
1746
  this.config = { ...config, ...browserOverrides };
@@ -1740,7 +1761,9 @@ var StormcloudVideoPlayer = class {
1740
1761
  }
1741
1762
  if (adPlayerType === "hls") {
1742
1763
  if (this.config.debugAdTiming) {
1743
- console.log("[StormcloudVideoPlayer] Creating HLS ad player (AdStorm mode)");
1764
+ console.log(
1765
+ "[StormcloudVideoPlayer] Creating HLS ad player (AdStorm mode)"
1766
+ );
1744
1767
  }
1745
1768
  return createHlsAdPlayer(this.video, {
1746
1769
  continueLiveStreamDuringAds,
@@ -1749,7 +1772,9 @@ var StormcloudVideoPlayer = class {
1749
1772
  });
1750
1773
  } else {
1751
1774
  if (this.config.debugAdTiming) {
1752
- console.log("[StormcloudVideoPlayer] Creating Google IMA ad player (Default mode)");
1775
+ console.log(
1776
+ "[StormcloudVideoPlayer] Creating Google IMA ad player (Default mode)"
1777
+ );
1753
1778
  }
1754
1779
  return createImaController(this.video, {
1755
1780
  continueLiveStreamDuringAds
@@ -1773,11 +1798,13 @@ var StormcloudVideoPlayer = class {
1773
1798
  }
1774
1799
  this.initializeTracking();
1775
1800
  if (this.shouldUseNativeHls()) {
1801
+ this.nativeHlsMode = true;
1802
+ this.videoSrcProtection = this.config.src;
1776
1803
  this.video.src = this.config.src;
1777
1804
  this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
1778
1805
  if (this.config.debugAdTiming) {
1779
1806
  console.log(
1780
- "[StormcloudVideoPlayer] allowNativeHls: true - VOD mode detected:",
1807
+ "[StormcloudVideoPlayer] Using native HLS playback - VOD mode:",
1781
1808
  {
1782
1809
  isLive: this.isLiveStream,
1783
1810
  allowNativeHls: this.config.allowNativeHls,
@@ -1925,7 +1952,9 @@ var StormcloudVideoPlayer = class {
1925
1952
  this.ima.initialize();
1926
1953
  this.ima.on("all_ads_completed", () => {
1927
1954
  if (this.config.debugAdTiming) {
1928
- console.log("[StormcloudVideoPlayer] IMA all_ads_completed event received");
1955
+ console.log(
1956
+ "[StormcloudVideoPlayer] IMA all_ads_completed event received"
1957
+ );
1929
1958
  }
1930
1959
  });
1931
1960
  this.ima.on("ad_error", () => {
@@ -1990,13 +2019,31 @@ var StormcloudVideoPlayer = class {
1990
2019
  this.video.addEventListener("timeupdate", () => {
1991
2020
  this.onTimeUpdate(this.video.currentTime);
1992
2021
  });
2022
+ this.video.addEventListener("emptied", () => {
2023
+ if (this.nativeHlsMode && this.videoSrcProtection && !this.ima.isAdPlaying()) {
2024
+ if (this.config.debugAdTiming) {
2025
+ console.log(
2026
+ "[StormcloudVideoPlayer] Video src was cleared, restoring:",
2027
+ this.videoSrcProtection
2028
+ );
2029
+ }
2030
+ const currentTime = this.video.currentTime;
2031
+ const wasPaused = this.video.paused;
2032
+ this.video.src = this.videoSrcProtection;
2033
+ this.video.currentTime = currentTime;
2034
+ if (!wasPaused) {
2035
+ this.video.play().catch(() => {
2036
+ });
2037
+ }
2038
+ }
2039
+ });
1993
2040
  }
1994
2041
  shouldUseNativeHls() {
1995
2042
  const streamType = this.getStreamType();
1996
2043
  if (streamType === "other") {
1997
2044
  return true;
1998
2045
  }
1999
- const canNative = this.video.canPlayType("application/vnd.apple.mpegURL");
2046
+ const canNative = this.video.canPlayType("application/vnd.apple.mpegurl");
2000
2047
  return !!(this.config.allowNativeHls && canNative);
2001
2048
  }
2002
2049
  onId3Tag(tag) {
@@ -2423,10 +2470,7 @@ var StormcloudVideoPlayer = class {
2423
2470
  var _a, _b, _c;
2424
2471
  const vastMode = this.config.vastMode || "default";
2425
2472
  if (this.config.debugAdTiming) {
2426
- console.log(
2427
- "[StormcloudVideoPlayer] VAST mode:",
2428
- vastMode
2429
- );
2473
+ console.log("[StormcloudVideoPlayer] VAST mode:", vastMode);
2430
2474
  }
2431
2475
  if (vastMode === "adstorm") {
2432
2476
  if (!this.config.licenseKey) {
@@ -2441,7 +2485,7 @@ var StormcloudVideoPlayer = class {
2441
2485
  this.apiVastTagUrl = vastEndpoint;
2442
2486
  if (this.config.debugAdTiming) {
2443
2487
  console.log(
2444
- "[StormcloudVideoPlayer] Using AdStorm VAST endpoint:",
2488
+ "[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):",
2445
2489
  vastEndpoint
2446
2490
  );
2447
2491
  }
@@ -2544,10 +2588,7 @@ var StormcloudVideoPlayer = class {
2544
2588
  this.currentAdIndex = 0;
2545
2589
  this.totalAdsInBreak = 1;
2546
2590
  if (this.config.debugAdTiming) {
2547
- console.log(
2548
- "[StormcloudVideoPlayer] Using VAST endpoint:",
2549
- vastTagUrl
2550
- );
2591
+ console.log("[StormcloudVideoPlayer] Using VAST endpoint:", vastTagUrl);
2551
2592
  }
2552
2593
  } else if (tags && tags.length > 0) {
2553
2594
  vastTagUrl = tags[0];
@@ -2697,12 +2738,26 @@ var StormcloudVideoPlayer = class {
2697
2738
  this.startAdFailsafeTimer();
2698
2739
  try {
2699
2740
  await this.ima.requestAds(vastTagUrl);
2700
- if (this.config.debugAdTiming) {
2701
- console.log("[StormcloudVideoPlayer] Ad request successful, starting playback");
2702
- }
2703
- await this.ima.play();
2704
- if (this.config.debugAdTiming) {
2705
- console.log("[StormcloudVideoPlayer] Ad playback started successfully");
2741
+ try {
2742
+ if (this.config.debugAdTiming) {
2743
+ console.log(
2744
+ "[StormcloudVideoPlayer] Ad request completed, attempting playback"
2745
+ );
2746
+ }
2747
+ await this.ima.play();
2748
+ if (this.config.debugAdTiming) {
2749
+ console.log(
2750
+ "[StormcloudVideoPlayer] Ad playback started successfully"
2751
+ );
2752
+ }
2753
+ } catch (playError) {
2754
+ if (this.config.debugAdTiming) {
2755
+ console.log(
2756
+ "[StormcloudVideoPlayer] No ads available, skipping playback"
2757
+ );
2758
+ }
2759
+ this.handleAdFailure();
2760
+ return;
2706
2761
  }
2707
2762
  } catch (error) {
2708
2763
  if (this.config.debugAdTiming) {
@@ -2755,7 +2810,9 @@ var StormcloudVideoPlayer = class {
2755
2810
  });
2756
2811
  } else {
2757
2812
  if (this.config.debugAdTiming) {
2758
- console.log("[StormcloudVideoPlayer] Video is already playing, no resume needed");
2813
+ console.log(
2814
+ "[StormcloudVideoPlayer] Video is already playing, no resume needed"
2815
+ );
2759
2816
  }
2760
2817
  }
2761
2818
  }
@@ -2774,7 +2831,11 @@ var StormcloudVideoPlayer = class {
2774
2831
  if (this.config.debugAdTiming) {
2775
2832
  console.warn(
2776
2833
  "[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume",
2777
- { paused: this.video.paused, showAds: this.showAds, adPlaying: this.ima.isAdPlaying() }
2834
+ {
2835
+ paused: this.video.paused,
2836
+ showAds: this.showAds,
2837
+ adPlaying: this.ima.isAdPlaying()
2838
+ }
2778
2839
  );
2779
2840
  }
2780
2841
  this.handleAdFailure();
@@ -2996,10 +3057,20 @@ var HlsPlayer = class extends import_react.Component {
2996
3057
  }
2997
3058
  };
2998
3059
  this.play = () => {
2999
- var _a, _b;
3060
+ var _a, _b, _c;
3000
3061
  if (this.props.videoElement) {
3001
- this.props.videoElement.play();
3002
- (_b = (_a = this.props).onPlay) == null ? void 0 : _b.call(_a);
3062
+ const video = this.props.videoElement;
3063
+ const hasValidSource = video.src || video.currentSrc && video.currentSrc !== "" || video.readyState >= 1;
3064
+ if (hasValidSource) {
3065
+ (_a = video.play()) == null ? void 0 : _a.catch((error) => {
3066
+ var _a2, _b2;
3067
+ console.error("[HlsPlayer] Failed to play:", error);
3068
+ (_b2 = (_a2 = this.props).onError) == null ? void 0 : _b2.call(_a2, error);
3069
+ });
3070
+ (_c = (_b = this.props).onPlay) == null ? void 0 : _c.call(_b);
3071
+ } else {
3072
+ console.warn("[HlsPlayer] Cannot play: video has no valid source");
3073
+ }
3003
3074
  }
3004
3075
  };
3005
3076
  this.pause = () => {