stormcloud-video-player 0.2.3 → 0.2.4

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.
@@ -39,7 +39,7 @@ var import_react = require("react");
39
39
  var import_hls = __toESM(require("hls.js"), 1);
40
40
 
41
41
  // src/sdk/ima.ts
42
- function createImaController(video) {
42
+ function createImaController(video, options) {
43
43
  let adPlaying = false;
44
44
  let originalMutedState = false;
45
45
  const listeners = /* @__PURE__ */ new Map();
@@ -232,8 +232,10 @@ function createImaController(video) {
232
232
  "[IMA] Max retries reached, emitting ad_error"
233
233
  );
234
234
  emit("ad_error");
235
- video.play().catch(() => {
236
- });
235
+ if (!options?.continueLiveStreamDuringAds) {
236
+ video.play().catch(() => {
237
+ });
238
+ }
237
239
  }
238
240
  }
239
241
  );
@@ -243,7 +245,14 @@ function createImaController(video) {
243
245
  console.log("[IMA] Content pause requested");
244
246
  originalMutedState = video.muted;
245
247
  video.muted = true;
246
- video.pause();
248
+ if (!options?.continueLiveStreamDuringAds) {
249
+ video.pause();
250
+ console.log("[IMA] Video paused (VOD mode)");
251
+ } else {
252
+ console.log(
253
+ "[IMA] Video continues playing but muted (Live mode)"
254
+ );
255
+ }
247
256
  adPlaying = true;
248
257
  if (adContainerEl)
249
258
  adContainerEl.style.pointerEvents = "auto";
@@ -258,8 +267,15 @@ function createImaController(video) {
258
267
  video.muted = originalMutedState;
259
268
  if (adContainerEl)
260
269
  adContainerEl.style.pointerEvents = "none";
261
- video.play().catch(() => {
262
- });
270
+ if (!options?.continueLiveStreamDuringAds) {
271
+ video.play().catch(() => {
272
+ });
273
+ console.log("[IMA] Video resumed (VOD mode)");
274
+ } else {
275
+ console.log(
276
+ "[IMA] Video unmuted (Live mode - was never paused)"
277
+ );
278
+ }
263
279
  emit("content_resume");
264
280
  }
265
281
  );
@@ -268,8 +284,17 @@ function createImaController(video) {
268
284
  adPlaying = false;
269
285
  video.muted = originalMutedState;
270
286
  if (adContainerEl) adContainerEl.style.pointerEvents = "none";
271
- video.play().catch(() => {
272
- });
287
+ if (!options?.continueLiveStreamDuringAds) {
288
+ video.play().catch(() => {
289
+ });
290
+ console.log(
291
+ "[IMA] Video resumed after all ads completed (VOD mode)"
292
+ );
293
+ } else {
294
+ console.log(
295
+ "[IMA] Video unmuted after all ads completed (Live mode)"
296
+ );
297
+ }
273
298
  emit("all_ads_completed");
274
299
  });
275
300
  console.log("[IMA] Ads manager event listeners attached");
@@ -283,8 +308,10 @@ function createImaController(video) {
283
308
  adPlaying = false;
284
309
  video.muted = originalMutedState;
285
310
  if (adContainerEl) adContainerEl.style.pointerEvents = "none";
286
- video.play().catch(() => {
287
- });
311
+ if (!options?.continueLiveStreamDuringAds) {
312
+ video.play().catch(() => {
313
+ });
314
+ }
288
315
  if (adsLoadedReject) {
289
316
  adsLoadedReject(new Error("Failed to setup ads manager"));
290
317
  adsLoadedReject = void 0;
@@ -338,8 +365,14 @@ function createImaController(video) {
338
365
  const height = video.clientHeight || 360;
339
366
  console.log(`[IMA] Initializing ads manager (${width}x${height})`);
340
367
  adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
341
- console.log("[IMA] Pausing video for ad playback");
342
- video.pause();
368
+ if (!options?.continueLiveStreamDuringAds) {
369
+ console.log("[IMA] Pausing video for ad playback (VOD mode)");
370
+ video.pause();
371
+ } else {
372
+ console.log(
373
+ "[IMA] Keeping video playing but muted for ad playback (Live mode)"
374
+ );
375
+ }
343
376
  adPlaying = true;
344
377
  console.log("[IMA] Starting ad playback");
345
378
  adsManager.start();
@@ -347,8 +380,10 @@ function createImaController(video) {
347
380
  } catch (error) {
348
381
  console.error("[IMA] Error starting ad playback:", error);
349
382
  adPlaying = false;
350
- video.play().catch(() => {
351
- });
383
+ if (!options?.continueLiveStreamDuringAds) {
384
+ video.play().catch(() => {
385
+ });
386
+ }
352
387
  return Promise.reject(error);
353
388
  }
354
389
  },
@@ -359,8 +394,13 @@ function createImaController(video) {
359
394
  adsManager?.stop?.();
360
395
  } catch {
361
396
  }
362
- video.play().catch(() => {
363
- });
397
+ if (!options?.continueLiveStreamDuringAds) {
398
+ video.play().catch(() => {
399
+ });
400
+ console.log("[IMA] Video resumed after stop (VOD mode)");
401
+ } else {
402
+ console.log("[IMA] Video unmuted after stop (Live mode)");
403
+ }
364
404
  },
365
405
  destroy() {
366
406
  try {
@@ -657,9 +697,12 @@ var StormcloudVideoPlayer = class {
657
697
  this.currentAdIndex = 0;
658
698
  this.totalAdsInBreak = 0;
659
699
  this.showAds = false;
700
+ this.isLiveStream = false;
660
701
  this.config = config;
661
702
  this.video = config.videoElement;
662
- this.ima = createImaController(this.video);
703
+ this.ima = createImaController(this.video, {
704
+ continueLiveStreamDuringAds: false
705
+ });
663
706
  }
664
707
  async load() {
665
708
  if (!this.attached) {
@@ -678,6 +721,22 @@ var StormcloudVideoPlayer = class {
678
721
  this.initializeTracking();
679
722
  if (this.shouldUseNativeHls()) {
680
723
  this.video.src = this.config.src;
724
+ this.isLiveStream = this.config.lowLatencyMode ?? false;
725
+ if (this.config.debugAdTiming) {
726
+ console.log(
727
+ "[StormcloudVideoPlayer] allowNativeHls: true - VOD mode detected:",
728
+ {
729
+ isLive: this.isLiveStream,
730
+ allowNativeHls: this.config.allowNativeHls,
731
+ adBehavior: "vod (main video pauses during ads)"
732
+ }
733
+ );
734
+ }
735
+ this.ima.destroy();
736
+ this.ima = createImaController(this.video, {
737
+ continueLiveStreamDuringAds: false
738
+ });
739
+ this.ima.initialize();
681
740
  if (this.config.autoplay) {
682
741
  await this.video.play().catch(() => {
683
742
  });
@@ -695,7 +754,23 @@ var StormcloudVideoPlayer = class {
695
754
  this.hls.on(import_hls.default.Events.MEDIA_ATTACHED, () => {
696
755
  this.hls?.loadSource(this.config.src);
697
756
  });
698
- this.hls.on(import_hls.default.Events.MANIFEST_PARSED, async () => {
757
+ this.hls.on(import_hls.default.Events.MANIFEST_PARSED, async (_, data) => {
758
+ this.isLiveStream = this.hls?.levels?.some(
759
+ (level) => level?.details?.live === true || level?.details?.type === "LIVE"
760
+ ) ?? false;
761
+ if (this.config.debugAdTiming) {
762
+ const adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
763
+ console.log("[StormcloudVideoPlayer] Stream type detected:", {
764
+ isLive: this.isLiveStream,
765
+ allowNativeHls: this.config.allowNativeHls,
766
+ adBehavior
767
+ });
768
+ }
769
+ this.ima.destroy();
770
+ this.ima = createImaController(this.video, {
771
+ continueLiveStreamDuringAds: this.shouldContinueLiveStreamDuringAds()
772
+ });
773
+ this.ima.initialize();
699
774
  if (this.config.autoplay) {
700
775
  await this.video.play().catch(() => {
701
776
  });
@@ -1321,6 +1396,15 @@ var StormcloudVideoPlayer = class {
1321
1396
  }
1322
1397
  return !!(this.config.allowNativeHls && !(this.config.showCustomControls ?? false));
1323
1398
  }
1399
+ shouldContinueLiveStreamDuringAds() {
1400
+ if (this.config.allowNativeHls) {
1401
+ return false;
1402
+ }
1403
+ if (!this.isLiveStream) {
1404
+ return false;
1405
+ }
1406
+ return true;
1407
+ }
1324
1408
  async loadDefaultVastFromAdstorm(adstormApiUrl, params) {
1325
1409
  const usp = new URLSearchParams(params || {});
1326
1410
  const url = `${adstormApiUrl}?${usp.toString()}`;
@@ -1635,6 +1719,9 @@ var StormcloudVideoPlayer = class {
1635
1719
  isFullscreen() {
1636
1720
  return !!document.fullscreenElement;
1637
1721
  }
1722
+ isLive() {
1723
+ return this.isLiveStream;
1724
+ }
1638
1725
  get videoElement() {
1639
1726
  return this.video;
1640
1727
  }