stormcloud-video-player 0.2.15 → 0.2.17
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/dist/stormcloud-vp.min.js +2 -2
- package/lib/index.cjs +388 -245
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +2 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +388 -245
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +90 -20
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +2 -0
- package/lib/players/FilePlayer.cjs +12 -1
- package/lib/players/FilePlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +103 -23
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +115 -24
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/ima.cjs +38 -2
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +363 -241
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
|
@@ -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
|
|
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":"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","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":";;;;;;;;;;;;;;;;;;;;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;AArHf;AAsHI,UAAI,KAAK,MAAM,cAAc;AAC3B,cAAM,QAAQ,KAAK,MAAM;AACzB,cAAM,iBACJ,MAAM,OACL,MAAM,cAAc,MAAM,eAAe,MAC1C,MAAM,cAAc;AAEtB,YAAI,gBAAgB;AAClB,sBAAM,KAAK,MAAX,mBAAc,MAAM,CAAC,UAAU;AA9HvC,gBAAAA,KAAA;AA+HU,oBAAQ,MAAM,gCAAgC,KAAK;AACnD,mBAAAA,MAAA,KAAK,OAAM,YAAX,wBAAAA,KAAqB;AAAA,UACvB;AAAA,QACF,OAAO;AACL,kBAAQ,KAAK,qDAAqD;AAAA,QACpE;AAAA,MACF;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,EArNA,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,EA0MA,SAAS;AACP,WAAO;AAAA,EACT;AACF;AAlOqB,WACZ,cAAc;AADF,WAGZ,UAAU,QAAQ;","names":["_a","_b"]}
|
|
@@ -287,6 +287,14 @@ function createImaController(video, options) {
|
|
|
287
287
|
function makeAdsRequest(google, vastTagUrl) {
|
|
288
288
|
const adsRequest = new google.ima.AdsRequest();
|
|
289
289
|
adsRequest.adTagUrl = vastTagUrl;
|
|
290
|
+
const videoWidth = video.offsetWidth || video.clientWidth || 640;
|
|
291
|
+
const videoHeight = video.offsetHeight || video.clientHeight || 360;
|
|
292
|
+
adsRequest.linearAdSlotWidth = videoWidth;
|
|
293
|
+
adsRequest.linearAdSlotHeight = videoHeight;
|
|
294
|
+
adsRequest.nonLinearAdSlotWidth = videoWidth;
|
|
295
|
+
adsRequest.nonLinearAdSlotHeight = videoHeight;
|
|
296
|
+
adsRequest.vastLoadTimeout = 5e3;
|
|
297
|
+
console.log(`[IMA] Ads request dimensions: ${videoWidth}x${videoHeight}`);
|
|
290
298
|
adsLoader.requestAds(adsRequest);
|
|
291
299
|
}
|
|
292
300
|
function destroyAdsManager() {
|
|
@@ -333,6 +341,18 @@ function createImaController(video, options) {
|
|
|
333
341
|
},
|
|
334
342
|
async requestAds(vastTagUrl) {
|
|
335
343
|
console.log("[IMA] Requesting ads:", vastTagUrl);
|
|
344
|
+
if (!vastTagUrl || vastTagUrl.trim() === "") {
|
|
345
|
+
const error = new Error("VAST tag URL is empty or undefined");
|
|
346
|
+
console.warn("[IMA]", error.message);
|
|
347
|
+
return Promise.reject(error);
|
|
348
|
+
}
|
|
349
|
+
try {
|
|
350
|
+
new URL(vastTagUrl);
|
|
351
|
+
} catch (e) {
|
|
352
|
+
const error = new Error(`Invalid VAST tag URL format: ${vastTagUrl}`);
|
|
353
|
+
console.warn("[IMA]", error.message);
|
|
354
|
+
return Promise.reject(error);
|
|
355
|
+
}
|
|
336
356
|
if (adPlaying) {
|
|
337
357
|
console.warn(
|
|
338
358
|
"[IMA] Cannot request new ads while an ad is playing. Call stop() first."
|
|
@@ -394,6 +414,18 @@ function createImaController(video, options) {
|
|
|
394
414
|
);
|
|
395
415
|
}
|
|
396
416
|
}
|
|
417
|
+
const videoWidth = video.offsetWidth || video.clientWidth;
|
|
418
|
+
const videoHeight = video.offsetHeight || video.clientHeight;
|
|
419
|
+
if (!videoWidth || !videoHeight || videoWidth === 0 || videoHeight === 0) {
|
|
420
|
+
const error = new Error(
|
|
421
|
+
`Invalid video dimensions: ${videoWidth}x${videoHeight}. Cannot initialize ads.`
|
|
422
|
+
);
|
|
423
|
+
console.warn("[IMA]", error.message);
|
|
424
|
+
currentReject == null ? void 0 : currentReject(error);
|
|
425
|
+
adsLoadedReject = void 0;
|
|
426
|
+
adsLoadedResolve = void 0;
|
|
427
|
+
return Promise.reject(error);
|
|
428
|
+
}
|
|
397
429
|
if (!adsLoader) {
|
|
398
430
|
console.log("[IMA] Creating ads loader");
|
|
399
431
|
const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);
|
|
@@ -442,7 +474,9 @@ function createImaController(video, options) {
|
|
|
442
474
|
emit("ad_error");
|
|
443
475
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
444
476
|
if (video.paused) {
|
|
445
|
-
console.log(
|
|
477
|
+
console.log(
|
|
478
|
+
"[IMA] Resuming paused video after ad error"
|
|
479
|
+
);
|
|
446
480
|
(_a = video.play()) == null ? void 0 : _a.catch(() => {
|
|
447
481
|
});
|
|
448
482
|
}
|
|
@@ -544,7 +578,9 @@ function createImaController(video, options) {
|
|
|
544
578
|
}
|
|
545
579
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
546
580
|
if (video.paused) {
|
|
547
|
-
console.log(
|
|
581
|
+
console.log(
|
|
582
|
+
"[IMA] Resuming paused video after setup error"
|
|
583
|
+
);
|
|
548
584
|
video.play().catch(() => {
|
|
549
585
|
});
|
|
550
586
|
}
|
|
@@ -1739,6 +1775,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1739
1775
|
this.totalAdsInBreak = 0;
|
|
1740
1776
|
this.showAds = false;
|
|
1741
1777
|
this.isLiveStream = false;
|
|
1778
|
+
this.nativeHlsMode = false;
|
|
1779
|
+
this.videoSrcProtection = null;
|
|
1742
1780
|
initializePolyfills();
|
|
1743
1781
|
const browserOverrides = getBrowserConfigOverrides();
|
|
1744
1782
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -1759,7 +1797,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1759
1797
|
}
|
|
1760
1798
|
if (adPlayerType === "hls") {
|
|
1761
1799
|
if (this.config.debugAdTiming) {
|
|
1762
|
-
console.log(
|
|
1800
|
+
console.log(
|
|
1801
|
+
"[StormcloudVideoPlayer] Creating HLS ad player (AdStorm mode)"
|
|
1802
|
+
);
|
|
1763
1803
|
}
|
|
1764
1804
|
return createHlsAdPlayer(this.video, {
|
|
1765
1805
|
continueLiveStreamDuringAds,
|
|
@@ -1768,7 +1808,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1768
1808
|
});
|
|
1769
1809
|
} else {
|
|
1770
1810
|
if (this.config.debugAdTiming) {
|
|
1771
|
-
console.log(
|
|
1811
|
+
console.log(
|
|
1812
|
+
"[StormcloudVideoPlayer] Creating Google IMA ad player (Default mode)"
|
|
1813
|
+
);
|
|
1772
1814
|
}
|
|
1773
1815
|
return createImaController(this.video, {
|
|
1774
1816
|
continueLiveStreamDuringAds
|
|
@@ -1792,11 +1834,13 @@ var StormcloudVideoPlayer = class {
|
|
|
1792
1834
|
}
|
|
1793
1835
|
this.initializeTracking();
|
|
1794
1836
|
if (this.shouldUseNativeHls()) {
|
|
1837
|
+
this.nativeHlsMode = true;
|
|
1838
|
+
this.videoSrcProtection = this.config.src;
|
|
1795
1839
|
this.video.src = this.config.src;
|
|
1796
1840
|
this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
|
|
1797
1841
|
if (this.config.debugAdTiming) {
|
|
1798
1842
|
console.log(
|
|
1799
|
-
"[StormcloudVideoPlayer]
|
|
1843
|
+
"[StormcloudVideoPlayer] Using native HLS playback - VOD mode:",
|
|
1800
1844
|
{
|
|
1801
1845
|
isLive: this.isLiveStream,
|
|
1802
1846
|
allowNativeHls: this.config.allowNativeHls,
|
|
@@ -1944,7 +1988,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1944
1988
|
this.ima.initialize();
|
|
1945
1989
|
this.ima.on("all_ads_completed", () => {
|
|
1946
1990
|
if (this.config.debugAdTiming) {
|
|
1947
|
-
console.log(
|
|
1991
|
+
console.log(
|
|
1992
|
+
"[StormcloudVideoPlayer] IMA all_ads_completed event received"
|
|
1993
|
+
);
|
|
1948
1994
|
}
|
|
1949
1995
|
});
|
|
1950
1996
|
this.ima.on("ad_error", () => {
|
|
@@ -2009,13 +2055,31 @@ var StormcloudVideoPlayer = class {
|
|
|
2009
2055
|
this.video.addEventListener("timeupdate", () => {
|
|
2010
2056
|
this.onTimeUpdate(this.video.currentTime);
|
|
2011
2057
|
});
|
|
2058
|
+
this.video.addEventListener("emptied", () => {
|
|
2059
|
+
if (this.nativeHlsMode && this.videoSrcProtection && !this.ima.isAdPlaying()) {
|
|
2060
|
+
if (this.config.debugAdTiming) {
|
|
2061
|
+
console.log(
|
|
2062
|
+
"[StormcloudVideoPlayer] Video src was cleared, restoring:",
|
|
2063
|
+
this.videoSrcProtection
|
|
2064
|
+
);
|
|
2065
|
+
}
|
|
2066
|
+
const currentTime = this.video.currentTime;
|
|
2067
|
+
const wasPaused = this.video.paused;
|
|
2068
|
+
this.video.src = this.videoSrcProtection;
|
|
2069
|
+
this.video.currentTime = currentTime;
|
|
2070
|
+
if (!wasPaused) {
|
|
2071
|
+
this.video.play().catch(() => {
|
|
2072
|
+
});
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
});
|
|
2012
2076
|
}
|
|
2013
2077
|
shouldUseNativeHls() {
|
|
2014
2078
|
const streamType = this.getStreamType();
|
|
2015
2079
|
if (streamType === "other") {
|
|
2016
2080
|
return true;
|
|
2017
2081
|
}
|
|
2018
|
-
const canNative = this.video.canPlayType("application/vnd.apple.
|
|
2082
|
+
const canNative = this.video.canPlayType("application/vnd.apple.mpegurl");
|
|
2019
2083
|
return !!(this.config.allowNativeHls && canNative);
|
|
2020
2084
|
}
|
|
2021
2085
|
onId3Tag(tag) {
|
|
@@ -2442,10 +2506,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2442
2506
|
var _a, _b, _c;
|
|
2443
2507
|
const vastMode = this.config.vastMode || "default";
|
|
2444
2508
|
if (this.config.debugAdTiming) {
|
|
2445
|
-
console.log(
|
|
2446
|
-
"[StormcloudVideoPlayer] VAST mode:",
|
|
2447
|
-
vastMode
|
|
2448
|
-
);
|
|
2509
|
+
console.log("[StormcloudVideoPlayer] VAST mode:", vastMode);
|
|
2449
2510
|
}
|
|
2450
2511
|
if (vastMode === "adstorm") {
|
|
2451
2512
|
if (!this.config.licenseKey) {
|
|
@@ -2563,10 +2624,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2563
2624
|
this.currentAdIndex = 0;
|
|
2564
2625
|
this.totalAdsInBreak = 1;
|
|
2565
2626
|
if (this.config.debugAdTiming) {
|
|
2566
|
-
console.log(
|
|
2567
|
-
"[StormcloudVideoPlayer] Using VAST endpoint:",
|
|
2568
|
-
vastTagUrl
|
|
2569
|
-
);
|
|
2627
|
+
console.log("[StormcloudVideoPlayer] Using VAST endpoint:", vastTagUrl);
|
|
2570
2628
|
}
|
|
2571
2629
|
} else if (tags && tags.length > 0) {
|
|
2572
2630
|
vastTagUrl = tags[0];
|
|
@@ -2718,15 +2776,21 @@ var StormcloudVideoPlayer = class {
|
|
|
2718
2776
|
await this.ima.requestAds(vastTagUrl);
|
|
2719
2777
|
try {
|
|
2720
2778
|
if (this.config.debugAdTiming) {
|
|
2721
|
-
console.log(
|
|
2779
|
+
console.log(
|
|
2780
|
+
"[StormcloudVideoPlayer] Ad request completed, attempting playback"
|
|
2781
|
+
);
|
|
2722
2782
|
}
|
|
2723
2783
|
await this.ima.play();
|
|
2724
2784
|
if (this.config.debugAdTiming) {
|
|
2725
|
-
console.log(
|
|
2785
|
+
console.log(
|
|
2786
|
+
"[StormcloudVideoPlayer] Ad playback started successfully"
|
|
2787
|
+
);
|
|
2726
2788
|
}
|
|
2727
2789
|
} catch (playError) {
|
|
2728
2790
|
if (this.config.debugAdTiming) {
|
|
2729
|
-
console.log(
|
|
2791
|
+
console.log(
|
|
2792
|
+
"[StormcloudVideoPlayer] No ads available, skipping playback"
|
|
2793
|
+
);
|
|
2730
2794
|
}
|
|
2731
2795
|
this.handleAdFailure();
|
|
2732
2796
|
return;
|
|
@@ -2782,7 +2846,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2782
2846
|
});
|
|
2783
2847
|
} else {
|
|
2784
2848
|
if (this.config.debugAdTiming) {
|
|
2785
|
-
console.log(
|
|
2849
|
+
console.log(
|
|
2850
|
+
"[StormcloudVideoPlayer] Video is already playing, no resume needed"
|
|
2851
|
+
);
|
|
2786
2852
|
}
|
|
2787
2853
|
}
|
|
2788
2854
|
}
|
|
@@ -2801,7 +2867,11 @@ var StormcloudVideoPlayer = class {
|
|
|
2801
2867
|
if (this.config.debugAdTiming) {
|
|
2802
2868
|
console.warn(
|
|
2803
2869
|
"[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume",
|
|
2804
|
-
{
|
|
2870
|
+
{
|
|
2871
|
+
paused: this.video.paused,
|
|
2872
|
+
showAds: this.showAds,
|
|
2873
|
+
adPlaying: this.ima.isAdPlaying()
|
|
2874
|
+
}
|
|
2805
2875
|
);
|
|
2806
2876
|
}
|
|
2807
2877
|
this.handleAdFailure();
|
|
@@ -3023,10 +3093,20 @@ var HlsPlayer = class extends import_react.Component {
|
|
|
3023
3093
|
}
|
|
3024
3094
|
};
|
|
3025
3095
|
this.play = () => {
|
|
3026
|
-
var _a, _b;
|
|
3096
|
+
var _a, _b, _c;
|
|
3027
3097
|
if (this.props.videoElement) {
|
|
3028
|
-
this.props.videoElement
|
|
3029
|
-
|
|
3098
|
+
const video = this.props.videoElement;
|
|
3099
|
+
const hasValidSource = video.src || video.currentSrc && video.currentSrc !== "" || video.readyState >= 1;
|
|
3100
|
+
if (hasValidSource) {
|
|
3101
|
+
(_a = video.play()) == null ? void 0 : _a.catch((error) => {
|
|
3102
|
+
var _a2, _b2;
|
|
3103
|
+
console.error("[HlsPlayer] Failed to play:", error);
|
|
3104
|
+
(_b2 = (_a2 = this.props).onError) == null ? void 0 : _b2.call(_a2, error);
|
|
3105
|
+
});
|
|
3106
|
+
(_c = (_b = this.props).onPlay) == null ? void 0 : _c.call(_b);
|
|
3107
|
+
} else {
|
|
3108
|
+
console.warn("[HlsPlayer] Cannot play: video has no valid source");
|
|
3109
|
+
}
|
|
3030
3110
|
}
|
|
3031
3111
|
};
|
|
3032
3112
|
this.pause = () => {
|