stormcloud-video-player 0.6.2 → 0.6.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.
@@ -618,6 +618,7 @@ function createVastAdLayer(contentVideo, options) {
618
618
  var destroyed = false;
619
619
  var tornDown = false;
620
620
  var trackingFired = createEmptyTrackingState();
621
+ var adStallTimerId;
621
622
  var currentAdEventHandlers;
622
623
  var preloadSlots = /* @__PURE__ */ new Map();
623
624
  function emit(event, payload) {
@@ -733,7 +734,14 @@ function createVastAdLayer(contentVideo, options) {
733
734
  video.volume = 1;
734
735
  return video;
735
736
  }
737
+ function clearAdStallTimer() {
738
+ if (adStallTimerId != null) {
739
+ clearTimeout(adStallTimerId);
740
+ adStallTimerId = void 0;
741
+ }
742
+ }
736
743
  function removeAdEventListeners() {
744
+ clearAdStallTimer();
737
745
  if (!currentAdEventHandlers || !adVideoElement) return;
738
746
  var el = adVideoElement;
739
747
  el.removeEventListener("timeupdate", currentAdEventHandlers.timeupdate);
@@ -743,6 +751,7 @@ function createVastAdLayer(contentVideo, options) {
743
751
  el.removeEventListener("volumechange", currentAdEventHandlers.volumechange);
744
752
  el.removeEventListener("pause", currentAdEventHandlers.pause);
745
753
  el.removeEventListener("play", currentAdEventHandlers.play);
754
+ el.removeEventListener("waiting", currentAdEventHandlers.waiting);
746
755
  currentAdEventHandlers = void 0;
747
756
  }
748
757
  function setupAdEventListeners() {
@@ -767,6 +776,7 @@ function createVastAdLayer(contentVideo, options) {
767
776
  }
768
777
  },
769
778
  playing: function playing() {
779
+ clearAdStallTimer();
770
780
  var ad = currentAd;
771
781
  if (!ad || trackingFired.start) return;
772
782
  trackingFired.start = true;
@@ -803,6 +813,16 @@ function createVastAdLayer(contentVideo, options) {
803
813
  if (currentAd && adVideoElement && adVideoElement.currentTime > 0) {
804
814
  fireTrackingPixels2(currentAd.trackingUrls.resume);
805
815
  }
816
+ },
817
+ waiting: function waiting() {
818
+ clearAdStallTimer();
819
+ adStallTimerId = setTimeout(function() {
820
+ adStallTimerId = void 0;
821
+ if (adPlaying) {
822
+ if (debug) console.warn("".concat(LOG, " Ad video stalled for too long, treating as error"));
823
+ handleAdError();
824
+ }
825
+ }, 8e3);
806
826
  }
807
827
  };
808
828
  adVideoElement.addEventListener("timeupdate", handlers.timeupdate);
@@ -812,6 +832,7 @@ function createVastAdLayer(contentVideo, options) {
812
832
  adVideoElement.addEventListener("volumechange", handlers.volumechange);
813
833
  adVideoElement.addEventListener("pause", handlers.pause);
814
834
  adVideoElement.addEventListener("play", handlers.play);
835
+ adVideoElement.addEventListener("waiting", handlers.waiting);
815
836
  currentAdEventHandlers = handlers;
816
837
  }
817
838
  function setAdPlayingFlag(isPlaying) {
@@ -823,6 +844,7 @@ function createVastAdLayer(contentVideo, options) {
823
844
  }
824
845
  function handleAdComplete() {
825
846
  if (tornDown) return;
847
+ clearAdStallTimer();
826
848
  if (debug) console.log("".concat(LOG, " Handling ad completion"));
827
849
  adPlaying = false;
828
850
  setAdPlayingFlag(false);
@@ -836,6 +858,7 @@ function createVastAdLayer(contentVideo, options) {
836
858
  function handleAdError() {
837
859
  if (tornDown) return;
838
860
  if (!adPlaying) return;
861
+ clearAdStallTimer();
839
862
  if (debug) console.log("".concat(LOG, " Handling ad error"));
840
863
  adPlaying = false;
841
864
  setAdPlayingFlag(false);
@@ -886,6 +909,7 @@ function createVastAdLayer(contentVideo, options) {
886
909
  adHls.loadSource(mediaFile.url);
887
910
  adHls.attachMedia(adVideoElement);
888
911
  adHls.on(import_hls.default.Events.MANIFEST_PARSED, function() {
912
+ if (!adPlaying) return;
889
913
  adVideoElement.play().catch(function(error) {
890
914
  console.error("".concat(LOG, " Error starting HLS ad playback:"), error);
891
915
  handleAdError();
@@ -934,7 +958,7 @@ function createVastAdLayer(contentVideo, options) {
934
958
  }
935
959
  function playAd(bids) {
936
960
  return _async_to_generator(function() {
937
- var winner, ad, contentVolume, _contentVideo_parentElement, container, adVolume, mediaFile;
961
+ var winner, ad, contentVolume, adVolume2, mediaFile2, _contentVideo_parentElement, container, adVolume, mediaFile;
938
962
  return _ts_generator(this, function(_state) {
939
963
  switch(_state.label){
940
964
  case 0:
@@ -978,37 +1002,71 @@ function createVastAdLayer(contentVideo, options) {
978
1002
  trackingFired.impression = true;
979
1003
  contentVolume = contentVideo.volume;
980
1004
  originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
981
- if (singleElementMode) {
982
- mainHlsInstance === null || mainHlsInstance === void 0 ? void 0 : mainHlsInstance.detachMedia();
983
- teardownCurrentPlayback();
984
- adVideoElement = contentVideo;
985
- adHls = void 0;
1005
+ if (!singleElementMode) return [
1006
+ 3,
1007
+ 3
1008
+ ];
1009
+ mainHlsInstance === null || mainHlsInstance === void 0 ? void 0 : mainHlsInstance.detachMedia();
1010
+ teardownCurrentPlayback();
1011
+ adVideoElement = contentVideo;
1012
+ adHls = void 0;
1013
+ adPlaying = true;
1014
+ setAdPlayingFlag(true);
1015
+ contentVideo.removeAttribute("src");
1016
+ contentVideo.load();
1017
+ if (!continueLiveStreamDuringAds) {
1018
+ contentVideo.pause();
1019
+ }
1020
+ contentVideo.muted = true;
1021
+ contentVideo.volume = 0;
1022
+ return [
1023
+ 4,
1024
+ new Promise(function(resolve) {
1025
+ return setTimeout(resolve, 200);
1026
+ })
1027
+ ];
1028
+ case 2:
1029
+ _state.sent();
1030
+ if (destroyed || tornDown) return [
1031
+ 2
1032
+ ];
1033
+ contentVideo.style.visibility = "visible";
1034
+ contentVideo.style.opacity = "1";
1035
+ emit("content_pause");
1036
+ setupAdEventListeners();
1037
+ adVolume2 = originalMutedState ? 1 : originalVolume;
1038
+ adVideoElement.volume = Math.max(0, Math.min(1, adVolume2));
1039
+ adVideoElement.muted = false;
1040
+ mediaFile2 = selectBestMediaFile(ad.mediaFiles);
1041
+ if (debug) console.log("".concat(LOG, " Loading ad from: ").concat(mediaFile2.url));
1042
+ startPlayback(mediaFile2);
1043
+ return [
1044
+ 2
1045
+ ];
1046
+ case 3:
1047
+ if (!adContainerEl) {
1048
+ ;
1049
+ container = document.createElement("div");
1050
+ container.style.position = "absolute";
1051
+ container.style.left = "0";
1052
+ container.style.top = "0";
1053
+ container.style.right = "0";
1054
+ container.style.bottom = "0";
1055
+ container.style.display = "none";
1056
+ container.style.alignItems = "center";
1057
+ container.style.justifyContent = "center";
1058
+ container.style.pointerEvents = "none";
1059
+ container.style.zIndex = "10";
1060
+ container.style.backgroundColor = "#000";
1061
+ (_contentVideo_parentElement = contentVideo.parentElement) === null || _contentVideo_parentElement === void 0 ? void 0 : _contentVideo_parentElement.appendChild(container);
1062
+ adContainerEl = container;
1063
+ }
1064
+ if (!adVideoElement) {
1065
+ adVideoElement = createAdVideoElement();
1066
+ adContainerEl.appendChild(adVideoElement);
986
1067
  setupAdEventListeners();
987
1068
  } else {
988
- if (!adContainerEl) {
989
- ;
990
- container = document.createElement("div");
991
- container.style.position = "absolute";
992
- container.style.left = "0";
993
- container.style.top = "0";
994
- container.style.right = "0";
995
- container.style.bottom = "0";
996
- container.style.display = "none";
997
- container.style.alignItems = "center";
998
- container.style.justifyContent = "center";
999
- container.style.pointerEvents = "none";
1000
- container.style.zIndex = "10";
1001
- container.style.backgroundColor = "#000";
1002
- (_contentVideo_parentElement = contentVideo.parentElement) === null || _contentVideo_parentElement === void 0 ? void 0 : _contentVideo_parentElement.appendChild(container);
1003
- adContainerEl = container;
1004
- }
1005
- if (!adVideoElement) {
1006
- adVideoElement = createAdVideoElement();
1007
- adContainerEl.appendChild(adVideoElement);
1008
- setupAdEventListeners();
1009
- } else {
1010
- teardownCurrentPlayback();
1011
- }
1069
+ teardownCurrentPlayback();
1012
1070
  }
1013
1071
  if (!continueLiveStreamDuringAds) {
1014
1072
  contentVideo.pause();
@@ -1020,7 +1078,7 @@ function createVastAdLayer(contentVideo, options) {
1020
1078
  adVolume = originalMutedState ? 1 : originalVolume;
1021
1079
  adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
1022
1080
  adVideoElement.muted = false;
1023
- if (!singleElementMode && adContainerEl) {
1081
+ if (adContainerEl) {
1024
1082
  adContainerEl.style.display = "flex";
1025
1083
  adContainerEl.style.pointerEvents = "auto";
1026
1084
  }
@@ -1124,6 +1182,7 @@ function createVastAdLayer(contentVideo, options) {
1124
1182
  if (debug) console.log("".concat(LOG, " [preload] HLS manifest parsed, token=").concat(token));
1125
1183
  });
1126
1184
  hls.on(import_hls.default.Events.ERROR, function(_evt, data) {
1185
+ if (!preloadSlots.has(token)) return;
1127
1186
  if (data.fatal) {
1128
1187
  if (debug) console.warn("".concat(LOG, " [preload] HLS error for token=").concat(token));
1129
1188
  preloadSlots.delete(token);
@@ -1160,113 +1219,146 @@ function createVastAdLayer(contentVideo, options) {
1160
1219
  }
1161
1220
  function playPreloaded(token) {
1162
1221
  return _async_to_generator(function() {
1163
- var slot, contentVolume, adVolume2, videoEl, container2, adVolume21, adVolume, container;
1222
+ var slot, contentVolume, adVolume2, videoEl, container2, adVolume21, nonFatalNetworkErrors, adVolume, container;
1164
1223
  return _ts_generator(this, function(_state) {
1165
- if (destroyed) return [
1166
- 2,
1167
- Promise.reject(new Error("Layer has been destroyed"))
1168
- ];
1169
- slot = preloadSlots.get(token);
1170
- if (!slot) {
1171
- if (debug) console.warn("".concat(LOG, " [preload] No slot found for token=").concat(token, ", nothing to play"));
1172
- return [
1173
- 2
1174
- ];
1175
- }
1176
- preloadSlots.delete(token);
1177
- if (debug) console.log("".concat(LOG, " [preload] Playing preloaded ad, token=").concat(token, ", ready=").concat(slot.ready));
1178
- contentVolume = contentVideo.volume;
1179
- originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
1180
- sessionId = generateSessionId();
1181
- currentAd = slot.ad;
1182
- trackingFired = _object_spread({}, createEmptyTrackingState());
1183
- fireTrackingPixels2(slot.ad.trackingUrls.impression);
1184
- trackingFired.impression = true;
1185
- if (singleElementMode) {
1186
- mainHlsInstance === null || mainHlsInstance === void 0 ? void 0 : mainHlsInstance.detachMedia();
1187
- teardownCurrentPlayback();
1188
- adVideoElement = contentVideo;
1189
- adHls = void 0;
1190
- setupAdEventListeners();
1191
- if (!continueLiveStreamDuringAds) {
1192
- contentVideo.pause();
1193
- }
1194
- contentVideo.muted = true;
1195
- contentVideo.volume = 0;
1196
- adPlaying = true;
1197
- setAdPlayingFlag(true);
1198
- adVolume2 = originalMutedState ? 1 : originalVolume;
1199
- contentVideo.volume = Math.max(0, Math.min(1, adVolume2));
1200
- contentVideo.muted = false;
1201
- emit("content_pause");
1202
- if (debug) console.log("".concat(LOG, " [preload] singleElementMode: attaching ad to contentVideo, url=").concat(slot.mediaFile.url));
1203
- startPlayback(slot.mediaFile);
1204
- return [
1205
- 2
1206
- ];
1207
- }
1208
- if (smartTVMode && !slot.videoEl) {
1209
- teardownCurrentPlayback();
1210
- if (adVideoElement) {
1211
- adVideoElement.remove();
1212
- adVideoElement = void 0;
1213
- }
1214
- videoEl = createAdVideoElement();
1215
- videoEl.style.visibility = "visible";
1216
- videoEl.style.pointerEvents = "none";
1217
- container2 = ensureAdContainer();
1218
- container2.appendChild(videoEl);
1219
- adVideoElement = videoEl;
1220
- setupAdEventListeners();
1221
- if (!continueLiveStreamDuringAds) {
1222
- contentVideo.pause();
1223
- }
1224
- contentVideo.muted = true;
1225
- contentVideo.volume = 0;
1226
- adPlaying = true;
1227
- setAdPlayingFlag(true);
1228
- adVolume21 = originalMutedState ? 1 : originalVolume;
1229
- adVideoElement.volume = Math.max(0, Math.min(1, adVolume21));
1230
- adVideoElement.muted = false;
1231
- container2.style.display = "flex";
1232
- container2.style.pointerEvents = "auto";
1233
- emit("content_pause");
1234
- if (debug) console.log("".concat(LOG, " [preload] smartTVMode deferred: creating video element and loading, url=").concat(slot.mediaFile.url));
1235
- startPlayback(slot.mediaFile);
1236
- return [
1237
- 2
1238
- ];
1239
- }
1240
- teardownCurrentPlayback();
1241
- if (adVideoElement && adVideoElement !== slot.videoEl) {
1242
- adVideoElement.remove();
1243
- }
1244
- slot.videoEl.style.visibility = "visible";
1245
- slot.videoEl.style.pointerEvents = "none";
1246
- adVideoElement = slot.videoEl;
1247
- adHls = slot.hlsInstance;
1248
- setupAdEventListeners();
1249
- if (!continueLiveStreamDuringAds) {
1250
- contentVideo.pause();
1224
+ switch(_state.label){
1225
+ case 0:
1226
+ if (destroyed) return [
1227
+ 2,
1228
+ Promise.reject(new Error("Layer has been destroyed"))
1229
+ ];
1230
+ slot = preloadSlots.get(token);
1231
+ if (!slot) {
1232
+ if (debug) console.warn("".concat(LOG, " [preload] No slot found for token=").concat(token, ", nothing to play"));
1233
+ return [
1234
+ 2
1235
+ ];
1236
+ }
1237
+ preloadSlots.delete(token);
1238
+ if (debug) console.log("".concat(LOG, " [preload] Playing preloaded ad, token=").concat(token, ", ready=").concat(slot.ready));
1239
+ contentVolume = contentVideo.volume;
1240
+ originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
1241
+ sessionId = generateSessionId();
1242
+ currentAd = slot.ad;
1243
+ trackingFired = _object_spread({}, createEmptyTrackingState());
1244
+ fireTrackingPixels2(slot.ad.trackingUrls.impression);
1245
+ trackingFired.impression = true;
1246
+ if (!singleElementMode) return [
1247
+ 3,
1248
+ 2
1249
+ ];
1250
+ mainHlsInstance === null || mainHlsInstance === void 0 ? void 0 : mainHlsInstance.detachMedia();
1251
+ teardownCurrentPlayback();
1252
+ adVideoElement = contentVideo;
1253
+ adHls = void 0;
1254
+ adPlaying = true;
1255
+ setAdPlayingFlag(true);
1256
+ contentVideo.removeAttribute("src");
1257
+ contentVideo.load();
1258
+ contentVideo.muted = true;
1259
+ contentVideo.volume = 0;
1260
+ return [
1261
+ 4,
1262
+ new Promise(function(resolve) {
1263
+ return setTimeout(resolve, 200);
1264
+ })
1265
+ ];
1266
+ case 1:
1267
+ _state.sent();
1268
+ if (destroyed || tornDown) return [
1269
+ 2
1270
+ ];
1271
+ contentVideo.style.visibility = "visible";
1272
+ contentVideo.style.opacity = "1";
1273
+ emit("content_pause");
1274
+ setupAdEventListeners();
1275
+ adVolume2 = originalMutedState ? 1 : originalVolume;
1276
+ contentVideo.volume = Math.max(0, Math.min(1, adVolume2));
1277
+ contentVideo.muted = false;
1278
+ if (debug) console.log("".concat(LOG, " [preload] singleElementMode: attaching ad to contentVideo, url=").concat(slot.mediaFile.url));
1279
+ startPlayback(slot.mediaFile);
1280
+ return [
1281
+ 2
1282
+ ];
1283
+ case 2:
1284
+ if (smartTVMode && !slot.videoEl) {
1285
+ teardownCurrentPlayback();
1286
+ if (adVideoElement) {
1287
+ adVideoElement.remove();
1288
+ adVideoElement = void 0;
1289
+ }
1290
+ videoEl = createAdVideoElement();
1291
+ videoEl.style.visibility = "visible";
1292
+ videoEl.style.pointerEvents = "none";
1293
+ container2 = ensureAdContainer();
1294
+ container2.appendChild(videoEl);
1295
+ adVideoElement = videoEl;
1296
+ setupAdEventListeners();
1297
+ if (!continueLiveStreamDuringAds) {
1298
+ contentVideo.pause();
1299
+ }
1300
+ contentVideo.muted = true;
1301
+ contentVideo.volume = 0;
1302
+ adPlaying = true;
1303
+ setAdPlayingFlag(true);
1304
+ adVolume21 = originalMutedState ? 1 : originalVolume;
1305
+ adVideoElement.volume = Math.max(0, Math.min(1, adVolume21));
1306
+ adVideoElement.muted = false;
1307
+ container2.style.display = "flex";
1308
+ container2.style.pointerEvents = "auto";
1309
+ emit("content_pause");
1310
+ if (debug) console.log("".concat(LOG, " [preload] smartTVMode deferred: creating video element and loading, url=").concat(slot.mediaFile.url));
1311
+ startPlayback(slot.mediaFile);
1312
+ return [
1313
+ 2
1314
+ ];
1315
+ }
1316
+ teardownCurrentPlayback();
1317
+ if (adVideoElement && adVideoElement !== slot.videoEl) {
1318
+ adVideoElement.remove();
1319
+ }
1320
+ slot.videoEl.style.visibility = "visible";
1321
+ slot.videoEl.style.pointerEvents = "none";
1322
+ adVideoElement = slot.videoEl;
1323
+ adHls = slot.hlsInstance;
1324
+ if (adHls) {
1325
+ nonFatalNetworkErrors = 0;
1326
+ adHls.on(import_hls.default.Events.ERROR, function(_event, data) {
1327
+ if (!adPlaying) return;
1328
+ if (data.fatal) {
1329
+ handleAdError();
1330
+ } else if (data.type === import_hls.default.ErrorTypes.NETWORK_ERROR) {
1331
+ nonFatalNetworkErrors++;
1332
+ if (nonFatalNetworkErrors >= 3) {
1333
+ if (debug) console.warn("".concat(LOG, " [preload] Too many non-fatal HLS network errors during playback, treating as fatal"));
1334
+ handleAdError();
1335
+ }
1336
+ }
1337
+ });
1338
+ }
1339
+ setupAdEventListeners();
1340
+ if (!continueLiveStreamDuringAds) {
1341
+ contentVideo.pause();
1342
+ }
1343
+ contentVideo.muted = true;
1344
+ contentVideo.volume = 0;
1345
+ adPlaying = true;
1346
+ setAdPlayingFlag(true);
1347
+ adVolume = originalMutedState ? 1 : originalVolume;
1348
+ adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
1349
+ adVideoElement.muted = false;
1350
+ container = ensureAdContainer();
1351
+ container.style.display = "flex";
1352
+ container.style.pointerEvents = "auto";
1353
+ emit("content_pause");
1354
+ adVideoElement.play().catch(function(error) {
1355
+ console.error("".concat(LOG, " [preload] Error playing preloaded ad:"), error);
1356
+ handleAdError();
1357
+ });
1358
+ return [
1359
+ 2
1360
+ ];
1251
1361
  }
1252
- contentVideo.muted = true;
1253
- contentVideo.volume = 0;
1254
- adPlaying = true;
1255
- setAdPlayingFlag(true);
1256
- adVolume = originalMutedState ? 1 : originalVolume;
1257
- adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
1258
- adVideoElement.muted = false;
1259
- container = ensureAdContainer();
1260
- container.style.display = "flex";
1261
- container.style.pointerEvents = "auto";
1262
- emit("content_pause");
1263
- adVideoElement.play().catch(function(error) {
1264
- console.error("".concat(LOG, " [preload] Error playing preloaded ad:"), error);
1265
- handleAdError();
1266
- });
1267
- return [
1268
- 2
1269
- ];
1270
1362
  });
1271
1363
  })();
1272
1364
  }
@@ -1451,6 +1543,7 @@ function createVastAdLayer(contentVideo, options) {
1451
1543
  return 1;
1452
1544
  },
1453
1545
  showPlaceholder: function showPlaceholder() {
1546
+ if (singleElementMode) return;
1454
1547
  contentVideo.style.opacity = "0";
1455
1548
  contentVideo.style.visibility = "hidden";
1456
1549
  if (!adContainerEl) {