stormcloud-video-player 0.8.48 → 0.8.49

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 { a as StormcloudVideoPlayerConfig } from '../types-cTqIKw_D.cjs';
2
+ import { S as StormcloudVideoPlayerConfig } from '../types-iDjS8f_7.cjs';
3
3
 
4
4
  interface HlsPlayerProps extends StormcloudVideoPlayerConfig {
5
5
  onMount?: (player: any) => void;
@@ -461,9 +461,11 @@ function createHlsAdPlayer(contentVideo, options) {
461
461
  var pendingTimeouts = [];
462
462
  var STALL_TIMEOUT_MS = 4e3;
463
463
  var STALL_CHECK_INTERVAL_MS = 1e3;
464
+ var BLACKFRAME_MIN_PLAYBACK_S = 1.5;
464
465
  var stallWatchdogId;
465
466
  var lastAdProgressTime = 0;
466
467
  var lastAdProgressPosition = 0;
468
+ var sawDecodedVideoFrame = false;
467
469
  var trackingFired = {
468
470
  impression: false,
469
471
  start: false,
@@ -644,6 +646,11 @@ function createHlsAdPlayer(contentVideo, options) {
644
646
  console.warn("[HlsAdPlayer] MediaFile ".concat(index, ' skipped (audio-only, type="').concat(type, '") — audio ads are not played to avoid a black screen'));
645
647
  return;
646
648
  }
649
+ var hasExplicitDimensions = mf.getAttribute("width") != null && mf.getAttribute("height") != null;
650
+ if (!isHlsMediaFile(mediaFile) && hasExplicitDimensions && (mediaFile.width <= 1 || mediaFile.height <= 1)) {
651
+ console.warn("[HlsAdPlayer] MediaFile ".concat(index, " skipped (degenerate dimensions ").concat(mediaFile.width, "x").concat(mediaFile.height, ', type="').concat(type, '") — likely an audio-only placeholder rendition'));
652
+ return;
653
+ }
647
654
  if (isHlsMediaFile(mediaFile) || isProgressiveMediaFile(mediaFile)) {
648
655
  mediaFiles.push(mediaFile);
649
656
  if (verbose) {
@@ -1111,6 +1118,14 @@ function createHlsAdPlayer(contentVideo, options) {
1111
1118
  fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);
1112
1119
  }
1113
1120
  };
1121
+ var onLoadedMetadata = function onLoadedMetadata() {
1122
+ if (!adPlaying || !adVideoElement) return;
1123
+ var videoWidth = adVideoElement.videoWidth, videoHeight = adVideoElement.videoHeight;
1124
+ if (videoWidth <= 1 || videoHeight <= 1) {
1125
+ console.warn("[HlsAdPlayer] Ad creative has no usable video dimensions (".concat(videoWidth, "x").concat(videoHeight, ") - skipping this creative"));
1126
+ handleVideoDecodeFailure();
1127
+ }
1128
+ };
1114
1129
  var onPlaying = function onPlaying() {
1115
1130
  startStallWatchdog();
1116
1131
  if (!currentAd || trackingFired.start) return;
@@ -1162,6 +1177,10 @@ function createHlsAdPlayer(contentVideo, options) {
1162
1177
  type: "timeupdate",
1163
1178
  handler: onTimeUpdate
1164
1179
  },
1180
+ {
1181
+ type: "loadedmetadata",
1182
+ handler: onLoadedMetadata
1183
+ },
1165
1184
  {
1166
1185
  type: "playing",
1167
1186
  handler: onPlaying
@@ -1351,13 +1370,51 @@ function createHlsAdPlayer(contentVideo, options) {
1351
1370
  }
1352
1371
  handleAdError();
1353
1372
  }
1373
+ function getDecodedVideoFrameCount(video) {
1374
+ try {
1375
+ if (typeof video.getVideoPlaybackQuality === "function") {
1376
+ var quality = video.getVideoPlaybackQuality();
1377
+ if (quality && typeof quality.totalVideoFrames === "number") {
1378
+ return quality.totalVideoFrames;
1379
+ }
1380
+ }
1381
+ var legacyCount = video.webkitDecodedFrameCount;
1382
+ if (typeof legacyCount === "number") {
1383
+ return legacyCount;
1384
+ }
1385
+ } catch (error) {
1386
+ console.warn("[HlsAdPlayer] Unable to read decoded video frame count:", error);
1387
+ }
1388
+ return void 0;
1389
+ }
1390
+ function handleVideoDecodeFailure() {
1391
+ console.warn("[HlsAdPlayer] Ad audio is advancing but no video frames decoded (black screen) - skipping this creative");
1392
+ clearStallWatchdog();
1393
+ if (currentAd) {
1394
+ fireTrackingPixels(currentAd.trackingUrls.error);
1395
+ }
1396
+ if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {
1397
+ return;
1398
+ }
1399
+ handleAdError();
1400
+ }
1354
1401
  function startStallWatchdog() {
1355
1402
  clearStallWatchdog();
1356
1403
  noteAdProgress();
1404
+ sawDecodedVideoFrame = false;
1357
1405
  stallWatchdogId = window.setInterval(function() {
1358
1406
  if (!adPlaying || !adVideoElement) {
1359
1407
  return;
1360
1408
  }
1409
+ if (!sawDecodedVideoFrame && !adVideoElement.paused) {
1410
+ var decodedFrames = getDecodedVideoFrameCount(adVideoElement);
1411
+ if (decodedFrames !== void 0 && decodedFrames > 0) {
1412
+ sawDecodedVideoFrame = true;
1413
+ } else if (decodedFrames === 0 && adVideoElement.currentTime >= BLACKFRAME_MIN_PLAYBACK_S) {
1414
+ handleVideoDecodeFailure();
1415
+ return;
1416
+ }
1417
+ }
1361
1418
  if (adVideoElement.currentTime > lastAdProgressPosition + 0.05) {
1362
1419
  noteAdProgress();
1363
1420
  return;