stormcloud-video-player 0.6.1 → 0.6.3

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.
@@ -599,7 +599,7 @@ function resolveBidToVastAd(winner, logPrefix) {
599
599
  return Promise.resolve(null);
600
600
  }
601
601
  function createVastAdLayer(contentVideo, options) {
602
- var _ref, _ref1, _ref2, _ref3;
602
+ var _ref, _ref1, _ref2, _ref3, _ref4;
603
603
  var adPlaying = false;
604
604
  var originalMutedState = false;
605
605
  var originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));
@@ -608,7 +608,8 @@ function createVastAdLayer(contentVideo, options) {
608
608
  var continueLiveStreamDuringAds = (_ref = options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) !== null && _ref !== void 0 ? _ref : false;
609
609
  var smartTVMode = (_ref1 = options === null || options === void 0 ? void 0 : options.smartTVMode) !== null && _ref1 !== void 0 ? _ref1 : false;
610
610
  var singleElementMode = (_ref2 = options === null || options === void 0 ? void 0 : options.singleElementMode) !== null && _ref2 !== void 0 ? _ref2 : false;
611
- var debug = (_ref3 = options === null || options === void 0 ? void 0 : options.debug) !== null && _ref3 !== void 0 ? _ref3 : false;
611
+ var forceMP4Ads = (_ref3 = options === null || options === void 0 ? void 0 : options.forceMP4Ads) !== null && _ref3 !== void 0 ? _ref3 : smartTVMode || singleElementMode;
612
+ var debug = (_ref4 = options === null || options === void 0 ? void 0 : options.debug) !== null && _ref4 !== void 0 ? _ref4 : false;
612
613
  var adVideoElement;
613
614
  var adHls;
614
615
  var adContainerEl;
@@ -679,14 +680,26 @@ function createVastAdLayer(contentVideo, options) {
679
680
  var _ref;
680
681
  var _scoredFiles_;
681
682
  if (mediaFiles.length === 0) throw new Error("No media files available");
682
- var firstFile = mediaFiles[0];
683
- if (mediaFiles.length === 1) return firstFile;
683
+ var candidates = mediaFiles;
684
+ if (forceMP4Ads) {
685
+ var mp4Only = candidates.filter(function(f) {
686
+ return !isHlsMediaFile(f);
687
+ });
688
+ if (mp4Only.length > 0) {
689
+ candidates = mp4Only;
690
+ if (debug) console.log("".concat(LOG, " forceMP4Ads: filtered to ").concat(mp4Only.length, " MP4-only file(s)"));
691
+ } else if (debug) {
692
+ console.warn("".concat(LOG, " forceMP4Ads: no MP4 files available, falling back to all media files"));
693
+ }
694
+ }
695
+ var firstFile = candidates[0];
696
+ if (candidates.length === 1) return firstFile;
684
697
  var mainQuality = getMainStreamQuality();
685
698
  if (!mainQuality) {
686
699
  if (debug) console.log("".concat(LOG, " No main stream quality info, using first media file"));
687
700
  return firstFile;
688
701
  }
689
- var scoredFiles = mediaFiles.map(function(file) {
702
+ var scoredFiles = candidates.map(function(file) {
690
703
  var widthDiff = Math.abs(file.width - mainQuality.width);
691
704
  var heightDiff = Math.abs(file.height - mainQuality.height);
692
705
  var resolutionDiff = widthDiff + heightDiff;
@@ -903,6 +916,16 @@ function createVastAdLayer(contentVideo, options) {
903
916
  }
904
917
  function startPlayback(mediaFile) {
905
918
  if (!adVideoElement) return;
919
+ if (singleElementMode && isHlsMediaFile(mediaFile)) {
920
+ var mp4Fallback = currentAd === null || currentAd === void 0 ? void 0 : currentAd.mediaFiles.find(function(f) {
921
+ return !isHlsMediaFile(f);
922
+ });
923
+ if (mp4Fallback) {
924
+ if (debug) console.log("".concat(LOG, " singleElementMode: HLS ad blocked, using MP4 fallback"));
925
+ startNativePlayback(mp4Fallback);
926
+ return;
927
+ }
928
+ }
906
929
  if (isHlsMediaFile(mediaFile)) {
907
930
  startHlsPlayback(mediaFile);
908
931
  } else {
@@ -911,7 +934,7 @@ function createVastAdLayer(contentVideo, options) {
911
934
  }
912
935
  function playAd(bids) {
913
936
  return _async_to_generator(function() {
914
- var winner, ad, contentVolume, _contentVideo_parentElement, container, adVolume, mediaFile;
937
+ var winner, ad, contentVolume, adVolume2, mediaFile2, _contentVideo_parentElement, container, adVolume, mediaFile;
915
938
  return _ts_generator(this, function(_state) {
916
939
  switch(_state.label){
917
940
  case 0:
@@ -955,37 +978,71 @@ function createVastAdLayer(contentVideo, options) {
955
978
  trackingFired.impression = true;
956
979
  contentVolume = contentVideo.volume;
957
980
  originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
958
- if (singleElementMode) {
959
- mainHlsInstance === null || mainHlsInstance === void 0 ? void 0 : mainHlsInstance.detachMedia();
960
- teardownCurrentPlayback();
961
- adVideoElement = contentVideo;
962
- adHls = void 0;
981
+ if (!singleElementMode) return [
982
+ 3,
983
+ 3
984
+ ];
985
+ mainHlsInstance === null || mainHlsInstance === void 0 ? void 0 : mainHlsInstance.detachMedia();
986
+ teardownCurrentPlayback();
987
+ adVideoElement = contentVideo;
988
+ adHls = void 0;
989
+ adPlaying = true;
990
+ setAdPlayingFlag(true);
991
+ contentVideo.removeAttribute("src");
992
+ contentVideo.load();
993
+ if (!continueLiveStreamDuringAds) {
994
+ contentVideo.pause();
995
+ }
996
+ contentVideo.muted = true;
997
+ contentVideo.volume = 0;
998
+ return [
999
+ 4,
1000
+ new Promise(function(resolve) {
1001
+ return setTimeout(resolve, 200);
1002
+ })
1003
+ ];
1004
+ case 2:
1005
+ _state.sent();
1006
+ if (destroyed || tornDown) return [
1007
+ 2
1008
+ ];
1009
+ contentVideo.style.visibility = "visible";
1010
+ contentVideo.style.opacity = "1";
1011
+ emit("content_pause");
1012
+ setupAdEventListeners();
1013
+ adVolume2 = originalMutedState ? 1 : originalVolume;
1014
+ adVideoElement.volume = Math.max(0, Math.min(1, adVolume2));
1015
+ adVideoElement.muted = false;
1016
+ mediaFile2 = selectBestMediaFile(ad.mediaFiles);
1017
+ if (debug) console.log("".concat(LOG, " Loading ad from: ").concat(mediaFile2.url));
1018
+ startPlayback(mediaFile2);
1019
+ return [
1020
+ 2
1021
+ ];
1022
+ case 3:
1023
+ if (!adContainerEl) {
1024
+ ;
1025
+ container = document.createElement("div");
1026
+ container.style.position = "absolute";
1027
+ container.style.left = "0";
1028
+ container.style.top = "0";
1029
+ container.style.right = "0";
1030
+ container.style.bottom = "0";
1031
+ container.style.display = "none";
1032
+ container.style.alignItems = "center";
1033
+ container.style.justifyContent = "center";
1034
+ container.style.pointerEvents = "none";
1035
+ container.style.zIndex = "10";
1036
+ container.style.backgroundColor = "#000";
1037
+ (_contentVideo_parentElement = contentVideo.parentElement) === null || _contentVideo_parentElement === void 0 ? void 0 : _contentVideo_parentElement.appendChild(container);
1038
+ adContainerEl = container;
1039
+ }
1040
+ if (!adVideoElement) {
1041
+ adVideoElement = createAdVideoElement();
1042
+ adContainerEl.appendChild(adVideoElement);
963
1043
  setupAdEventListeners();
964
1044
  } else {
965
- if (!adContainerEl) {
966
- ;
967
- container = document.createElement("div");
968
- container.style.position = "absolute";
969
- container.style.left = "0";
970
- container.style.top = "0";
971
- container.style.right = "0";
972
- container.style.bottom = "0";
973
- container.style.display = "none";
974
- container.style.alignItems = "center";
975
- container.style.justifyContent = "center";
976
- container.style.pointerEvents = "none";
977
- container.style.zIndex = "10";
978
- container.style.backgroundColor = "#000";
979
- (_contentVideo_parentElement = contentVideo.parentElement) === null || _contentVideo_parentElement === void 0 ? void 0 : _contentVideo_parentElement.appendChild(container);
980
- adContainerEl = container;
981
- }
982
- if (!adVideoElement) {
983
- adVideoElement = createAdVideoElement();
984
- adContainerEl.appendChild(adVideoElement);
985
- setupAdEventListeners();
986
- } else {
987
- teardownCurrentPlayback();
988
- }
1045
+ teardownCurrentPlayback();
989
1046
  }
990
1047
  if (!continueLiveStreamDuringAds) {
991
1048
  contentVideo.pause();
@@ -997,7 +1054,7 @@ function createVastAdLayer(contentVideo, options) {
997
1054
  adVolume = originalMutedState ? 1 : originalVolume;
998
1055
  adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
999
1056
  adVideoElement.muted = false;
1000
- if (!singleElementMode && adContainerEl) {
1057
+ if (adContainerEl) {
1001
1058
  adContainerEl.style.display = "flex";
1002
1059
  adContainerEl.style.pointerEvents = "auto";
1003
1060
  }
@@ -1101,6 +1158,7 @@ function createVastAdLayer(contentVideo, options) {
1101
1158
  if (debug) console.log("".concat(LOG, " [preload] HLS manifest parsed, token=").concat(token));
1102
1159
  });
1103
1160
  hls.on(import_hls.default.Events.ERROR, function(_evt, data) {
1161
+ if (!preloadSlots.has(token)) return;
1104
1162
  if (data.fatal) {
1105
1163
  if (debug) console.warn("".concat(LOG, " [preload] HLS error for token=").concat(token));
1106
1164
  preloadSlots.delete(token);
@@ -1137,113 +1195,146 @@ function createVastAdLayer(contentVideo, options) {
1137
1195
  }
1138
1196
  function playPreloaded(token) {
1139
1197
  return _async_to_generator(function() {
1140
- var slot, contentVolume, adVolume2, videoEl, container2, adVolume21, adVolume, container;
1198
+ var slot, contentVolume, adVolume2, videoEl, container2, adVolume21, nonFatalNetworkErrors, adVolume, container;
1141
1199
  return _ts_generator(this, function(_state) {
1142
- if (destroyed) return [
1143
- 2,
1144
- Promise.reject(new Error("Layer has been destroyed"))
1145
- ];
1146
- slot = preloadSlots.get(token);
1147
- if (!slot) {
1148
- if (debug) console.warn("".concat(LOG, " [preload] No slot found for token=").concat(token, ", nothing to play"));
1149
- return [
1150
- 2
1151
- ];
1152
- }
1153
- preloadSlots.delete(token);
1154
- if (debug) console.log("".concat(LOG, " [preload] Playing preloaded ad, token=").concat(token, ", ready=").concat(slot.ready));
1155
- contentVolume = contentVideo.volume;
1156
- originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
1157
- sessionId = generateSessionId();
1158
- currentAd = slot.ad;
1159
- trackingFired = _object_spread({}, createEmptyTrackingState());
1160
- fireTrackingPixels2(slot.ad.trackingUrls.impression);
1161
- trackingFired.impression = true;
1162
- if (singleElementMode) {
1163
- mainHlsInstance === null || mainHlsInstance === void 0 ? void 0 : mainHlsInstance.detachMedia();
1164
- teardownCurrentPlayback();
1165
- adVideoElement = contentVideo;
1166
- adHls = void 0;
1167
- setupAdEventListeners();
1168
- if (!continueLiveStreamDuringAds) {
1169
- contentVideo.pause();
1170
- }
1171
- contentVideo.muted = true;
1172
- contentVideo.volume = 0;
1173
- adPlaying = true;
1174
- setAdPlayingFlag(true);
1175
- adVolume2 = originalMutedState ? 1 : originalVolume;
1176
- contentVideo.volume = Math.max(0, Math.min(1, adVolume2));
1177
- contentVideo.muted = false;
1178
- emit("content_pause");
1179
- if (debug) console.log("".concat(LOG, " [preload] singleElementMode: attaching ad to contentVideo, url=").concat(slot.mediaFile.url));
1180
- startPlayback(slot.mediaFile);
1181
- return [
1182
- 2
1183
- ];
1184
- }
1185
- if (smartTVMode && !slot.videoEl) {
1186
- teardownCurrentPlayback();
1187
- if (adVideoElement) {
1188
- adVideoElement.remove();
1189
- adVideoElement = void 0;
1190
- }
1191
- videoEl = createAdVideoElement();
1192
- videoEl.style.visibility = "visible";
1193
- videoEl.style.pointerEvents = "none";
1194
- container2 = ensureAdContainer();
1195
- container2.appendChild(videoEl);
1196
- adVideoElement = videoEl;
1197
- setupAdEventListeners();
1198
- if (!continueLiveStreamDuringAds) {
1199
- contentVideo.pause();
1200
- }
1201
- contentVideo.muted = true;
1202
- contentVideo.volume = 0;
1203
- adPlaying = true;
1204
- setAdPlayingFlag(true);
1205
- adVolume21 = originalMutedState ? 1 : originalVolume;
1206
- adVideoElement.volume = Math.max(0, Math.min(1, adVolume21));
1207
- adVideoElement.muted = false;
1208
- container2.style.display = "flex";
1209
- container2.style.pointerEvents = "auto";
1210
- emit("content_pause");
1211
- if (debug) console.log("".concat(LOG, " [preload] smartTVMode deferred: creating video element and loading, url=").concat(slot.mediaFile.url));
1212
- startPlayback(slot.mediaFile);
1213
- return [
1214
- 2
1215
- ];
1216
- }
1217
- teardownCurrentPlayback();
1218
- if (adVideoElement && adVideoElement !== slot.videoEl) {
1219
- adVideoElement.remove();
1220
- }
1221
- slot.videoEl.style.visibility = "visible";
1222
- slot.videoEl.style.pointerEvents = "none";
1223
- adVideoElement = slot.videoEl;
1224
- adHls = slot.hlsInstance;
1225
- setupAdEventListeners();
1226
- if (!continueLiveStreamDuringAds) {
1227
- contentVideo.pause();
1200
+ switch(_state.label){
1201
+ case 0:
1202
+ if (destroyed) return [
1203
+ 2,
1204
+ Promise.reject(new Error("Layer has been destroyed"))
1205
+ ];
1206
+ slot = preloadSlots.get(token);
1207
+ if (!slot) {
1208
+ if (debug) console.warn("".concat(LOG, " [preload] No slot found for token=").concat(token, ", nothing to play"));
1209
+ return [
1210
+ 2
1211
+ ];
1212
+ }
1213
+ preloadSlots.delete(token);
1214
+ if (debug) console.log("".concat(LOG, " [preload] Playing preloaded ad, token=").concat(token, ", ready=").concat(slot.ready));
1215
+ contentVolume = contentVideo.volume;
1216
+ originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
1217
+ sessionId = generateSessionId();
1218
+ currentAd = slot.ad;
1219
+ trackingFired = _object_spread({}, createEmptyTrackingState());
1220
+ fireTrackingPixels2(slot.ad.trackingUrls.impression);
1221
+ trackingFired.impression = true;
1222
+ if (!singleElementMode) return [
1223
+ 3,
1224
+ 2
1225
+ ];
1226
+ mainHlsInstance === null || mainHlsInstance === void 0 ? void 0 : mainHlsInstance.detachMedia();
1227
+ teardownCurrentPlayback();
1228
+ adVideoElement = contentVideo;
1229
+ adHls = void 0;
1230
+ adPlaying = true;
1231
+ setAdPlayingFlag(true);
1232
+ contentVideo.removeAttribute("src");
1233
+ contentVideo.load();
1234
+ contentVideo.muted = true;
1235
+ contentVideo.volume = 0;
1236
+ return [
1237
+ 4,
1238
+ new Promise(function(resolve) {
1239
+ return setTimeout(resolve, 200);
1240
+ })
1241
+ ];
1242
+ case 1:
1243
+ _state.sent();
1244
+ if (destroyed || tornDown) return [
1245
+ 2
1246
+ ];
1247
+ contentVideo.style.visibility = "visible";
1248
+ contentVideo.style.opacity = "1";
1249
+ emit("content_pause");
1250
+ setupAdEventListeners();
1251
+ adVolume2 = originalMutedState ? 1 : originalVolume;
1252
+ contentVideo.volume = Math.max(0, Math.min(1, adVolume2));
1253
+ contentVideo.muted = false;
1254
+ if (debug) console.log("".concat(LOG, " [preload] singleElementMode: attaching ad to contentVideo, url=").concat(slot.mediaFile.url));
1255
+ startPlayback(slot.mediaFile);
1256
+ return [
1257
+ 2
1258
+ ];
1259
+ case 2:
1260
+ if (smartTVMode && !slot.videoEl) {
1261
+ teardownCurrentPlayback();
1262
+ if (adVideoElement) {
1263
+ adVideoElement.remove();
1264
+ adVideoElement = void 0;
1265
+ }
1266
+ videoEl = createAdVideoElement();
1267
+ videoEl.style.visibility = "visible";
1268
+ videoEl.style.pointerEvents = "none";
1269
+ container2 = ensureAdContainer();
1270
+ container2.appendChild(videoEl);
1271
+ adVideoElement = videoEl;
1272
+ setupAdEventListeners();
1273
+ if (!continueLiveStreamDuringAds) {
1274
+ contentVideo.pause();
1275
+ }
1276
+ contentVideo.muted = true;
1277
+ contentVideo.volume = 0;
1278
+ adPlaying = true;
1279
+ setAdPlayingFlag(true);
1280
+ adVolume21 = originalMutedState ? 1 : originalVolume;
1281
+ adVideoElement.volume = Math.max(0, Math.min(1, adVolume21));
1282
+ adVideoElement.muted = false;
1283
+ container2.style.display = "flex";
1284
+ container2.style.pointerEvents = "auto";
1285
+ emit("content_pause");
1286
+ if (debug) console.log("".concat(LOG, " [preload] smartTVMode deferred: creating video element and loading, url=").concat(slot.mediaFile.url));
1287
+ startPlayback(slot.mediaFile);
1288
+ return [
1289
+ 2
1290
+ ];
1291
+ }
1292
+ teardownCurrentPlayback();
1293
+ if (adVideoElement && adVideoElement !== slot.videoEl) {
1294
+ adVideoElement.remove();
1295
+ }
1296
+ slot.videoEl.style.visibility = "visible";
1297
+ slot.videoEl.style.pointerEvents = "none";
1298
+ adVideoElement = slot.videoEl;
1299
+ adHls = slot.hlsInstance;
1300
+ if (adHls) {
1301
+ nonFatalNetworkErrors = 0;
1302
+ adHls.on(import_hls.default.Events.ERROR, function(_event, data) {
1303
+ if (!adPlaying) return;
1304
+ if (data.fatal) {
1305
+ handleAdError();
1306
+ } else if (data.type === import_hls.default.ErrorTypes.NETWORK_ERROR) {
1307
+ nonFatalNetworkErrors++;
1308
+ if (nonFatalNetworkErrors >= 3) {
1309
+ if (debug) console.warn("".concat(LOG, " [preload] Too many non-fatal HLS network errors during playback, treating as fatal"));
1310
+ handleAdError();
1311
+ }
1312
+ }
1313
+ });
1314
+ }
1315
+ setupAdEventListeners();
1316
+ if (!continueLiveStreamDuringAds) {
1317
+ contentVideo.pause();
1318
+ }
1319
+ contentVideo.muted = true;
1320
+ contentVideo.volume = 0;
1321
+ adPlaying = true;
1322
+ setAdPlayingFlag(true);
1323
+ adVolume = originalMutedState ? 1 : originalVolume;
1324
+ adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
1325
+ adVideoElement.muted = false;
1326
+ container = ensureAdContainer();
1327
+ container.style.display = "flex";
1328
+ container.style.pointerEvents = "auto";
1329
+ emit("content_pause");
1330
+ adVideoElement.play().catch(function(error) {
1331
+ console.error("".concat(LOG, " [preload] Error playing preloaded ad:"), error);
1332
+ handleAdError();
1333
+ });
1334
+ return [
1335
+ 2
1336
+ ];
1228
1337
  }
1229
- contentVideo.muted = true;
1230
- contentVideo.volume = 0;
1231
- adPlaying = true;
1232
- setAdPlayingFlag(true);
1233
- adVolume = originalMutedState ? 1 : originalVolume;
1234
- adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
1235
- adVideoElement.muted = false;
1236
- container = ensureAdContainer();
1237
- container.style.display = "flex";
1238
- container.style.pointerEvents = "auto";
1239
- emit("content_pause");
1240
- adVideoElement.play().catch(function(error) {
1241
- console.error("".concat(LOG, " [preload] Error playing preloaded ad:"), error);
1242
- handleAdError();
1243
- });
1244
- return [
1245
- 2
1246
- ];
1247
1338
  });
1248
1339
  })();
1249
1340
  }