stormcloud-video-player 0.2.10 → 0.2.12

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/lib/index.cjs CHANGED
@@ -295,8 +295,11 @@ function createImaController(video, options) {
295
295
  );
296
296
  emit("ad_error");
297
297
  if (!options?.continueLiveStreamDuringAds) {
298
- video.play()?.catch(() => {
299
- });
298
+ if (video.paused) {
299
+ console.log("[IMA] Resuming paused video after ad error");
300
+ video.play()?.catch(() => {
301
+ });
302
+ }
300
303
  }
301
304
  }
302
305
  }
@@ -387,10 +390,17 @@ function createImaController(video, options) {
387
390
  console.error("[IMA] Error setting up ads manager:", e);
388
391
  adPlaying = false;
389
392
  video.muted = originalMutedState;
390
- if (adContainerEl) adContainerEl.style.pointerEvents = "none";
393
+ if (adContainerEl) {
394
+ adContainerEl.style.pointerEvents = "none";
395
+ adContainerEl.style.display = "none";
396
+ console.log("[IMA] Ad container hidden after setup error");
397
+ }
391
398
  if (!options?.continueLiveStreamDuringAds) {
392
- video.play().catch(() => {
393
- });
399
+ if (video.paused) {
400
+ console.log("[IMA] Resuming paused video after setup error");
401
+ video.play().catch(() => {
402
+ });
403
+ }
394
404
  }
395
405
  if (adsLoadedReject) {
396
406
  adsLoadedReject(new Error("Failed to setup ads manager"));
@@ -408,10 +418,17 @@ function createImaController(video, options) {
408
418
  console.error("[IMA] Ads loader error:", adErrorEvent.getError());
409
419
  adPlaying = false;
410
420
  video.muted = originalMutedState;
411
- if (adContainerEl) adContainerEl.style.pointerEvents = "none";
421
+ if (adContainerEl) {
422
+ adContainerEl.style.pointerEvents = "none";
423
+ adContainerEl.style.display = "none";
424
+ console.log("[IMA] Ad container hidden after loader error");
425
+ }
412
426
  if (!options?.continueLiveStreamDuringAds) {
413
- video.play().catch(() => {
414
- });
427
+ if (video.paused) {
428
+ console.log("[IMA] Resuming paused video after loader error");
429
+ video.play().catch(() => {
430
+ });
431
+ }
415
432
  }
416
433
  if (adsLoadedReject) {
417
434
  adsLoadedReject(new Error("Ads loader error"));
@@ -708,10 +725,18 @@ async function getBrowserID(clientInfo) {
708
725
  if (typeof crypto !== "undefined" && crypto.subtle && crypto.subtle.digest) {
709
726
  try {
710
727
  await crypto.subtle.digest("SHA-256", new Uint8Array([1, 2, 3]));
711
- const hashBuffer = await crypto.subtle.digest(
712
- "SHA-256",
713
- new TextEncoder().encode(fingerprintString)
714
- );
728
+ let encodedData;
729
+ if (typeof TextEncoder !== "undefined") {
730
+ encodedData = new TextEncoder().encode(fingerprintString);
731
+ } else {
732
+ const utf8 = unescape(encodeURIComponent(fingerprintString));
733
+ const buffer = new Uint8Array(utf8.length);
734
+ for (let i = 0; i < utf8.length; i++) {
735
+ buffer[i] = utf8.charCodeAt(i);
736
+ }
737
+ encodedData = buffer;
738
+ }
739
+ const hashBuffer = await crypto.subtle.digest("SHA-256", encodedData);
715
740
  const hashArray = Array.from(new Uint8Array(hashBuffer));
716
741
  const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
717
742
  cachedBrowserId = hashHex;
@@ -988,15 +1013,25 @@ var StormcloudVideoPlayer = class {
988
1013
  if (this.config.debugAdTiming) {
989
1014
  console.log("[StormcloudVideoPlayer] IMA ad_error event received");
990
1015
  }
991
- if (!this.inAdBreak) return;
992
- const remaining = this.getRemainingAdMs();
993
- if (remaining > 500 && this.adPodQueue.length > 0) {
994
- const next = this.adPodQueue.shift();
995
- this.currentAdIndex++;
996
- this.playSingleAd(next).catch(() => {
997
- });
998
- } else {
999
- this.handleAdFailure();
1016
+ if (this.showAds) {
1017
+ if (this.inAdBreak) {
1018
+ const remaining = this.getRemainingAdMs();
1019
+ if (remaining > 500 && this.adPodQueue.length > 0) {
1020
+ const next = this.adPodQueue.shift();
1021
+ this.currentAdIndex++;
1022
+ this.playSingleAd(next).catch(() => {
1023
+ });
1024
+ } else {
1025
+ this.handleAdFailure();
1026
+ }
1027
+ } else {
1028
+ if (this.config.debugAdTiming) {
1029
+ console.log(
1030
+ "[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
1031
+ );
1032
+ }
1033
+ this.handleAdFailure();
1034
+ }
1000
1035
  }
1001
1036
  });
1002
1037
  this.ima.on("content_pause", () => {
@@ -1577,9 +1612,20 @@ var StormcloudVideoPlayer = class {
1577
1612
  return;
1578
1613
  }
1579
1614
  if (vastTagUrl) {
1615
+ this.inAdBreak = true;
1580
1616
  this.showAds = true;
1581
1617
  this.currentAdIndex++;
1582
- await this.playSingleAd(vastTagUrl);
1618
+ try {
1619
+ await this.playSingleAd(vastTagUrl);
1620
+ } catch (error) {
1621
+ if (this.config.debugAdTiming) {
1622
+ console.error(
1623
+ "[StormcloudVideoPlayer] Ad playback failed in handleAdStart:",
1624
+ error
1625
+ );
1626
+ }
1627
+ this.handleAdFailure();
1628
+ }
1583
1629
  }
1584
1630
  if (this.expectedAdBreakDurationMs == null && scheduled?.durationMs != null) {
1585
1631
  this.expectedAdBreakDurationMs = scheduled.durationMs;
@@ -1710,7 +1756,13 @@ var StormcloudVideoPlayer = class {
1710
1756
  handleAdFailure() {
1711
1757
  if (this.config.debugAdTiming) {
1712
1758
  console.log(
1713
- "[StormcloudVideoPlayer] Handling ad failure - resuming content"
1759
+ "[StormcloudVideoPlayer] Handling ad failure - resuming content",
1760
+ {
1761
+ inAdBreak: this.inAdBreak,
1762
+ showAds: this.showAds,
1763
+ videoPaused: this.video.paused,
1764
+ adPlaying: this.ima.isAdPlaying()
1765
+ }
1714
1766
  );
1715
1767
  }
1716
1768
  this.inAdBreak = false;
@@ -1731,13 +1783,21 @@ var StormcloudVideoPlayer = class {
1731
1783
  );
1732
1784
  }
1733
1785
  if (this.video.paused) {
1734
- this.video.play()?.catch(() => {
1786
+ if (this.config.debugAdTiming) {
1787
+ console.log("[StormcloudVideoPlayer] Resuming paused video");
1788
+ }
1789
+ this.video.play()?.catch((error) => {
1735
1790
  if (this.config.debugAdTiming) {
1736
1791
  console.error(
1737
- "[StormcloudVideoPlayer] Failed to resume video after ad failure"
1792
+ "[StormcloudVideoPlayer] Failed to resume video after ad failure:",
1793
+ error
1738
1794
  );
1739
1795
  }
1740
1796
  });
1797
+ } else {
1798
+ if (this.config.debugAdTiming) {
1799
+ console.log("[StormcloudVideoPlayer] Video is already playing, no resume needed");
1800
+ }
1741
1801
  }
1742
1802
  }
1743
1803
  startAdFailsafeTimer() {
@@ -1749,10 +1809,12 @@ var StormcloudVideoPlayer = class {
1749
1809
  );
1750
1810
  }
1751
1811
  this.adFailsafeTimerId = window.setTimeout(() => {
1752
- if (this.video.paused) {
1812
+ const shouldTrigger = this.video.paused || this.showAds && !this.ima.isAdPlaying();
1813
+ if (shouldTrigger) {
1753
1814
  if (this.config.debugAdTiming) {
1754
1815
  console.warn(
1755
- "[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume"
1816
+ "[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume",
1817
+ { paused: this.video.paused, showAds: this.showAds, adPlaying: this.ima.isAdPlaying() }
1756
1818
  );
1757
1819
  }
1758
1820
  this.handleAdFailure();
@@ -3470,10 +3532,30 @@ var randomString = () => {
3470
3532
  };
3471
3533
  var parseQuery = (url) => {
3472
3534
  const query = {};
3473
- const params = new URLSearchParams(url.split("?")[1] || "");
3474
- params.forEach((value, key) => {
3475
- query[key] = value;
3476
- });
3535
+ const queryString = url.split("?")[1] || "";
3536
+ if (!queryString) return query;
3537
+ if (typeof URLSearchParams !== "undefined") {
3538
+ try {
3539
+ const params = new URLSearchParams(queryString);
3540
+ params.forEach((value, key) => {
3541
+ query[key] = value;
3542
+ });
3543
+ } catch (e) {
3544
+ queryString.split("&").forEach((param) => {
3545
+ const [key, value] = param.split("=");
3546
+ if (key) {
3547
+ query[decodeURIComponent(key)] = value ? decodeURIComponent(value) : "";
3548
+ }
3549
+ });
3550
+ }
3551
+ } else {
3552
+ queryString.split("&").forEach((param) => {
3553
+ const [key, value] = param.split("=");
3554
+ if (key) {
3555
+ query[decodeURIComponent(key)] = value ? decodeURIComponent(value) : "";
3556
+ }
3557
+ });
3558
+ }
3477
3559
  return query;
3478
3560
  };
3479
3561
  var merge = (target, ...sources) => {