stormcloud-video-player 0.3.62 → 0.3.63

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.
@@ -1,5 +1,5 @@
1
1
  import { Component } from 'react';
2
- import { S as StormcloudVideoPlayerConfig } from '../types-BJPNhfLV.cjs';
2
+ import { S as StormcloudVideoPlayerConfig } from '../types-CjI14dPN.cjs';
3
3
 
4
4
  interface HlsPlayerProps extends StormcloudVideoPlayerConfig {
5
5
  onMount?: (player: any) => void;
@@ -3528,7 +3528,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3528
3528
  var _level_details, _level_details1;
3529
3529
  return (level === null || level === void 0 ? void 0 : (_level_details = level.details) === null || _level_details === void 0 ? void 0 : _level_details.live) === true || (level === null || level === void 0 ? void 0 : (_level_details1 = level.details) === null || _level_details1 === void 0 ? void 0 : _level_details1.type) === "LIVE";
3530
3530
  })) !== null && _ref !== void 0 ? _ref : false;
3531
- if (!this.isLiveStream && this.vmapBreaks.length === 0 && this.apiVastTagUrl) {
3531
+ if (!this.isVmapEnabled() && !this.isLiveStream && this.vmapBreaks.length === 0 && this.apiVastTagUrl) {
3532
3532
  prerollKey = "synthetic-vod-preroll";
3533
3533
  if (!this.consumedVmapBreakIds.has(prerollKey)) {
3534
3534
  this.vmapBreaks = [
@@ -4111,6 +4111,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4111
4111
  _this.onTimeUpdate(_this.video.currentTime);
4112
4112
  };
4113
4113
  this.video.addEventListener("timeupdate", this.timeUpdateHandler);
4114
+ this.endedHandler = function() {
4115
+ _this.onVideoEnded();
4116
+ };
4117
+ this.video.addEventListener("ended", this.endedHandler);
4114
4118
  this.emptiedHandler = function() {
4115
4119
  if (_this.nativeHlsMode && _this.videoSrcProtection && !_this.ima.isAdPlaying()) {
4116
4120
  if (_this.config.debugAdTiming) {
@@ -5422,6 +5426,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5422
5426
  }
5423
5427
  }
5424
5428
  },
5429
+ {
5430
+ key: "isVmapEnabled",
5431
+ value: function isVmapEnabled() {
5432
+ var _this_config_vmapUrl;
5433
+ return !!(this.config.isVmap && ((_this_config_vmapUrl = this.config.vmapUrl) === null || _this_config_vmapUrl === void 0 ? void 0 : _this_config_vmapUrl.trim()));
5434
+ }
5435
+ },
5425
5436
  {
5426
5437
  key: "fetchAdConfiguration",
5427
5438
  value: function fetchAdConfiguration() {
@@ -5430,7 +5441,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5430
5441
  return _ts_generator(this, function(_state) {
5431
5442
  switch(_state.label){
5432
5443
  case 0:
5433
- if (!this.config.vmapUrl) return [
5444
+ if (!this.isVmapEnabled()) return [
5434
5445
  3,
5435
5446
  2
5436
5447
  ];
@@ -5440,7 +5451,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5440
5451
  ];
5441
5452
  case 1:
5442
5453
  _state.sent();
5443
- _state.label = 2;
5454
+ if (this.config.debugAdTiming) {
5455
+ console.log("[StormcloudVideoPlayer] VMAP mode enabled");
5456
+ }
5457
+ return [
5458
+ 2
5459
+ ];
5444
5460
  case 2:
5445
5461
  vastMode = this.config.vastMode || "default";
5446
5462
  if (this.config.debugAdTiming) {
@@ -5608,7 +5624,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5608
5624
  }
5609
5625
  return [];
5610
5626
  }
5611
- var adBreakNodes = Array.from(doc.querySelectorAll("AdBreak, vmap\\:AdBreak"));
5627
+ var VMAP_NS = "http://www.iab.net/videosuite/vmap";
5628
+ var adBreakNodes = Array.from(doc.getElementsByTagNameNS(VMAP_NS, "AdBreak"));
5629
+ if (adBreakNodes.length === 0) {
5630
+ adBreakNodes = Array.from(doc.querySelectorAll("AdBreak, vmap\\:AdBreak"));
5631
+ }
5632
+ if (adBreakNodes.length === 0) {
5633
+ adBreakNodes = Array.from(doc.getElementsByTagName("*")).filter(function(el) {
5634
+ return el.localName === "AdBreak";
5635
+ });
5636
+ }
5612
5637
  var parsed = [];
5613
5638
  adBreakNodes.forEach(function(node, index) {
5614
5639
  var timeOffsetRaw = (node.getAttribute("timeOffset") || "").trim();
@@ -5616,8 +5641,17 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5616
5641
  if (startTimeMs == null) {
5617
5642
  return;
5618
5643
  }
5619
- var adTagNode = node.querySelector("AdTagURI, vmap\\:AdTagURI");
5620
- var adTagUrl = ((adTagNode === null || adTagNode === void 0 ? void 0 : adTagNode.textContent) || "").trim();
5644
+ var adTagNode = node.getElementsByTagNameNS(VMAP_NS, "AdTagURI")[0];
5645
+ if (!adTagNode) {
5646
+ var _node_querySelector;
5647
+ adTagNode = (_node_querySelector = node.querySelector("AdTagURI, vmap\\:AdTagURI")) !== null && _node_querySelector !== void 0 ? _node_querySelector : void 0;
5648
+ }
5649
+ if (!adTagNode) {
5650
+ adTagNode = Array.from(node.getElementsByTagName("*")).find(function(el) {
5651
+ return el.localName === "AdTagURI";
5652
+ });
5653
+ }
5654
+ var adTagUrl = _this.resolveVmapAdTagUrl(((adTagNode === null || adTagNode === void 0 ? void 0 : adTagNode.textContent) || "").trim());
5621
5655
  if (!adTagUrl) {
5622
5656
  return;
5623
5657
  }
@@ -5636,6 +5670,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5636
5670
  return parsed;
5637
5671
  }
5638
5672
  },
5673
+ {
5674
+ key: "resolveVmapAdTagUrl",
5675
+ value: function resolveVmapAdTagUrl(url) {
5676
+ if (!url) {
5677
+ return "";
5678
+ }
5679
+ return url.replace(/\[timestamp\]/gi, String(Date.now())).replace(/\$\{GDPR\}/gi, "0").trim();
5680
+ }
5681
+ },
5639
5682
  {
5640
5683
  key: "parseVmapTimeOffsetToMs",
5641
5684
  value: function parseVmapTimeOffsetToMs(timeOffset) {
@@ -5658,6 +5701,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5658
5701
  var millis = Number(ms.padEnd(3, "0").slice(0, 3));
5659
5702
  return (hours * 3600 + minutes * 60 + seconds) * 1e3 + millis;
5660
5703
  }
5704
+ var msOnly = timeOffset.match(/^(\d{1,2}):(\d{2})(?:\.(\d{1,3}))?$/);
5705
+ if (msOnly) {
5706
+ var _msOnly = _sliced_to_array(msOnly, 4), mm1 = _msOnly[1], ss1 = _msOnly[2], tmp1 = _msOnly[3], ms1 = tmp1 === void 0 ? "0" : tmp1;
5707
+ var minutes1 = Number(mm1);
5708
+ var seconds1 = Number(ss1);
5709
+ var millis1 = Number(ms1.padEnd(3, "0").slice(0, 3));
5710
+ return (minutes1 * 60 + seconds1) * 1e3 + millis1;
5711
+ }
5661
5712
  var percent = timeOffset.match(/^(\d+(?:\.\d+)?)%$/);
5662
5713
  if (percent) {
5663
5714
  var ratio = Number(percent[1]) / 100;
@@ -7173,23 +7224,49 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7173
7224
  key: "onTimeUpdate",
7174
7225
  value: function onTimeUpdate(currentTimeSec) {
7175
7226
  var _this = this;
7227
+ if (!this.isVmapEnabled() || this.vmapBreaks.length === 0) {
7228
+ return;
7229
+ }
7176
7230
  if (this.ima.isAdPlaying() || this.inAdBreak) return;
7177
7231
  var nowMs = currentTimeSec * 1e3;
7178
7232
  var breakToPlay = this.findBreakForTime(nowMs);
7179
7233
  if (breakToPlay) {
7180
- void this.handleMidAdJoin(breakToPlay, nowMs).catch(function(error) {
7234
+ void this.handleVmapAdBreak(breakToPlay, nowMs).catch(function(error) {
7235
+ if (_this.config.debugAdTiming) {
7236
+ console.warn("[StormcloudVideoPlayer] VMAP ad break failed gracefully:", error);
7237
+ }
7238
+ });
7239
+ }
7240
+ }
7241
+ },
7242
+ {
7243
+ key: "onVideoEnded",
7244
+ value: function onVideoEnded() {
7245
+ var _this = this;
7246
+ if (!this.isVmapEnabled() || this.vmapBreaks.length === 0) {
7247
+ return;
7248
+ }
7249
+ if (this.ima.isAdPlaying() || this.inAdBreak) {
7250
+ return;
7251
+ }
7252
+ var durationMs = Number.isFinite(this.video.duration) ? Math.floor(this.video.duration * 1e3) : 0;
7253
+ var postroll = this.vmapBreaks.find(function(b) {
7254
+ return b.startTimeMs === -1 && !_this.consumedVmapBreakIds.has(_this.getAdBreakKey(b));
7255
+ });
7256
+ if (postroll) {
7257
+ void this.handleVmapAdBreak(postroll, durationMs).catch(function(error) {
7181
7258
  if (_this.config.debugAdTiming) {
7182
- console.warn("[StormcloudVideoPlayer] Mid-roll VMAP join failed gracefully:", error);
7259
+ console.warn("[StormcloudVideoPlayer] VMAP post-roll failed gracefully:", error);
7183
7260
  }
7184
7261
  });
7185
7262
  }
7186
7263
  }
7187
7264
  },
7188
7265
  {
7189
- key: "handleMidAdJoin",
7190
- value: function handleMidAdJoin(adBreak, nowMs) {
7266
+ key: "handleVmapAdBreak",
7267
+ value: function handleVmapAdBreak(adBreak, nowMs) {
7191
7268
  return _async_to_generator(function() {
7192
- var _adBreak_durationMs, _this_config_driftToleranceMs, key, breakStartMs, durationMs, endMs, tol, inWindow, remainingMs, tags, first, rest, error;
7269
+ var _adBreak_durationMs, key, breakStartMs, durationMs, endMs, inWindow, tags, first, rest, error;
7193
7270
  return _ts_generator(this, function(_state) {
7194
7271
  switch(_state.label){
7195
7272
  case 0:
@@ -7207,25 +7284,28 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7207
7284
  }
7208
7285
  durationMs = (_adBreak_durationMs = adBreak.durationMs) !== null && _adBreak_durationMs !== void 0 ? _adBreak_durationMs : 0;
7209
7286
  endMs = breakStartMs + durationMs;
7210
- tol = (_this_config_driftToleranceMs = this.config.driftToleranceMs) !== null && _this_config_driftToleranceMs !== void 0 ? _this_config_driftToleranceMs : 1e3;
7211
- inWindow = durationMs > 0 ? nowMs > breakStartMs && nowMs < endMs : nowMs + tol >= breakStartMs;
7287
+ inWindow = durationMs > 0 ? nowMs >= breakStartMs && nowMs < endMs : nowMs >= breakStartMs;
7212
7288
  if (!inWindow) return [
7213
7289
  3,
7214
7290
  4
7215
7291
  ];
7216
7292
  this.consumedVmapBreakIds.add(key);
7217
- remainingMs = durationMs > 0 ? Math.max(0, endMs - nowMs) : 0;
7218
- tags = this.selectVastTagsForBreak(adBreak) || (this.apiVastTagUrl ? [
7219
- this.apiVastTagUrl
7220
- ] : void 0);
7221
- if (!(tags && tags.length > 0)) return [
7222
- 3,
7223
- 4
7224
- ];
7293
+ tags = this.selectVastTagsForBreak(adBreak);
7294
+ if (!tags || tags.length === 0) {
7295
+ return [
7296
+ 2
7297
+ ];
7298
+ }
7225
7299
  first = tags[0];
7226
7300
  rest = tags.slice(1);
7227
7301
  this.adPodQueue = rest;
7228
7302
  this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
7303
+ this.showAds = true;
7304
+ this.inAdBreak = true;
7305
+ this.currentAdBreakStartWallClockMs = Date.now();
7306
+ if (!this.video.paused) {
7307
+ this.video.pause();
7308
+ }
7229
7309
  _state.label = 1;
7230
7310
  case 1:
7231
7311
  _state.trys.push([
@@ -7240,10 +7320,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7240
7320
  ];
7241
7321
  case 2:
7242
7322
  _state.sent();
7243
- this.inAdBreak = true;
7244
- this.expectedAdBreakDurationMs = remainingMs;
7245
- this.currentAdBreakStartWallClockMs = Date.now();
7246
- this.scheduleAdStopCountdown(remainingMs);
7247
7323
  return [
7248
7324
  3,
7249
7325
  4
@@ -7251,8 +7327,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7251
7327
  case 3:
7252
7328
  error = _state.sent();
7253
7329
  this.adPodQueue = [];
7330
+ this.inAdBreak = false;
7331
+ this.showAds = false;
7254
7332
  if (this.config.debugAdTiming) {
7255
- console.warn("[StormcloudVideoPlayer] Mid-roll VMAP ad request failed:", error);
7333
+ console.warn("[StormcloudVideoPlayer] VMAP ad request failed:", error);
7256
7334
  }
7257
7335
  return [
7258
7336
  3,
@@ -7923,16 +8001,18 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7923
8001
  {
7924
8002
  key: "selectVastTagsForBreak",
7925
8003
  value: function selectVastTagsForBreak(b) {
8004
+ var _this = this;
7926
8005
  if (!b || !b.vastTagUrl) return void 0;
7927
- if (b.vastTagUrl.includes(",")) {
7928
- return b.vastTagUrl.split(",").map(function(s) {
7929
- return s.trim();
8006
+ var resolvedUrl = this.resolveVmapAdTagUrl(b.vastTagUrl);
8007
+ if (resolvedUrl.includes(",")) {
8008
+ return resolvedUrl.split(",").map(function(s) {
8009
+ return _this.resolveVmapAdTagUrl(s.trim());
7930
8010
  }).filter(function(s) {
7931
8011
  return s.length > 0;
7932
8012
  });
7933
8013
  }
7934
8014
  return [
7935
- b.vastTagUrl
8015
+ resolvedUrl
7936
8016
  ];
7937
8017
  }
7938
8018
  },
@@ -7964,9 +8044,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7964
8044
  {
7965
8045
  key: "findBreakForTime",
7966
8046
  value: function findBreakForTime(nowMs) {
7967
- var _this_config_driftToleranceMs;
7968
8047
  var schedule = this.vmapBreaks;
7969
- var tol = (_this_config_driftToleranceMs = this.config.driftToleranceMs) !== null && _this_config_driftToleranceMs !== void 0 ? _this_config_driftToleranceMs : 1e3;
7970
8048
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
7971
8049
  try {
7972
8050
  for(var _iterator = schedule[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
@@ -7978,9 +8056,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
7978
8056
  if (breakStartMs == null) {
7979
8057
  continue;
7980
8058
  }
7981
- var end = breakStartMs + (b.durationMs || 0);
7982
- var effectiveTol = breakStartMs === 0 ? Math.max(tol, 3e4) : tol;
7983
- if (nowMs >= breakStartMs && (b.durationMs ? nowMs < end : nowMs <= breakStartMs + effectiveTol)) {
8059
+ if (b.durationMs) {
8060
+ var end = breakStartMs + b.durationMs;
8061
+ if (nowMs >= breakStartMs && nowMs < end) {
8062
+ return b;
8063
+ }
8064
+ continue;
8065
+ }
8066
+ if (nowMs >= breakStartMs) {
7984
8067
  return b;
7985
8068
  }
7986
8069
  }
@@ -8188,6 +8271,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8188
8271
  this.video.removeEventListener("timeupdate", this.timeUpdateHandler);
8189
8272
  delete this.timeUpdateHandler;
8190
8273
  }
8274
+ if (this.endedHandler) {
8275
+ this.video.removeEventListener("ended", this.endedHandler);
8276
+ delete this.endedHandler;
8277
+ }
8191
8278
  if (this.emptiedHandler) {
8192
8279
  this.video.removeEventListener("emptied", this.emptiedHandler);
8193
8280
  delete this.emptiedHandler;