stormcloud-video-player 0.3.67 → 0.3.68

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.d.cts CHANGED
@@ -233,9 +233,13 @@ declare class StormcloudVideoPlayer {
233
233
  private preloadPoolLoopRunning;
234
234
  private adDetectSentForCurrentBreak;
235
235
  private preAdBreakAudio;
236
+ private detectedLowLatencyStream;
237
+ private latencyProfileApplied;
236
238
  constructor(config: StormcloudVideoPlayerConfig);
237
239
  private createAdPlayer;
238
240
  load(): Promise<void>;
241
+ private applyStreamLatencyProfile;
242
+ private isLowLatencyManifest;
239
243
  private attachImaEventListeners;
240
244
  private recreateImaController;
241
245
  private ensurePlaceholderContainer;
@@ -306,6 +310,7 @@ declare class StormcloudVideoPlayer {
306
310
  isShowingAds(): boolean;
307
311
  getStreamType(): "hls" | "other";
308
312
  shouldShowNativeControls(): boolean;
313
+ isLowLatencyStream(): boolean | undefined;
309
314
  private shouldContinueLiveStreamDuringAds;
310
315
  private startAdPrefetch;
311
316
  private clearPendingAdBreak;
package/lib/index.d.ts CHANGED
@@ -233,9 +233,13 @@ declare class StormcloudVideoPlayer {
233
233
  private preloadPoolLoopRunning;
234
234
  private adDetectSentForCurrentBreak;
235
235
  private preAdBreakAudio;
236
+ private detectedLowLatencyStream;
237
+ private latencyProfileApplied;
236
238
  constructor(config: StormcloudVideoPlayerConfig);
237
239
  private createAdPlayer;
238
240
  load(): Promise<void>;
241
+ private applyStreamLatencyProfile;
242
+ private isLowLatencyManifest;
239
243
  private attachImaEventListeners;
240
244
  private recreateImaController;
241
245
  private ensurePlaceholderContainer;
@@ -306,6 +310,7 @@ declare class StormcloudVideoPlayer {
306
310
  isShowingAds(): boolean;
307
311
  getStreamType(): "hls" | "other";
308
312
  shouldShowNativeControls(): boolean;
313
+ isLowLatencyStream(): boolean | undefined;
309
314
  private shouldContinueLiveStreamDuringAds;
310
315
  private startAdPrefetch;
311
316
  private clearPendingAdBreak;
package/lib/index.js CHANGED
@@ -1782,7 +1782,7 @@ function createHlsAdPlayer(contentVideo, options) {
1782
1782
  }
1783
1783
  var adElement = xmlDoc.querySelector("Ad");
1784
1784
  if (!adElement) {
1785
- console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
1785
+ console.warn("[HlsAdPlayer] No Ad element found in VAST XML (no fill). Content (first 2000 chars):", xmlString.substring(0, 2e3));
1786
1786
  return null;
1787
1787
  }
1788
1788
  var adId = adElement.getAttribute("id") || "unknown";
@@ -1878,7 +1878,7 @@ function createHlsAdPlayer(contentVideo, options) {
1878
1878
  }
1879
1879
  function fetchAndParseVastAd(vastTagUrl) {
1880
1880
  return _async_to_generator(function() {
1881
- var response, vastXml;
1881
+ var response, vastXml, trimmedXml;
1882
1882
  return _ts_generator(this, function(_state) {
1883
1883
  switch(_state.label){
1884
1884
  case 0:
@@ -1904,8 +1904,16 @@ function createHlsAdPlayer(contentVideo, options) {
1904
1904
  ];
1905
1905
  case 2:
1906
1906
  vastXml = _state.sent();
1907
- console.log("[HlsAdPlayer] VAST XML received");
1907
+ console.log("[HlsAdPlayer] VAST XML received (length=".concat(vastXml.length, ")"));
1908
1908
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
1909
+ trimmedXml = vastXml.trim();
1910
+ if (trimmedXml.length === 0) {
1911
+ console.warn("[HlsAdPlayer] VAST response body is empty (no fill)");
1912
+ return [
1913
+ 2,
1914
+ null
1915
+ ];
1916
+ }
1909
1917
  return [
1910
1918
  2,
1911
1919
  parseVastXml(vastXml)
@@ -3369,6 +3377,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3369
3377
  this.preloadPoolActive = false;
3370
3378
  this.preloadPoolLoopRunning = false;
3371
3379
  this.adDetectSentForCurrentBreak = false;
3380
+ this.latencyProfileApplied = false;
3372
3381
  this.continuousFetchLoopRunning = false;
3373
3382
  initializePolyfills();
3374
3383
  var browserOverrides = getBrowserConfigOverrides();
@@ -3485,24 +3494,21 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3485
3494
  2
3486
3495
  ];
3487
3496
  case 7:
3488
- this.hls = new Hls2(_object_spread_props(_object_spread({
3497
+ this.hls = new Hls2({
3489
3498
  enableWorker: true,
3490
3499
  backBufferLength: 30,
3491
3500
  liveDurationInfinity: true,
3492
3501
  lowLatencyMode: !!this.config.lowLatencyMode,
3493
- maxLiveSyncPlaybackRate: this.config.lowLatencyMode ? 1.5 : 1
3494
- }, this.config.lowLatencyMode ? {
3495
- liveSyncDuration: 2
3496
- } : {}), {
3502
+ maxLiveSyncPlaybackRate: 1.1,
3497
3503
  maxBufferLength: 30,
3498
3504
  maxMaxBufferLength: 600,
3499
3505
  maxBufferSize: 60 * 1e3 * 1e3,
3500
- maxBufferHole: 0.5,
3506
+ maxBufferHole: 1,
3501
3507
  highBufferWatchdogPeriod: 2,
3502
- nudgeOffset: 0.1,
3503
- nudgeMaxRetry: 3,
3508
+ nudgeOffset: 0.2,
3509
+ nudgeMaxRetry: 5,
3504
3510
  startPosition: -1
3505
- }));
3511
+ });
3506
3512
  this.hls.on(Hls2.Events.MEDIA_ATTACHED, function() {
3507
3513
  var _this_hls;
3508
3514
  (_this_hls = _this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.loadSource(_this.config.src);
@@ -3546,6 +3552,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3546
3552
  this.bufferedSegmentsCount = 0;
3547
3553
  this.hasInitialBufferCompleted = false;
3548
3554
  this.shouldAutoplayAfterBuffering = !!this.config.autoplay;
3555
+ this.latencyProfileApplied = false;
3556
+ this.detectedLowLatencyStream = void 0;
3549
3557
  minSegments = (_this_config_minSegmentsBeforePlay = this.config.minSegmentsBeforePlay) !== null && _this_config_minSegmentsBeforePlay !== void 0 ? _this_config_minSegmentsBeforePlay : 2;
3550
3558
  if (this.config.debugAdTiming) {
3551
3559
  console.log("[StormcloudVideoPlayer] Waiting for", minSegments, "segments to buffer before playback");
@@ -3575,6 +3583,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3575
3583
  }).call(_this);
3576
3584
  });
3577
3585
  this.hls.on(Hls2.Events.LEVEL_LOADED, function(_evt, data) {
3586
+ _this.applyStreamLatencyProfile(data === null || data === void 0 ? void 0 : data.details);
3578
3587
  if (_this.inAdBreak || _this.pendingAdBreak) {
3579
3588
  return;
3580
3589
  }
@@ -3854,6 +3863,64 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3854
3863
  }).call(this);
3855
3864
  }
3856
3865
  },
3866
+ {
3867
+ key: "applyStreamLatencyProfile",
3868
+ value: function applyStreamLatencyProfile(details) {
3869
+ if (this.latencyProfileApplied || !this.hls) {
3870
+ return;
3871
+ }
3872
+ if (!details) {
3873
+ return;
3874
+ }
3875
+ if (details.live !== true) {
3876
+ this.latencyProfileApplied = true;
3877
+ this.detectedLowLatencyStream = false;
3878
+ return;
3879
+ }
3880
+ var isLowLatencyManifest = this.isLowLatencyManifest(details);
3881
+ var useLowLatency = isLowLatencyManifest && !!this.config.lowLatencyMode;
3882
+ this.detectedLowLatencyStream = useLowLatency;
3883
+ this.latencyProfileApplied = true;
3884
+ var cfg = this.hls.config;
3885
+ if (useLowLatency) {
3886
+ cfg.maxLiveSyncPlaybackRate = 1.5;
3887
+ cfg.maxBufferHole = 0.5;
3888
+ delete cfg.liveSyncDuration;
3889
+ } else {
3890
+ cfg.maxLiveSyncPlaybackRate = 1.1;
3891
+ cfg.maxBufferHole = 1;
3892
+ delete cfg.liveSyncDuration;
3893
+ cfg.liveSyncDurationCount = 3;
3894
+ }
3895
+ if (this.config.debugAdTiming) {
3896
+ var _details_targetduration;
3897
+ console.log("[StormcloudVideoPlayer] Live latency profile: ".concat(useLowLatency ? "LL-HLS (low latency)" : "standard live (stability)"), {
3898
+ isLowLatencyManifest: isLowLatencyManifest,
3899
+ lowLatencyModeRequested: !!this.config.lowLatencyMode,
3900
+ canBlockReload: details.canBlockReload,
3901
+ partTarget: details.partTarget,
3902
+ partHoldBack: details.partHoldBack,
3903
+ partListLength: Array.isArray(details.partList) ? details.partList.length : 0,
3904
+ targetDuration: (_details_targetduration = details.targetduration) !== null && _details_targetduration !== void 0 ? _details_targetduration : details.targetDuration,
3905
+ maxLiveSyncPlaybackRate: cfg.maxLiveSyncPlaybackRate,
3906
+ maxBufferHole: cfg.maxBufferHole
3907
+ });
3908
+ }
3909
+ }
3910
+ },
3911
+ {
3912
+ key: "isLowLatencyManifest",
3913
+ value: function isLowLatencyManifest(details) {
3914
+ if (!details) {
3915
+ return false;
3916
+ }
3917
+ var hasParts = Array.isArray(details.partList) && details.partList.length > 0;
3918
+ var hasPartTarget = typeof details.partTarget === "number" && details.partTarget > 0;
3919
+ var hasPartHoldBack = typeof details.partHoldBack === "number" && details.partHoldBack > 0;
3920
+ var canBlockReload = details.canBlockReload === true;
3921
+ return hasParts || hasPartTarget || hasPartHoldBack || canBlockReload;
3922
+ }
3923
+ },
3857
3924
  {
3858
3925
  key: "attachImaEventListeners",
3859
3926
  value: function attachImaEventListeners() {
@@ -5842,6 +5909,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5842
5909
  return !!(this.config.allowNativeHls && !((_this_config_showCustomControls = this.config.showCustomControls) !== null && _this_config_showCustomControls !== void 0 ? _this_config_showCustomControls : false));
5843
5910
  }
5844
5911
  },
5912
+ {
5913
+ key: "isLowLatencyStream",
5914
+ value: function isLowLatencyStream() {
5915
+ return this.detectedLowLatencyStream;
5916
+ }
5917
+ },
5845
5918
  {
5846
5919
  key: "shouldContinueLiveStreamDuringAds",
5847
5920
  value: function shouldContinueLiveStreamDuringAds() {