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.
@@ -78,7 +78,7 @@ var import_react2 = require("react");
78
78
  var import_hls = __toESM(require("hls.js"), 1);
79
79
 
80
80
  // src/sdk/ima.ts
81
- function createImaController(video) {
81
+ function createImaController(video, options) {
82
82
  let adPlaying = false;
83
83
  let originalMutedState = false;
84
84
  const listeners = /* @__PURE__ */ new Map();
@@ -271,8 +271,10 @@ function createImaController(video) {
271
271
  "[IMA] Max retries reached, emitting ad_error"
272
272
  );
273
273
  emit("ad_error");
274
- video.play().catch(() => {
275
- });
274
+ if (!options?.continueLiveStreamDuringAds) {
275
+ video.play().catch(() => {
276
+ });
277
+ }
276
278
  }
277
279
  }
278
280
  );
@@ -282,7 +284,14 @@ function createImaController(video) {
282
284
  console.log("[IMA] Content pause requested");
283
285
  originalMutedState = video.muted;
284
286
  video.muted = true;
285
- video.pause();
287
+ if (!options?.continueLiveStreamDuringAds) {
288
+ video.pause();
289
+ console.log("[IMA] Video paused (VOD mode)");
290
+ } else {
291
+ console.log(
292
+ "[IMA] Video continues playing but muted (Live mode)"
293
+ );
294
+ }
286
295
  adPlaying = true;
287
296
  if (adContainerEl)
288
297
  adContainerEl.style.pointerEvents = "auto";
@@ -297,8 +306,15 @@ function createImaController(video) {
297
306
  video.muted = originalMutedState;
298
307
  if (adContainerEl)
299
308
  adContainerEl.style.pointerEvents = "none";
300
- video.play().catch(() => {
301
- });
309
+ if (!options?.continueLiveStreamDuringAds) {
310
+ video.play().catch(() => {
311
+ });
312
+ console.log("[IMA] Video resumed (VOD mode)");
313
+ } else {
314
+ console.log(
315
+ "[IMA] Video unmuted (Live mode - was never paused)"
316
+ );
317
+ }
302
318
  emit("content_resume");
303
319
  }
304
320
  );
@@ -307,8 +323,17 @@ function createImaController(video) {
307
323
  adPlaying = false;
308
324
  video.muted = originalMutedState;
309
325
  if (adContainerEl) adContainerEl.style.pointerEvents = "none";
310
- video.play().catch(() => {
311
- });
326
+ if (!options?.continueLiveStreamDuringAds) {
327
+ video.play().catch(() => {
328
+ });
329
+ console.log(
330
+ "[IMA] Video resumed after all ads completed (VOD mode)"
331
+ );
332
+ } else {
333
+ console.log(
334
+ "[IMA] Video unmuted after all ads completed (Live mode)"
335
+ );
336
+ }
312
337
  emit("all_ads_completed");
313
338
  });
314
339
  console.log("[IMA] Ads manager event listeners attached");
@@ -322,8 +347,10 @@ function createImaController(video) {
322
347
  adPlaying = false;
323
348
  video.muted = originalMutedState;
324
349
  if (adContainerEl) adContainerEl.style.pointerEvents = "none";
325
- video.play().catch(() => {
326
- });
350
+ if (!options?.continueLiveStreamDuringAds) {
351
+ video.play().catch(() => {
352
+ });
353
+ }
327
354
  if (adsLoadedReject) {
328
355
  adsLoadedReject(new Error("Failed to setup ads manager"));
329
356
  adsLoadedReject = void 0;
@@ -377,8 +404,14 @@ function createImaController(video) {
377
404
  const height = video.clientHeight || 360;
378
405
  console.log(`[IMA] Initializing ads manager (${width}x${height})`);
379
406
  adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
380
- console.log("[IMA] Pausing video for ad playback");
381
- video.pause();
407
+ if (!options?.continueLiveStreamDuringAds) {
408
+ console.log("[IMA] Pausing video for ad playback (VOD mode)");
409
+ video.pause();
410
+ } else {
411
+ console.log(
412
+ "[IMA] Keeping video playing but muted for ad playback (Live mode)"
413
+ );
414
+ }
382
415
  adPlaying = true;
383
416
  console.log("[IMA] Starting ad playback");
384
417
  adsManager.start();
@@ -386,8 +419,10 @@ function createImaController(video) {
386
419
  } catch (error) {
387
420
  console.error("[IMA] Error starting ad playback:", error);
388
421
  adPlaying = false;
389
- video.play().catch(() => {
390
- });
422
+ if (!options?.continueLiveStreamDuringAds) {
423
+ video.play().catch(() => {
424
+ });
425
+ }
391
426
  return Promise.reject(error);
392
427
  }
393
428
  },
@@ -398,8 +433,13 @@ function createImaController(video) {
398
433
  adsManager?.stop?.();
399
434
  } catch {
400
435
  }
401
- video.play().catch(() => {
402
- });
436
+ if (!options?.continueLiveStreamDuringAds) {
437
+ video.play().catch(() => {
438
+ });
439
+ console.log("[IMA] Video resumed after stop (VOD mode)");
440
+ } else {
441
+ console.log("[IMA] Video unmuted after stop (Live mode)");
442
+ }
403
443
  },
404
444
  destroy() {
405
445
  try {
@@ -696,9 +736,12 @@ var StormcloudVideoPlayer = class {
696
736
  this.currentAdIndex = 0;
697
737
  this.totalAdsInBreak = 0;
698
738
  this.showAds = false;
739
+ this.isLiveStream = false;
699
740
  this.config = config;
700
741
  this.video = config.videoElement;
701
- this.ima = createImaController(this.video);
742
+ this.ima = createImaController(this.video, {
743
+ continueLiveStreamDuringAds: false
744
+ });
702
745
  }
703
746
  async load() {
704
747
  if (!this.attached) {
@@ -717,6 +760,22 @@ var StormcloudVideoPlayer = class {
717
760
  this.initializeTracking();
718
761
  if (this.shouldUseNativeHls()) {
719
762
  this.video.src = this.config.src;
763
+ this.isLiveStream = this.config.lowLatencyMode ?? false;
764
+ if (this.config.debugAdTiming) {
765
+ console.log(
766
+ "[StormcloudVideoPlayer] allowNativeHls: true - VOD mode detected:",
767
+ {
768
+ isLive: this.isLiveStream,
769
+ allowNativeHls: this.config.allowNativeHls,
770
+ adBehavior: "vod (main video pauses during ads)"
771
+ }
772
+ );
773
+ }
774
+ this.ima.destroy();
775
+ this.ima = createImaController(this.video, {
776
+ continueLiveStreamDuringAds: false
777
+ });
778
+ this.ima.initialize();
720
779
  if (this.config.autoplay) {
721
780
  await this.video.play().catch(() => {
722
781
  });
@@ -734,7 +793,23 @@ var StormcloudVideoPlayer = class {
734
793
  this.hls.on(import_hls.default.Events.MEDIA_ATTACHED, () => {
735
794
  this.hls?.loadSource(this.config.src);
736
795
  });
737
- this.hls.on(import_hls.default.Events.MANIFEST_PARSED, async () => {
796
+ this.hls.on(import_hls.default.Events.MANIFEST_PARSED, async (_, data) => {
797
+ this.isLiveStream = this.hls?.levels?.some(
798
+ (level) => level?.details?.live === true || level?.details?.type === "LIVE"
799
+ ) ?? false;
800
+ if (this.config.debugAdTiming) {
801
+ const adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
802
+ console.log("[StormcloudVideoPlayer] Stream type detected:", {
803
+ isLive: this.isLiveStream,
804
+ allowNativeHls: this.config.allowNativeHls,
805
+ adBehavior
806
+ });
807
+ }
808
+ this.ima.destroy();
809
+ this.ima = createImaController(this.video, {
810
+ continueLiveStreamDuringAds: this.shouldContinueLiveStreamDuringAds()
811
+ });
812
+ this.ima.initialize();
738
813
  if (this.config.autoplay) {
739
814
  await this.video.play().catch(() => {
740
815
  });
@@ -1360,6 +1435,15 @@ var StormcloudVideoPlayer = class {
1360
1435
  }
1361
1436
  return !!(this.config.allowNativeHls && !(this.config.showCustomControls ?? false));
1362
1437
  }
1438
+ shouldContinueLiveStreamDuringAds() {
1439
+ if (this.config.allowNativeHls) {
1440
+ return false;
1441
+ }
1442
+ if (!this.isLiveStream) {
1443
+ return false;
1444
+ }
1445
+ return true;
1446
+ }
1363
1447
  async loadDefaultVastFromAdstorm(adstormApiUrl, params) {
1364
1448
  const usp = new URLSearchParams(params || {});
1365
1449
  const url = `${adstormApiUrl}?${usp.toString()}`;
@@ -1674,6 +1758,9 @@ var StormcloudVideoPlayer = class {
1674
1758
  isFullscreen() {
1675
1759
  return !!document.fullscreenElement;
1676
1760
  }
1761
+ isLive() {
1762
+ return this.isLiveStream;
1763
+ }
1677
1764
  get videoElement() {
1678
1765
  return this.video;
1679
1766
  }