stormcloud-video-player 0.8.4 → 0.8.6

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.
@@ -388,6 +388,7 @@ var import_react = __toESM(require("react"), 1);
388
388
  var import_hls2 = __toESM(require("hls.js"), 1);
389
389
  // src/sdk/hlsAdPlayer.ts
390
390
  var import_hls = __toESM(require("hls.js"), 1);
391
+ var MAX_VAST_WRAPPER_DEPTH = 5;
391
392
  function createHlsAdPlayer(contentVideo, options) {
392
393
  var adPlaying = false;
393
394
  var originalMutedState = false;
@@ -545,25 +546,91 @@ function createHlsAdPlayer(contentVideo, options) {
545
546
  var url = mediaFile.url.toLowerCase();
546
547
  return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
547
548
  }
549
+ function createEmptyTrackingUrls() {
550
+ return {
551
+ impression: [],
552
+ start: [],
553
+ firstQuartile: [],
554
+ midpoint: [],
555
+ thirdQuartile: [],
556
+ complete: [],
557
+ mute: [],
558
+ unmute: [],
559
+ pause: [],
560
+ resume: [],
561
+ fullscreen: [],
562
+ exitFullscreen: [],
563
+ skip: [],
564
+ error: []
565
+ };
566
+ }
567
+ function extractTrackingUrls(xmlDoc) {
568
+ var trackingUrls = createEmptyTrackingUrls();
569
+ xmlDoc.querySelectorAll("Impression").forEach(function(el) {
570
+ var _el_textContent;
571
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
572
+ if (url) trackingUrls.impression.push(url);
573
+ });
574
+ xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
575
+ var _el_textContent;
576
+ var event = el.getAttribute("event");
577
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
578
+ if (event && url) {
579
+ var eventKey = event;
580
+ if (trackingUrls[eventKey]) {
581
+ trackingUrls[eventKey].push(url);
582
+ }
583
+ }
584
+ });
585
+ xmlDoc.querySelectorAll("Error").forEach(function(el) {
586
+ var _el_textContent;
587
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
588
+ if (url) trackingUrls.error.push(url);
589
+ });
590
+ return trackingUrls;
591
+ }
592
+ function mergeTrackingUrls(target, source) {
593
+ Object.keys(target).forEach(function(key) {
594
+ if (source[key] && source[key].length > 0) {
595
+ target[key] = target[key].concat(source[key]);
596
+ }
597
+ });
598
+ return target;
599
+ }
548
600
  function parseVastXml(xmlString) {
549
601
  try {
550
- var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
602
+ var _xmlDoc_querySelector, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent1, _xmlDoc_querySelector2, _xmlDoc_querySelector3;
551
603
  var parser = new DOMParser();
552
604
  var xmlDoc = parser.parseFromString(xmlString, "text/xml");
553
605
  var parserError = xmlDoc.querySelector("parsererror");
554
606
  if (parserError) {
555
607
  console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
556
- return null;
608
+ return {
609
+ type: "empty"
610
+ };
557
611
  }
558
612
  var adElement = xmlDoc.querySelector("Ad");
559
613
  if (!adElement) {
560
614
  console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
561
- return null;
615
+ return {
616
+ type: "empty"
617
+ };
562
618
  }
563
619
  var adId = adElement.getAttribute("id") || "unknown";
564
620
  var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
621
+ var clickThrough = (_xmlDoc_querySelector1 = xmlDoc.querySelector("ClickThrough")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent = _xmlDoc_querySelector1.textContent) === null || _xmlDoc_querySelector_textContent === void 0 ? void 0 : _xmlDoc_querySelector_textContent.trim();
622
+ var wrapperUri = (_xmlDoc_querySelector2 = xmlDoc.querySelector("VASTAdTagURI")) === null || _xmlDoc_querySelector2 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent1 = _xmlDoc_querySelector2.textContent) === null || _xmlDoc_querySelector_textContent1 === void 0 ? void 0 : _xmlDoc_querySelector_textContent1.trim();
623
+ if (wrapperUri) {
624
+ console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(wrapperUri));
625
+ return {
626
+ type: "wrapper",
627
+ vastAdTagUri: wrapperUri,
628
+ trackingUrls: extractTrackingUrls(xmlDoc),
629
+ clickThrough: clickThrough
630
+ };
631
+ }
565
632
  var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
566
- var durationText = ((_xmlDoc_querySelector1 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : _xmlDoc_querySelector1.textContent) || "00:00:30";
633
+ var durationText = ((_xmlDoc_querySelector3 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector3 === void 0 ? void 0 : _xmlDoc_querySelector3.textContent) || "00:00:30";
567
634
  var durationParts = durationText.split(":");
568
635
  var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
569
636
  var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
@@ -603,57 +670,31 @@ function createHlsAdPlayer(contentVideo, options) {
603
670
  } else {
604
671
  console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
605
672
  }
606
- return null;
607
- }
608
- var trackingUrls = {
609
- impression: [],
610
- start: [],
611
- firstQuartile: [],
612
- midpoint: [],
613
- thirdQuartile: [],
614
- complete: [],
615
- mute: [],
616
- unmute: [],
617
- pause: [],
618
- resume: [],
619
- fullscreen: [],
620
- exitFullscreen: [],
621
- skip: [],
622
- error: []
623
- };
624
- xmlDoc.querySelectorAll("Impression").forEach(function(el) {
625
- var _el_textContent;
626
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
627
- if (url) trackingUrls.impression.push(url);
628
- });
629
- xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
630
- var _el_textContent;
631
- var event = el.getAttribute("event");
632
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
633
- if (event && url) {
634
- var eventKey = event;
635
- if (trackingUrls[eventKey]) {
636
- trackingUrls[eventKey].push(url);
637
- }
638
- }
639
- });
640
- var clickThrough = (_xmlDoc_querySelector2 = xmlDoc.querySelector("ClickThrough")) === null || _xmlDoc_querySelector2 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent = _xmlDoc_querySelector2.textContent) === null || _xmlDoc_querySelector_textContent === void 0 ? void 0 : _xmlDoc_querySelector_textContent.trim();
673
+ return {
674
+ type: "empty"
675
+ };
676
+ }
641
677
  return {
642
- id: adId,
643
- title: title,
644
- duration: duration,
645
- mediaFiles: mediaFiles,
646
- trackingUrls: trackingUrls,
647
- clickThrough: clickThrough
678
+ type: "inline",
679
+ ad: {
680
+ id: adId,
681
+ title: title,
682
+ duration: duration,
683
+ mediaFiles: mediaFiles,
684
+ trackingUrls: extractTrackingUrls(xmlDoc),
685
+ clickThrough: clickThrough
686
+ }
648
687
  };
649
688
  } catch (error) {
650
689
  console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
651
- return null;
690
+ return {
691
+ type: "empty"
692
+ };
652
693
  }
653
694
  }
654
- function fetchAndParseVastAd(vastTagUrl) {
695
+ function fetchVastXml(vastTagUrl) {
655
696
  return _async_to_generator(function() {
656
- var response, vastXml;
697
+ var response;
657
698
  return _ts_generator(this, function(_state) {
658
699
  switch(_state.label){
659
700
  case 0:
@@ -674,20 +715,58 @@ function createHlsAdPlayer(contentVideo, options) {
674
715
  throw new Error("Failed to fetch VAST: ".concat(response.statusText));
675
716
  }
676
717
  return [
677
- 4,
718
+ 2,
678
719
  response.text()
679
720
  ];
680
- case 2:
721
+ }
722
+ });
723
+ })();
724
+ }
725
+ function fetchAndParseVastAd(_0) {
726
+ return _async_to_generator(function(vastTagUrl) {
727
+ var depth, accumulatedTracking, vastXml, parsed;
728
+ var _arguments = arguments;
729
+ return _ts_generator(this, function(_state) {
730
+ switch(_state.label){
731
+ case 0:
732
+ depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls();
733
+ return [
734
+ 4,
735
+ fetchVastXml(vastTagUrl)
736
+ ];
737
+ case 1:
681
738
  vastXml = _state.sent();
682
739
  console.log("[HlsAdPlayer] VAST XML received");
683
740
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
741
+ parsed = parseVastXml(vastXml);
742
+ if (parsed.type === "empty") {
743
+ return [
744
+ 2,
745
+ null
746
+ ];
747
+ }
748
+ if (parsed.type === "wrapper") {
749
+ if (depth >= MAX_VAST_WRAPPER_DEPTH) {
750
+ console.warn("[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain"));
751
+ return [
752
+ 2,
753
+ null
754
+ ];
755
+ }
756
+ mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);
757
+ return [
758
+ 2,
759
+ fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking)
760
+ ];
761
+ }
762
+ mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);
684
763
  return [
685
764
  2,
686
- parseVastXml(vastXml)
765
+ parsed.ad
687
766
  ];
688
767
  }
689
768
  });
690
- })();
769
+ }).apply(this, arguments);
691
770
  }
692
771
  function createAdVideoElement() {
693
772
  var video = document.createElement("video");
@@ -2226,6 +2305,166 @@ function initializePolyfills() {
2226
2305
  polyfillTextEncoder();
2227
2306
  polyfillPromiseFinally();
2228
2307
  }
2308
+ // src/utils/vastMacros.ts
2309
+ function generateCorrelator() {
2310
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
2311
+ try {
2312
+ var _buf_, _buf_1;
2313
+ var buf = new Uint32Array(2);
2314
+ crypto.getRandomValues(buf);
2315
+ var value = ((_buf_ = buf[0]) !== null && _buf_ !== void 0 ? _buf_ : 0) * 2097152 + (((_buf_1 = buf[1]) !== null && _buf_1 !== void 0 ? _buf_1 : 0) & 2097151);
2316
+ if (value > 0) {
2317
+ return String(value);
2318
+ }
2319
+ } catch (unused) {}
2320
+ }
2321
+ return String(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) + 1);
2322
+ }
2323
+ var UNEXPANDED_MACRO_PATTERN = /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/;
2324
+ function applyVastMacros(baseUrl, ctx) {
2325
+ var url;
2326
+ try {
2327
+ url = new URL(baseUrl);
2328
+ } catch (unused) {
2329
+ return replaceCorrelatorFallback(baseUrl, ctx.correlator);
2330
+ }
2331
+ var params = url.searchParams;
2332
+ params.set("correlator", ctx.correlator);
2333
+ params.set("scor", ctx.streamCorrelator);
2334
+ if (ctx.pod != null) {
2335
+ params.set("pod", String(ctx.pod));
2336
+ }
2337
+ if (ctx.adPosition != null) {
2338
+ params.set("ppos", String(ctx.adPosition));
2339
+ }
2340
+ if (ctx.pageUrl) {
2341
+ params.set("url", ctx.pageUrl);
2342
+ params.set("description_url", ctx.pageUrl);
2343
+ }
2344
+ if (ctx.adWillPlayMuted != null) {
2345
+ params.set("vpmute", ctx.adWillPlayMuted ? "1" : "0");
2346
+ }
2347
+ if (ctx.adWillAutoPlay != null) {
2348
+ params.set("vpa", ctx.adWillAutoPlay ? "auto" : "click");
2349
+ }
2350
+ if (ctx.deviceId && ctx.deviceIdType) {
2351
+ params.set("rdid", ctx.deviceId);
2352
+ params.set("idtype", ctx.deviceIdType);
2353
+ params.set("is_lat", ctx.limitAdTracking ? "1" : "0");
2354
+ } else {
2355
+ params.delete("rdid");
2356
+ params.delete("idtype");
2357
+ params.delete("is_lat");
2358
+ }
2359
+ var consent = ctx.consent;
2360
+ if ((consent === null || consent === void 0 ? void 0 : consent.gdpr) != null) {
2361
+ params.set("gdpr", consent.gdpr);
2362
+ }
2363
+ if ((consent === null || consent === void 0 ? void 0 : consent.gdprConsent) != null) {
2364
+ params.set("gdpr_consent", consent.gdprConsent);
2365
+ }
2366
+ if ((consent === null || consent === void 0 ? void 0 : consent.usPrivacy) != null) {
2367
+ params.set("us_privacy", consent.usPrivacy);
2368
+ }
2369
+ if (ctx.adTest) {
2370
+ params.set("adtest", "on");
2371
+ }
2372
+ var staleKeys = [];
2373
+ params.forEach(function(value, key) {
2374
+ if (UNEXPANDED_MACRO_PATTERN.test(value)) {
2375
+ staleKeys.push(key);
2376
+ }
2377
+ });
2378
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2379
+ try {
2380
+ for(var _iterator = staleKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2381
+ var key = _step.value;
2382
+ params.delete(key);
2383
+ }
2384
+ } catch (err) {
2385
+ _didIteratorError = true;
2386
+ _iteratorError = err;
2387
+ } finally{
2388
+ try {
2389
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2390
+ _iterator.return();
2391
+ }
2392
+ } finally{
2393
+ if (_didIteratorError) {
2394
+ throw _iteratorError;
2395
+ }
2396
+ }
2397
+ }
2398
+ return url.toString();
2399
+ }
2400
+ function replaceCorrelatorFallback(baseUrl, correlator) {
2401
+ var correlatorRegex = /([?&])correlator=([^&]*)/;
2402
+ if (correlatorRegex.test(baseUrl)) {
2403
+ return baseUrl.replace(correlatorRegex, "$1correlator=".concat(correlator));
2404
+ }
2405
+ var sep = baseUrl.includes("?") ? "&" : "?";
2406
+ return "".concat(baseUrl).concat(sep, "correlator=").concat(correlator);
2407
+ }
2408
+ function fetchConsentSignals() {
2409
+ var timeoutMs = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 1500;
2410
+ var signals = {};
2411
+ if (typeof window === "undefined") {
2412
+ return Promise.resolve(signals);
2413
+ }
2414
+ var tasks = [];
2415
+ var tcfApi = window.__tcfapi;
2416
+ if (typeof tcfApi === "function") {
2417
+ tasks.push(new Promise(function(resolve) {
2418
+ var settled = false;
2419
+ try {
2420
+ tcfApi("addEventListener", 2, function(tcData, success) {
2421
+ if (settled) return;
2422
+ if (success && tcData && (tcData.eventStatus === "tcloaded" || tcData.eventStatus === "useractioncomplete")) {
2423
+ settled = true;
2424
+ signals.gdpr = tcData.gdprApplies ? "1" : "0";
2425
+ if (typeof tcData.tcString === "string" && tcData.tcString) {
2426
+ signals.gdprConsent = tcData.tcString;
2427
+ }
2428
+ try {
2429
+ tcfApi("removeEventListener", 2, function() {}, tcData.listenerId);
2430
+ } catch (unused) {}
2431
+ resolve();
2432
+ }
2433
+ });
2434
+ } catch (unused) {
2435
+ resolve();
2436
+ }
2437
+ setTimeout(function() {
2438
+ if (!settled) {
2439
+ settled = true;
2440
+ resolve();
2441
+ }
2442
+ }, timeoutMs);
2443
+ }));
2444
+ }
2445
+ var uspApi = window.__uspapi;
2446
+ if (typeof uspApi === "function") {
2447
+ tasks.push(new Promise(function(resolve) {
2448
+ try {
2449
+ uspApi("getUSPData", 1, function(data, success) {
2450
+ if (success && typeof (data === null || data === void 0 ? void 0 : data.uspString) === "string" && data.uspString) {
2451
+ signals.usPrivacy = data.uspString;
2452
+ }
2453
+ resolve();
2454
+ });
2455
+ } catch (unused) {
2456
+ resolve();
2457
+ }
2458
+ setTimeout(resolve, timeoutMs);
2459
+ }));
2460
+ }
2461
+ if (tasks.length === 0) {
2462
+ return Promise.resolve(signals);
2463
+ }
2464
+ return Promise.all(tasks).then(function() {
2465
+ return signals;
2466
+ });
2467
+ }
2229
2468
  // src/utils/browserCompat.ts
2230
2469
  function getChromeVersion(ua) {
2231
2470
  var match = ua.match(/Chrome\/(\d+)/);
@@ -2451,6 +2690,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2451
2690
  this.preloadPoolLoopRunning = false;
2452
2691
  this.adDetectSentForCurrentBreak = false;
2453
2692
  this.palPlaybackStarted = false;
2693
+ this.streamCorrelator = generateCorrelator();
2694
+ this.consentSignals = {};
2695
+ this.podCounter = 0;
2696
+ this.podAssignedByPrefetch = false;
2697
+ this.adRequestPositionInBreak = 0;
2454
2698
  this.continuousFetchLoopRunning = false;
2455
2699
  initializePolyfills();
2456
2700
  var browserOverrides = getBrowserConfigOverrides();
@@ -2523,6 +2767,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2523
2767
  adWillPlayMuted: !!this.config.muted,
2524
2768
  continuousPlayback: (_this_config_lowLatencyMode = this.config.lowLatencyMode) !== null && _this_config_lowLatencyMode !== void 0 ? _this_config_lowLatencyMode : false
2525
2769
  }).catch(function() {});
2770
+ fetchConsentSignals().then(function(signals) {
2771
+ _this.consentSignals = signals;
2772
+ }).catch(function() {});
2526
2773
  this.initializeTracking();
2527
2774
  if (!this.shouldUseNativeHls()) return [
2528
2775
  3,
@@ -4819,25 +5066,35 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4819
5066
  return this.getRemainingAdMs();
4820
5067
  }
4821
5068
  },
5069
+ {
5070
+ key: "beginNewAdPod",
5071
+ value: function beginNewAdPod() {
5072
+ this.podCounter++;
5073
+ this.adRequestPositionInBreak = 0;
5074
+ }
5075
+ },
4822
5076
  {
4823
5077
  key: "generateVastUrlsWithCorrelators",
4824
5078
  value: function generateVastUrlsWithCorrelators(baseUrl, count) {
4825
5079
  var urls = [];
4826
- var baseTimestamp = Date.now();
4827
5080
  for(var i = 0; i < count; i++){
4828
- var timestamp = baseTimestamp + i;
4829
- var random = Math.floor(Math.random() * 1e12);
4830
- var uniqueCorrelator = "".concat(timestamp, "_").concat(random, "_").concat(i);
4831
- var urlWithCorrelator = void 0;
4832
- var correlatorRegex = /([?&])correlator=([^&]*)/;
4833
- if (correlatorRegex.test(baseUrl)) {
4834
- urlWithCorrelator = baseUrl.replace(correlatorRegex, "$1correlator=".concat(uniqueCorrelator));
4835
- } else if (baseUrl.includes("?")) {
4836
- urlWithCorrelator = "".concat(baseUrl, "&correlator=").concat(uniqueCorrelator);
4837
- } else {
4838
- urlWithCorrelator = "".concat(baseUrl, "?correlator=").concat(uniqueCorrelator);
4839
- }
4840
- urls.push(this.palNonce.injectNonce(urlWithCorrelator));
5081
+ this.adRequestPositionInBreak++;
5082
+ var adWillPlayMuted = this.inAdBreak ? this.adPlayer.getOriginalMutedState() : this.video.muted;
5083
+ var urlWithMacros = applyVastMacros(baseUrl, {
5084
+ correlator: generateCorrelator(),
5085
+ streamCorrelator: this.streamCorrelator,
5086
+ pod: this.podCounter > 0 ? this.podCounter : void 0,
5087
+ adPosition: this.adRequestPositionInBreak,
5088
+ pageUrl: typeof window !== "undefined" ? window.location.href : void 0,
5089
+ adWillPlayMuted: adWillPlayMuted,
5090
+ adWillAutoPlay: !!this.config.autoplay,
5091
+ deviceId: this.config.deviceId,
5092
+ deviceIdType: this.config.deviceIdType,
5093
+ limitAdTracking: this.config.limitAdTracking,
5094
+ adTest: this.config.adTest,
5095
+ consent: this.consentSignals
5096
+ });
5097
+ urls.push(this.palNonce.injectNonce(urlWithMacros));
4841
5098
  }
4842
5099
  return urls;
4843
5100
  }
@@ -4907,6 +5164,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4907
5164
  }
4908
5165
  return;
4909
5166
  }
5167
+ this.beginNewAdPod();
5168
+ this.podAssignedByPrefetch = true;
4910
5169
  var urlsToPregenerate = 5;
4911
5170
  var generatedUrls = this.generateVastUrlsWithCorrelators(baseVastUrl, urlsToPregenerate);
4912
5171
  this.pendingAdBreak = _object_spread_props(_object_spread({
@@ -4944,6 +5203,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4944
5203
  }
4945
5204
  this.pendingAdBreak = null;
4946
5205
  this.pendingScte35CueKey = void 0;
5206
+ this.podAssignedByPrefetch = false;
4947
5207
  }
4948
5208
  },
4949
5209
  {
@@ -5380,6 +5640,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5380
5640
  this.continuousFetchingActive = true;
5381
5641
  this.isShowingPlaceholder = false;
5382
5642
  this.totalAdRequestsInBreak = 0;
5643
+ if (this.podAssignedByPrefetch) {
5644
+ this.podAssignedByPrefetch = false;
5645
+ } else {
5646
+ this.beginNewAdPod();
5647
+ }
5383
5648
  currentMuted = this.video.muted;
5384
5649
  currentVolume = this.video.volume;
5385
5650
  this.adPlayer.updateOriginalMutedState(currentMuted, currentVolume);