stormcloud-video-player 0.5.7 → 0.5.8
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 +1 -1
- package/lib/index.cjs +109 -23
- 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 +109 -23
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +109 -23
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +2 -0
- package/lib/players/HlsPlayer.cjs +109 -23
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +109 -23
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/prebidController.cjs +4 -6
- package/lib/sdk/prebidController.cjs.map +1 -1
- package/lib/sdk/vastParser.cjs +3 -5
- package/lib/sdk/vastParser.cjs.map +1 -1
- package/lib/sdk/vastParser.d.cts +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +109 -23
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/sdk/vastParser.cjs","../../src/sdk/vastParser.ts"],"names":["key","__defProp","Object","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","enumerable","get","__copyProps","to","from","except","desc","call","__toCommonJS","mod","value","vastParser_exports","createEmptyTrackingState","fetchAndParseVastAd","fireTrackingPixels","parseVastXml","module","exports","isHlsType","type","includes","isMp4Type","xmlString","filter","logPrefix","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","console","error","textContent","adElement","warn"],"mappings":"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","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/sdk/vastParser.ts\nvar vastParser_exports = {};\n__export(vastParser_exports, {\n createEmptyTrackingState: () => createEmptyTrackingState,\n fetchAndParseVastAd: () => fetchAndParseVastAd,\n fireTrackingPixels: () => fireTrackingPixels,\n parseVastXml: () => parseVastXml\n});\nmodule.exports = __toCommonJS(vastParser_exports);\nfunction isHlsType(type) {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\nfunction isMp4Type(type) {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\nfunction parseVastXml(xmlString, filter = \"all\", logPrefix = \"[VastParser]\") {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n const durationText = xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + Math.round(parseFloat(durationParts[2] || \"0\"));\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n console.log(\n `${logPrefix} Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n console.log(\n `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n });\n console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: []\n };\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\nasync function fetchAndParseVastAd(vastTagUrl, filter = \"all\", logPrefix = \"[VastParser]\") {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\"\n },\n referrerPolicy: \"no-referrer-when-downgrade\"\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2e3)\n );\n return parseVastXml(vastXml, filter, logPrefix);\n}\nfunction createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n}\nfunction fireTrackingPixels(urls, sessionId, licenseKey, logPrefix = \"[VastParser]\") {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n if (sessionId) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}session_id=${sessionId}`;\n }\n if (licenseKey) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}license_key=${licenseKey}`;\n }\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createEmptyTrackingState,\n fetchAndParseVastAd,\n fireTrackingPixels,\n parseVastXml\n});\n","export interface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nexport interface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n mute: string[];\n unmute: string[];\n pause: string[];\n resume: string[];\n fullscreen: string[];\n exitFullscreen: string[];\n skip: string[];\n error: string[];\n}\n\nexport interface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\nexport type MediaFileFilter = \"hls-only\" | \"mp4-first\" | \"all\";\n\nfunction isHlsType(type: string): boolean {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\n\nfunction isMp4Type(type: string): boolean {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\n\nexport function parseVastXml(\n xmlString: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): VastAd | null {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const isNoAdAvailable =\n adId === \"empty\" ||\n title.toLowerCase().includes(\"no ad available\") ||\n title.toLowerCase() === \"no ad available\";\n\n const durationText =\n xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n Math.round(parseFloat(durationParts[2] || \"0\"));\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `${logPrefix} Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n\n console.log(\n `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : undefined;\n\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n });\n\n console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n\n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: [],\n };\n\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n\n const clickThrough = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\n\nexport async function fetchAndParseVastAd(\n vastTagUrl: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): Promise<VastAd | null> {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\",\n },\n referrerPolicy: \"no-referrer-when-downgrade\",\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2000)\n );\n\n return parseVastXml(vastXml, filter, logPrefix);\n}\n\nexport function createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n}\n\nexport function fireTrackingPixels(\n urls: string[],\n sessionId?: string,\n licenseKey?: string,\n logPrefix = \"[VastParser]\"\n): void {\n if (!urls || urls.length === 0) return;\n\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n\n if (sessionId) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }session_id=${sessionId}`;\n }\n\n if (licenseKey) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }license_key=${licenseKey}`;\n }\n\n const img = new Image(1, 1);\n img.src = trackingUrl;\n console.log(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/sdk/vastParser.cjs","../../src/sdk/vastParser.ts"],"names":["key","__defProp","Object","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","enumerable","get","__copyProps","to","from","except","desc","call","__toCommonJS","mod","value","vastParser_exports","createEmptyTrackingState","fetchAndParseVastAd","fireTrackingPixels","parseVastXml","module","exports","isHlsType","type","includes","isMp4Type","xmlString","filter","logPrefix","xmlDoc","parser","DOMParser","parseFromString","parserError","querySelector","console","error","textContent","adElement","warn"],"mappings":"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","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/sdk/vastParser.ts\nvar vastParser_exports = {};\n__export(vastParser_exports, {\n createEmptyTrackingState: () => createEmptyTrackingState,\n fetchAndParseVastAd: () => fetchAndParseVastAd,\n fireTrackingPixels: () => fireTrackingPixels,\n parseVastXml: () => parseVastXml\n});\nmodule.exports = __toCommonJS(vastParser_exports);\nfunction isHlsType(type) {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\nfunction isMp4Type(type) {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\nfunction parseVastXml(xmlString, filter = \"all\", logPrefix = \"[VastParser]\") {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n const isNoAdAvailable = adId === \"empty\" || title.toLowerCase().includes(\"no ad available\") || title.toLowerCase() === \"no ad available\";\n const durationText = xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration = parseInt(durationParts[0] || \"0\", 10) * 3600 + parseInt(durationParts[1] || \"0\", 10) * 60 + Math.round(parseFloat(durationParts[2] || \"0\"));\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles = [];\n console.log(\n `${logPrefix} Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n console.log(\n `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0\n });\n console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n const trackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: []\n };\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n const clickThrough = xmlDoc.querySelector(\"ClickThrough\")?.textContent?.trim();\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\nasync function fetchAndParseVastAd(vastTagUrl, filter = \"all\", logPrefix = \"[VastParser]\") {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\"\n },\n referrerPolicy: \"no-referrer-when-downgrade\"\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2e3)\n );\n return parseVastXml(vastXml, filter, logPrefix);\n}\nfunction createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false\n };\n}\nfunction fireTrackingPixels(urls, sessionId, logPrefix = \"[VastParser]\") {\n if (!urls || urls.length === 0) return;\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n if (sessionId) {\n trackingUrl = `${trackingUrl}${trackingUrl.includes(\"?\") ? \"&\" : \"?\"}session_id=${sessionId}`;\n }\n const img = new Image(1, 1);\n img.onerror = () => {\n };\n img.src = trackingUrl;\n console.log(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n createEmptyTrackingState,\n fetchAndParseVastAd,\n fireTrackingPixels,\n parseVastXml\n});\n","export interface VastMediaFile {\n url: string;\n type: string;\n width: number;\n height: number;\n bitrate?: number | undefined;\n}\n\nexport interface VastTrackingUrls {\n impression: string[];\n start: string[];\n firstQuartile: string[];\n midpoint: string[];\n thirdQuartile: string[];\n complete: string[];\n mute: string[];\n unmute: string[];\n pause: string[];\n resume: string[];\n fullscreen: string[];\n exitFullscreen: string[];\n skip: string[];\n error: string[];\n}\n\nexport interface VastAd {\n id: string;\n title: string;\n duration: number;\n mediaFiles: VastMediaFile[];\n trackingUrls: VastTrackingUrls;\n clickThrough?: string | undefined;\n}\n\nexport type MediaFileFilter = \"hls-only\" | \"mp4-first\" | \"all\";\n\nfunction isHlsType(type: string): boolean {\n return type === \"application/x-mpegURL\" || type.includes(\"m3u8\");\n}\n\nfunction isMp4Type(type: string): boolean {\n return type === \"video/mp4\" || type.includes(\"mp4\");\n}\n\nexport function parseVastXml(\n xmlString: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): VastAd | null {\n try {\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n const parserError = xmlDoc.querySelector(\"parsererror\");\n if (parserError) {\n console.error(\n `${logPrefix} XML parsing error (malformed VAST XML):`,\n parserError.textContent\n );\n return null;\n }\n\n const adElement = xmlDoc.querySelector(\"Ad\");\n if (!adElement) {\n console.warn(`${logPrefix} No Ad element found in VAST XML`);\n return null;\n }\n\n const adId = adElement.getAttribute(\"id\") || \"unknown\";\n const title = xmlDoc.querySelector(\"AdTitle\")?.textContent || \"Ad\";\n\n const isNoAdAvailable =\n adId === \"empty\" ||\n title.toLowerCase().includes(\"no ad available\") ||\n title.toLowerCase() === \"no ad available\";\n\n const durationText =\n xmlDoc.querySelector(\"Duration\")?.textContent || \"00:00:30\";\n const durationParts = durationText.split(\":\");\n const duration =\n parseInt(durationParts[0] || \"0\", 10) * 3600 +\n parseInt(durationParts[1] || \"0\", 10) * 60 +\n Math.round(parseFloat(durationParts[2] || \"0\"));\n\n const mediaFileElements = xmlDoc.querySelectorAll(\"MediaFile\");\n const mediaFiles: VastMediaFile[] = [];\n\n console.log(\n `${logPrefix} Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`\n );\n\n mediaFileElements.forEach((mf, index) => {\n const type = mf.getAttribute(\"type\") || \"\";\n const url = mf.textContent?.trim() || \"\";\n const width = mf.getAttribute(\"width\") || \"\";\n const height = mf.getAttribute(\"height\") || \"\";\n\n console.log(\n `${logPrefix} MediaFile ${index}: type=\"${type}\", url=\"${url.substring(0, 80)}...\", width=\"${width}\", height=\"${height}\"`\n );\n\n if (!url) {\n console.warn(`${logPrefix} MediaFile ${index} has empty URL`);\n return;\n }\n\n const isHls = isHlsType(type);\n const isMp4 = isMp4Type(type);\n\n let accepted = false;\n if (filter === \"hls-only\") {\n accepted = isHls;\n } else if (filter === \"mp4-first\") {\n accepted = isMp4 || isHls;\n } else {\n accepted = true;\n }\n\n if (!accepted) {\n console.log(\n `${logPrefix} MediaFile ${index} ignored (type=\"${type}\" not accepted by filter \"${filter}\")`\n );\n return;\n }\n\n const bitrateAttr = mf.getAttribute(\"bitrate\");\n const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : undefined;\n\n mediaFiles.push({\n url,\n type,\n width: parseInt(width || \"1920\", 10),\n height: parseInt(height || \"1080\", 10),\n bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : undefined,\n });\n\n console.log(`${logPrefix} Added MediaFile: type=\"${type}\" url=\"${url.substring(0, 80)}...\"`);\n });\n\n if (filter === \"mp4-first\" && mediaFiles.length > 1) {\n mediaFiles.sort((a, b) => {\n const aIsMp4 = isMp4Type(a.type) ? 0 : 1;\n const bIsMp4 = isMp4Type(b.type) ? 0 : 1;\n return aIsMp4 - bIsMp4;\n });\n }\n\n if (mediaFiles.length === 0) {\n if (isNoAdAvailable) {\n console.warn(\n `${logPrefix} No ads available (VAST response indicates no ads)`\n );\n } else {\n console.warn(`${logPrefix} No compatible media files found in VAST XML`);\n }\n return null;\n }\n\n const trackingUrls: VastTrackingUrls = {\n impression: [],\n start: [],\n firstQuartile: [],\n midpoint: [],\n thirdQuartile: [],\n complete: [],\n mute: [],\n unmute: [],\n pause: [],\n resume: [],\n fullscreen: [],\n exitFullscreen: [],\n skip: [],\n error: [],\n };\n\n xmlDoc.querySelectorAll(\"Impression\").forEach((el) => {\n const url = el.textContent?.trim();\n if (url) trackingUrls.impression.push(url);\n });\n\n xmlDoc.querySelectorAll(\"Tracking\").forEach((el) => {\n const event = el.getAttribute(\"event\");\n const url = el.textContent?.trim();\n if (event && url) {\n const eventKey = event as keyof VastTrackingUrls;\n if (trackingUrls[eventKey]) {\n trackingUrls[eventKey].push(url);\n }\n }\n });\n\n const clickThrough = xmlDoc\n .querySelector(\"ClickThrough\")\n ?.textContent?.trim();\n\n return {\n id: adId,\n title,\n duration,\n mediaFiles,\n trackingUrls,\n clickThrough,\n };\n } catch (error) {\n console.error(`${logPrefix} Error parsing VAST XML:`, error);\n return null;\n }\n}\n\nexport async function fetchAndParseVastAd(\n vastTagUrl: string,\n filter: MediaFileFilter = \"all\",\n logPrefix = \"[VastParser]\"\n): Promise<VastAd | null> {\n const response = await fetch(vastTagUrl, {\n mode: \"cors\",\n credentials: \"include\",\n headers: {\n Accept: \"application/xml, text/xml, */*\",\n },\n referrerPolicy: \"no-referrer-when-downgrade\",\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch VAST: ${response.statusText}`);\n }\n\n const vastXml = await response.text();\n console.log(`${logPrefix} VAST XML received`);\n console.log(\n `${logPrefix} VAST XML content (first 2000 chars):`,\n vastXml.substring(0, 2000)\n );\n\n return parseVastXml(vastXml, filter, logPrefix);\n}\n\nexport function createEmptyTrackingState() {\n return {\n impression: false,\n start: false,\n firstQuartile: false,\n midpoint: false,\n thirdQuartile: false,\n complete: false,\n };\n}\n\nexport function fireTrackingPixels(\n urls: string[],\n sessionId?: string,\n logPrefix = \"[VastParser]\"\n): void {\n if (!urls || urls.length === 0) return;\n\n urls.forEach((url) => {\n try {\n let trackingUrl = url;\n\n if (sessionId) {\n trackingUrl = `${trackingUrl}${\n trackingUrl.includes(\"?\") ? \"&\" : \"?\"\n }session_id=${sessionId}`;\n }\n\n const img = new Image(1, 1);\n img.onerror = () => {\n // 502 or other network errors are fire-and-forget; do not affect playback\n };\n img.src = trackingUrl;\n console.log(`${logPrefix} Fired tracking pixel: ${trackingUrl}`);\n } catch (error) {\n console.warn(`${logPrefix} Error firing tracking pixel:`, error);\n }\n });\n}\n"]}
|
package/lib/sdk/vastParser.d.cts
CHANGED
|
@@ -40,6 +40,6 @@ declare function createEmptyTrackingState(): {
|
|
|
40
40
|
thirdQuartile: boolean;
|
|
41
41
|
complete: boolean;
|
|
42
42
|
};
|
|
43
|
-
declare function fireTrackingPixels(urls: string[], sessionId?: string,
|
|
43
|
+
declare function fireTrackingPixels(urls: string[], sessionId?: string, logPrefix?: string): void;
|
|
44
44
|
|
|
45
45
|
export { type MediaFileFilter, type VastAd, type VastMediaFile, type VastTrackingUrls, createEmptyTrackingState, fetchAndParseVastAd, fireTrackingPixels, parseVastXml };
|
|
@@ -564,8 +564,8 @@ function createEmptyTrackingState() {
|
|
|
564
564
|
complete: false
|
|
565
565
|
};
|
|
566
566
|
}
|
|
567
|
-
function fireTrackingPixels(urls, sessionId
|
|
568
|
-
var logPrefix = arguments.length >
|
|
567
|
+
function fireTrackingPixels(urls, sessionId) {
|
|
568
|
+
var logPrefix = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "[VastParser]";
|
|
569
569
|
if (!urls || urls.length === 0) return;
|
|
570
570
|
urls.forEach(function(url) {
|
|
571
571
|
try {
|
|
@@ -573,10 +573,8 @@ function fireTrackingPixels(urls, sessionId, licenseKey) {
|
|
|
573
573
|
if (sessionId) {
|
|
574
574
|
trackingUrl = "".concat(trackingUrl).concat(trackingUrl.includes("?") ? "&" : "?", "session_id=").concat(sessionId);
|
|
575
575
|
}
|
|
576
|
-
if (licenseKey) {
|
|
577
|
-
trackingUrl = "".concat(trackingUrl).concat(trackingUrl.includes("?") ? "&" : "?", "license_key=").concat(licenseKey);
|
|
578
|
-
}
|
|
579
576
|
var img = new Image(1, 1);
|
|
577
|
+
img.onerror = function() {};
|
|
580
578
|
img.src = trackingUrl;
|
|
581
579
|
console.log("".concat(logPrefix, " Fired tracking pixel: ").concat(trackingUrl));
|
|
582
580
|
} catch (error) {
|
|
@@ -977,7 +975,7 @@ function createPrebidController(contentVideo, options) {
|
|
|
977
975
|
return "session-".concat(Date.now(), "-").concat(Math.random().toString(36).substr(2, 9));
|
|
978
976
|
}
|
|
979
977
|
function fireTrackingPixels2(urls) {
|
|
980
|
-
fireTrackingPixels(urls, sessionId,
|
|
978
|
+
fireTrackingPixels(urls, sessionId, LOG);
|
|
981
979
|
}
|
|
982
980
|
function getMainStreamQuality() {
|
|
983
981
|
if (!mainHlsInstance || !mainHlsInstance.levels) {
|
|
@@ -2714,6 +2712,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
2714
2712
|
this.totalAdRequestsInBreak = 0;
|
|
2715
2713
|
this.maxTotalAdRequestsPerBreak = 20;
|
|
2716
2714
|
this.pendingAdBreak = null;
|
|
2715
|
+
this.prefetchAdPromise = null;
|
|
2716
|
+
this.savedMutedStateBeforeScte = null;
|
|
2717
2717
|
this.consecutiveFailures = 0;
|
|
2718
2718
|
this.maxConsecutiveFailures = 5;
|
|
2719
2719
|
this.lastAdRequestTime = 0;
|
|
@@ -3189,6 +3189,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
3189
3189
|
}
|
|
3190
3190
|
}
|
|
3191
3191
|
console.error("[AD-ERROR]", errorMessage, errorPayload || "");
|
|
3192
|
+
_this.adController.stop().catch(function() {});
|
|
3192
3193
|
_this.handleAdFailure();
|
|
3193
3194
|
});
|
|
3194
3195
|
this.adController.on("content_pause", function() {
|
|
@@ -3251,6 +3252,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
3251
3252
|
{
|
|
3252
3253
|
key: "recreateAdController",
|
|
3253
3254
|
value: function recreateAdController() {
|
|
3255
|
+
this.prefetchAdPromise = null;
|
|
3254
3256
|
var shouldShowPlaceholder = this.inAdBreak && this.showAds;
|
|
3255
3257
|
if (shouldShowPlaceholder && this.adController) {
|
|
3256
3258
|
this.showPlaceholderLayer();
|
|
@@ -3579,6 +3581,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
3579
3581
|
if (marker.type === "start") {
|
|
3580
3582
|
var _this_config_immediateManifestAds;
|
|
3581
3583
|
var _this_pendingAdBreak;
|
|
3584
|
+
this.savedMutedStateBeforeScte = {
|
|
3585
|
+
muted: this.video.muted,
|
|
3586
|
+
volume: this.video.volume
|
|
3587
|
+
};
|
|
3588
|
+
this.adController.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3582
3589
|
if (!this.video.muted) {
|
|
3583
3590
|
this.video.muted = true;
|
|
3584
3591
|
this.video.volume = 0;
|
|
@@ -4020,6 +4027,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
4020
4027
|
{
|
|
4021
4028
|
key: "startAdPrefetch",
|
|
4022
4029
|
value: function startAdPrefetch(marker, fragmentSn) {
|
|
4030
|
+
var _this = this;
|
|
4023
4031
|
if (this.pendingAdBreak || this.inAdBreak) {
|
|
4024
4032
|
return;
|
|
4025
4033
|
}
|
|
@@ -4031,8 +4039,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
4031
4039
|
isFetching: false,
|
|
4032
4040
|
fetchStartTime: Date.now()
|
|
4033
4041
|
});
|
|
4042
|
+
this.prefetchAdPromise = this.adController.requestAds().catch(function() {
|
|
4043
|
+
if (_this.config.debugAdTiming) {
|
|
4044
|
+
console.log("[PREFETCH] Prebid auction prefetch failed, will request at playback time");
|
|
4045
|
+
}
|
|
4046
|
+
});
|
|
4034
4047
|
if (this.config.debugAdTiming) {
|
|
4035
|
-
console.log("[PREFETCH] Ad break marker registered, auction
|
|
4048
|
+
console.log("[PREFETCH] Ad break marker registered, auction prefetch started");
|
|
4036
4049
|
}
|
|
4037
4050
|
}
|
|
4038
4051
|
},
|
|
@@ -4043,6 +4056,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
4043
4056
|
clearTimeout(this.prefetchTimerId);
|
|
4044
4057
|
this.prefetchTimerId = void 0;
|
|
4045
4058
|
}
|
|
4059
|
+
this.prefetchAdPromise = null;
|
|
4046
4060
|
this.pendingAdBreak = null;
|
|
4047
4061
|
}
|
|
4048
4062
|
},
|
|
@@ -4050,7 +4064,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
4050
4064
|
key: "handleAdStart",
|
|
4051
4065
|
value: function handleAdStart(_marker) {
|
|
4052
4066
|
return _async_to_generator(function() {
|
|
4053
|
-
var adBreakDurationMs, mode,
|
|
4067
|
+
var _this_savedMutedStateBeforeScte, adBreakDurationMs, mode, state, unused, unused1, adLoadedInfo, adVolume, error;
|
|
4054
4068
|
return _ts_generator(this, function(_state) {
|
|
4055
4069
|
switch(_state.label){
|
|
4056
4070
|
case 0:
|
|
@@ -4063,9 +4077,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
4063
4077
|
this.continuousFetchingActive = true;
|
|
4064
4078
|
this.isShowingPlaceholder = false;
|
|
4065
4079
|
this.totalAdRequestsInBreak = 0;
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4080
|
+
state = (_this_savedMutedStateBeforeScte = this.savedMutedStateBeforeScte) !== null && _this_savedMutedStateBeforeScte !== void 0 ? _this_savedMutedStateBeforeScte : {
|
|
4081
|
+
muted: this.video.muted,
|
|
4082
|
+
volume: this.video.volume
|
|
4083
|
+
};
|
|
4084
|
+
this.adController.updateOriginalMutedState(state.muted, state.volume);
|
|
4085
|
+
this.savedMutedStateBeforeScte = null;
|
|
4069
4086
|
if (!this.video.muted) {
|
|
4070
4087
|
this.video.muted = true;
|
|
4071
4088
|
this.video.volume = 0;
|
|
@@ -4084,25 +4101,94 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
4084
4101
|
if (this.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {
|
|
4085
4102
|
this.expectedAdBreakDurationMs = adBreakDurationMs;
|
|
4086
4103
|
}
|
|
4087
|
-
this.clearPendingAdBreak();
|
|
4088
4104
|
if (this.config.debugAdTiming) {
|
|
4089
|
-
console.log("[CONTINUOUS-FETCH] \uD83D\uDCCB Prebid auction
|
|
4105
|
+
console.log("[CONTINUOUS-FETCH] \uD83D\uDCCB Prebid auction (prefetch or requestAds)");
|
|
4090
4106
|
}
|
|
4091
4107
|
_state.label = 1;
|
|
4092
4108
|
case 1:
|
|
4093
4109
|
_state.trys.push([
|
|
4094
4110
|
1,
|
|
4095
|
-
|
|
4111
|
+
6,
|
|
4096
4112
|
,
|
|
4097
|
-
|
|
4113
|
+
12
|
|
4098
4114
|
]);
|
|
4099
4115
|
this.lastAdRequestTime = Date.now();
|
|
4116
|
+
if (!this.prefetchAdPromise) return [
|
|
4117
|
+
3,
|
|
4118
|
+
3
|
|
4119
|
+
];
|
|
4100
4120
|
return [
|
|
4101
4121
|
4,
|
|
4102
|
-
this.
|
|
4122
|
+
this.prefetchAdPromise
|
|
4103
4123
|
];
|
|
4104
4124
|
case 2:
|
|
4105
4125
|
_state.sent();
|
|
4126
|
+
this.prefetchAdPromise = null;
|
|
4127
|
+
return [
|
|
4128
|
+
3,
|
|
4129
|
+
5
|
|
4130
|
+
];
|
|
4131
|
+
case 3:
|
|
4132
|
+
return [
|
|
4133
|
+
4,
|
|
4134
|
+
this.adController.requestAds()
|
|
4135
|
+
];
|
|
4136
|
+
case 4:
|
|
4137
|
+
_state.sent();
|
|
4138
|
+
_state.label = 5;
|
|
4139
|
+
case 5:
|
|
4140
|
+
return [
|
|
4141
|
+
3,
|
|
4142
|
+
12
|
|
4143
|
+
];
|
|
4144
|
+
case 6:
|
|
4145
|
+
unused = _state.sent();
|
|
4146
|
+
_state.label = 7;
|
|
4147
|
+
case 7:
|
|
4148
|
+
_state.trys.push([
|
|
4149
|
+
7,
|
|
4150
|
+
9,
|
|
4151
|
+
,
|
|
4152
|
+
11
|
|
4153
|
+
]);
|
|
4154
|
+
return [
|
|
4155
|
+
4,
|
|
4156
|
+
this.adController.requestAds()
|
|
4157
|
+
];
|
|
4158
|
+
case 8:
|
|
4159
|
+
_state.sent();
|
|
4160
|
+
return [
|
|
4161
|
+
3,
|
|
4162
|
+
11
|
|
4163
|
+
];
|
|
4164
|
+
case 9:
|
|
4165
|
+
unused1 = _state.sent();
|
|
4166
|
+
this.clearPendingAdBreak();
|
|
4167
|
+
this.consecutiveFailures++;
|
|
4168
|
+
return [
|
|
4169
|
+
4,
|
|
4170
|
+
this.tryNextAvailableAdWithRateLimit()
|
|
4171
|
+
];
|
|
4172
|
+
case 10:
|
|
4173
|
+
_state.sent();
|
|
4174
|
+
return [
|
|
4175
|
+
2
|
|
4176
|
+
];
|
|
4177
|
+
case 11:
|
|
4178
|
+
return [
|
|
4179
|
+
3,
|
|
4180
|
+
12
|
|
4181
|
+
];
|
|
4182
|
+
case 12:
|
|
4183
|
+
this.clearPendingAdBreak();
|
|
4184
|
+
_state.label = 13;
|
|
4185
|
+
case 13:
|
|
4186
|
+
_state.trys.push([
|
|
4187
|
+
13,
|
|
4188
|
+
15,
|
|
4189
|
+
,
|
|
4190
|
+
17
|
|
4191
|
+
]);
|
|
4106
4192
|
if (this.config.licenseKey) {
|
|
4107
4193
|
adLoadedInfo = {
|
|
4108
4194
|
source: this.getAdSource(),
|
|
@@ -4119,19 +4205,19 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
4119
4205
|
4,
|
|
4120
4206
|
this.adController.play()
|
|
4121
4207
|
];
|
|
4122
|
-
case
|
|
4208
|
+
case 14:
|
|
4123
4209
|
_state.sent();
|
|
4124
4210
|
if (this.expectedAdBreakDurationMs != null) {
|
|
4125
4211
|
this.currentAdBreakStartWallClockMs = Date.now();
|
|
4126
4212
|
this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
|
|
4127
4213
|
}
|
|
4128
|
-
adVolume =
|
|
4214
|
+
adVolume = state.muted ? 0 : state.volume;
|
|
4129
4215
|
this.adController.setAdVolume(adVolume);
|
|
4130
4216
|
return [
|
|
4131
4217
|
3,
|
|
4132
|
-
|
|
4218
|
+
17
|
|
4133
4219
|
];
|
|
4134
|
-
case
|
|
4220
|
+
case 15:
|
|
4135
4221
|
error = _state.sent();
|
|
4136
4222
|
if (this.config.debugAdTiming) {
|
|
4137
4223
|
console.warn("[CONTINUOUS-FETCH] \u26A0\uFE0F First ad request failed:", error);
|
|
@@ -4141,13 +4227,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
4141
4227
|
4,
|
|
4142
4228
|
this.tryNextAvailableAdWithRateLimit()
|
|
4143
4229
|
];
|
|
4144
|
-
case
|
|
4230
|
+
case 16:
|
|
4145
4231
|
_state.sent();
|
|
4146
4232
|
return [
|
|
4147
4233
|
3,
|
|
4148
|
-
|
|
4234
|
+
17
|
|
4149
4235
|
];
|
|
4150
|
-
case
|
|
4236
|
+
case 17:
|
|
4151
4237
|
return [
|
|
4152
4238
|
2
|
|
4153
4239
|
];
|