stormcloud-video-player 0.5.26 → 0.6.1

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.
@@ -436,362 +436,6 @@ var canPlay = {
436
436
  var import_react2 = require("react");
437
437
  // src/player/StormcloudVideoPlayer.ts
438
438
  var import_hls2 = __toESM(require("hls.js"), 1);
439
- // src/sdk/prebid.ts
440
- var DEFAULT_TIMEOUT_MS = 3e3;
441
- var AUCTION_URL = "https://sspproxy.adstorm.co/openrtb2/auction/adstorm";
442
- function createPrebidManager() {
443
- var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
444
- var _options_debug;
445
- var initialized = false;
446
- var debug = (_options_debug = options.debug) !== null && _options_debug !== void 0 ? _options_debug : false;
447
- function log() {
448
- for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
449
- args[_key] = arguments[_key];
450
- }
451
- if (debug) {
452
- var _console;
453
- (_console = console).log.apply(_console, [
454
- "[Prebid]"
455
- ].concat(_to_consumable_array(args)));
456
- }
457
- }
458
- function warn() {
459
- for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
460
- args[_key] = arguments[_key];
461
- }
462
- var _console;
463
- (_console = console).warn.apply(_console, [
464
- "[Prebid]"
465
- ].concat(_to_consumable_array(args)));
466
- }
467
- function parseResponse(data) {
468
- var bids = [];
469
- var seatbids = (data === null || data === void 0 ? void 0 : data.seatbid) || [];
470
- var currency = (data === null || data === void 0 ? void 0 : data.cur) || "USD";
471
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
472
- try {
473
- for(var _iterator = seatbids[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
474
- var seatbid = _step.value;
475
- var seat = seatbid.seat || "unknown";
476
- var bidArray = seatbid.bid || [];
477
- var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
478
- try {
479
- for(var _iterator1 = bidArray[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
480
- var bid = _step1.value;
481
- var _bid_ext_prebid_cache_vastXml, _bid_ext_prebid_cache, _bid_ext_prebid, _bid_ext;
482
- var cacheUrl = (_bid_ext = bid.ext) === null || _bid_ext === void 0 ? void 0 : (_bid_ext_prebid = _bid_ext.prebid) === null || _bid_ext_prebid === void 0 ? void 0 : (_bid_ext_prebid_cache = _bid_ext_prebid.cache) === null || _bid_ext_prebid_cache === void 0 ? void 0 : (_bid_ext_prebid_cache_vastXml = _bid_ext_prebid_cache.vastXml) === null || _bid_ext_prebid_cache_vastXml === void 0 ? void 0 : _bid_ext_prebid_cache_vastXml.url;
483
- var vastXml = bid.adm || void 0;
484
- var bidResponse = {
485
- bidder: seat,
486
- cpm: bid.price || 0,
487
- width: bid.w || 0,
488
- height: bid.h || 0,
489
- adId: bid.id || "",
490
- impId: bid.impid || "",
491
- creativeId: bid.crid || "",
492
- currency: currency
493
- };
494
- if (cacheUrl) bidResponse.vastUrl = cacheUrl;
495
- if (vastXml) bidResponse.vastXml = vastXml;
496
- if (bid.adomain) bidResponse.adomain = bid.adomain;
497
- bids.push(bidResponse);
498
- }
499
- } catch (err) {
500
- _didIteratorError1 = true;
501
- _iteratorError1 = err;
502
- } finally{
503
- try {
504
- if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
505
- _iterator1.return();
506
- }
507
- } finally{
508
- if (_didIteratorError1) {
509
- throw _iteratorError1;
510
- }
511
- }
512
- }
513
- }
514
- } catch (err) {
515
- _didIteratorError = true;
516
- _iteratorError = err;
517
- } finally{
518
- try {
519
- if (!_iteratorNormalCompletion && _iterator.return != null) {
520
- _iterator.return();
521
- }
522
- } finally{
523
- if (_didIteratorError) {
524
- throw _iteratorError;
525
- }
526
- }
527
- }
528
- bids.sort(function(a, b) {
529
- return b.cpm - a.cpm;
530
- });
531
- return bids;
532
- }
533
- function initialize() {
534
- return _async_to_generator(function() {
535
- return _ts_generator(this, function(_state) {
536
- if (initialized) return [
537
- 2
538
- ];
539
- initialized = true;
540
- log("Initialized, auction URL:", AUCTION_URL);
541
- return [
542
- 2
543
- ];
544
- });
545
- })();
546
- }
547
- function requestBids(context) {
548
- return _async_to_generator(function() {
549
- var timeout, controller, timeoutId, _data_ext, _data_ext1, fetchOptions, body, response, body1, data, bids, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, b, error;
550
- return _ts_generator(this, function(_state) {
551
- switch(_state.label){
552
- case 0:
553
- if (!initialized) {
554
- throw new Error("Prebid not initialized. Call initialize() first.");
555
- }
556
- timeout = DEFAULT_TIMEOUT_MS;
557
- log("Fetching auction response from:", AUCTION_URL);
558
- controller = typeof AbortController !== "undefined" ? new AbortController() : null;
559
- timeoutId = setTimeout(function() {
560
- controller === null || controller === void 0 ? void 0 : controller.abort();
561
- }, timeout + 2e3);
562
- _state.label = 1;
563
- case 1:
564
- _state.trys.push([
565
- 1,
566
- 6,
567
- ,
568
- 7
569
- ]);
570
- fetchOptions = {
571
- method: "POST"
572
- };
573
- if (controller) {
574
- fetchOptions.signal = controller.signal;
575
- }
576
- if ((context === null || context === void 0 ? void 0 : context.remainingBreakSec) != null) {
577
- body = {
578
- imp: [
579
- {
580
- video: {
581
- maxduration: Math.floor(context.remainingBreakSec)
582
- }
583
- }
584
- ]
585
- };
586
- fetchOptions.body = JSON.stringify(body);
587
- fetchOptions.headers = {
588
- "Content-Type": "application/json"
589
- };
590
- log("Sending context to auction: maxduration=", Math.floor(context.remainingBreakSec));
591
- }
592
- return [
593
- 4,
594
- fetch(AUCTION_URL, fetchOptions)
595
- ];
596
- case 2:
597
- response = _state.sent();
598
- clearTimeout(timeoutId);
599
- if (!!response.ok) return [
600
- 3,
601
- 4
602
- ];
603
- return [
604
- 4,
605
- response.text().catch(function() {
606
- return "";
607
- })
608
- ];
609
- case 3:
610
- body1 = _state.sent();
611
- throw new Error("Prebid Server returned HTTP ".concat(response.status, ": ").concat(body1.slice(0, 200)));
612
- case 4:
613
- return [
614
- 4,
615
- response.json()
616
- ];
617
- case 5:
618
- data = _state.sent();
619
- if (debug && (data === null || data === void 0 ? void 0 : (_data_ext = data.ext) === null || _data_ext === void 0 ? void 0 : _data_ext.responsetimemillis)) {
620
- log("Bidder response times:", data.ext.responsetimemillis);
621
- }
622
- if (debug && (data === null || data === void 0 ? void 0 : (_data_ext1 = data.ext) === null || _data_ext1 === void 0 ? void 0 : _data_ext1.errors)) {
623
- warn("Auction errors:", data.ext.errors);
624
- }
625
- bids = parseResponse(data);
626
- log("Received ".concat(bids.length, " bid(s)"));
627
- if (debug) {
628
- _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
629
- try {
630
- for(_iterator = bids[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
631
- b = _step.value;
632
- log(" ".concat(b.bidder, ": $").concat(b.cpm.toFixed(2), " ").concat(b.currency, " ").concat(b.width, "x").concat(b.height) + (b.vastUrl ? " [cached VAST]" : "") + (b.vastXml && !b.vastUrl ? " [VAST XML]" : ""));
633
- }
634
- } catch (err) {
635
- _didIteratorError = true;
636
- _iteratorError = err;
637
- } finally{
638
- try {
639
- if (!_iteratorNormalCompletion && _iterator.return != null) {
640
- _iterator.return();
641
- }
642
- } finally{
643
- if (_didIteratorError) {
644
- throw _iteratorError;
645
- }
646
- }
647
- }
648
- }
649
- return [
650
- 2,
651
- bids
652
- ];
653
- case 6:
654
- error = _state.sent();
655
- clearTimeout(timeoutId);
656
- if ((error === null || error === void 0 ? void 0 : error.name) === "AbortError") {
657
- warn("Auction request timed out after ".concat(timeout + 2e3, "ms"));
658
- return [
659
- 2,
660
- []
661
- ];
662
- }
663
- throw error;
664
- case 7:
665
- return [
666
- 2
667
- ];
668
- }
669
- });
670
- })();
671
- }
672
- var REQUEST_BIDS_MAX_RETRIES = 3;
673
- var REQUEST_BIDS_BACKOFF_MS = 1500;
674
- function requestBidsUntilResponse(context) {
675
- return _async_to_generator(function() {
676
- var _loop, lastError, attempt, _ret;
677
- return _ts_generator(this, function(_state) {
678
- switch(_state.label){
679
- case 0:
680
- _loop = function(attempt) {
681
- var bids, err, delay;
682
- return _ts_generator(this, function(_state) {
683
- switch(_state.label){
684
- case 0:
685
- _state.trys.push([
686
- 0,
687
- 2,
688
- ,
689
- 3
690
- ]);
691
- return [
692
- 4,
693
- requestBids(context)
694
- ];
695
- case 1:
696
- bids = _state.sent();
697
- if (bids.length > 0) {
698
- log("requestBidsUntilResponse: got ".concat(bids.length, " bid(s) on attempt ").concat(attempt));
699
- return [
700
- 2,
701
- {
702
- v: bids
703
- }
704
- ];
705
- }
706
- log("requestBidsUntilResponse: no bids on attempt ".concat(attempt, "/").concat(REQUEST_BIDS_MAX_RETRIES));
707
- return [
708
- 3,
709
- 3
710
- ];
711
- case 2:
712
- err = _state.sent();
713
- lastError = err;
714
- warn("requestBidsUntilResponse: attempt ".concat(attempt, "/").concat(REQUEST_BIDS_MAX_RETRIES, " failed:"), err);
715
- return [
716
- 3,
717
- 3
718
- ];
719
- case 3:
720
- if (!(attempt < REQUEST_BIDS_MAX_RETRIES)) return [
721
- 3,
722
- 5
723
- ];
724
- delay = REQUEST_BIDS_BACKOFF_MS * attempt;
725
- log("requestBidsUntilResponse: waiting ".concat(delay, "ms before retry"));
726
- return [
727
- 4,
728
- new Promise(function(resolve) {
729
- return setTimeout(resolve, delay);
730
- })
731
- ];
732
- case 4:
733
- _state.sent();
734
- _state.label = 5;
735
- case 5:
736
- return [
737
- 2
738
- ];
739
- }
740
- });
741
- };
742
- if (!initialized) {
743
- throw new Error("Prebid not initialized. Call initialize() first.");
744
- }
745
- attempt = 1;
746
- _state.label = 1;
747
- case 1:
748
- if (!(attempt <= REQUEST_BIDS_MAX_RETRIES)) return [
749
- 3,
750
- 4
751
- ];
752
- return [
753
- 5,
754
- _ts_values(_loop(attempt))
755
- ];
756
- case 2:
757
- _ret = _state.sent();
758
- if (_type_of(_ret) === "object") return [
759
- 2,
760
- _ret.v
761
- ];
762
- _state.label = 3;
763
- case 3:
764
- attempt++;
765
- return [
766
- 3,
767
- 1
768
- ];
769
- case 4:
770
- if (_instanceof(lastError, Error)) {
771
- throw lastError;
772
- }
773
- return [
774
- 2,
775
- []
776
- ];
777
- }
778
- });
779
- })();
780
- }
781
- function destroy() {
782
- initialized = false;
783
- log("Destroyed");
784
- }
785
- return {
786
- initialize: initialize,
787
- requestBids: requestBids,
788
- requestBidsUntilResponse: requestBidsUntilResponse,
789
- destroy: destroy,
790
- get isInitialized () {
791
- return initialized;
792
- }
793
- };
794
- }
795
439
  // src/sdk/vastParser.ts
796
440
  function isHlsType(type) {
797
441
  return type === "application/x-mpegURL" || type.includes("m3u8");
@@ -1090,11 +734,271 @@ function fireTrackingPixels(urls, sessionId) {
1090
734
  } catch (error) {
1091
735
  console.warn("".concat(logPrefix, " Error firing tracking pixel:"), error);
1092
736
  }
1093
- });
737
+ });
738
+ }
739
+ // src/sdk/vastManager.ts
740
+ var VAST_TAG_URL = "https://pubads.g.doubleclick.net/gampad/ads?iu=/21821455290/Airy-Android&description_url=http%3A%2F%2Fairy.tv&tfcd=0&npa=0&sz=1x1%7C300x250%7C400x300%7C640x480&gdfp_req=1&unviewed_position_start=1&correlator=[placeholder]&vpos=preroll&output=vast&env=vp&vpmute=0&vpa=click";
741
+ var DEFAULT_TIMEOUT_MS = 5e3;
742
+ var MAX_RETRIES = 3;
743
+ var RETRY_BACKOFF_MS = 1500;
744
+ function createVastManager() {
745
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
746
+ var _options_debug;
747
+ var initialized = false;
748
+ var debug = (_options_debug = options.debug) !== null && _options_debug !== void 0 ? _options_debug : false;
749
+ function log() {
750
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
751
+ args[_key] = arguments[_key];
752
+ }
753
+ if (debug) {
754
+ var _console;
755
+ (_console = console).log.apply(_console, [
756
+ "[VastManager]"
757
+ ].concat(_to_consumable_array(args)));
758
+ }
759
+ }
760
+ function warn() {
761
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
762
+ args[_key] = arguments[_key];
763
+ }
764
+ var _console;
765
+ (_console = console).warn.apply(_console, [
766
+ "[VastManager]"
767
+ ].concat(_to_consumable_array(args)));
768
+ }
769
+ function initialize() {
770
+ return _async_to_generator(function() {
771
+ return _ts_generator(this, function(_state) {
772
+ if (initialized) return [
773
+ 2
774
+ ];
775
+ initialized = true;
776
+ log("Initialized, VAST tag URL:", VAST_TAG_URL.split("?")[0]);
777
+ return [
778
+ 2
779
+ ];
780
+ });
781
+ })();
782
+ }
783
+ function requestBids(_context) {
784
+ return _async_to_generator(function() {
785
+ var correlator, url, controller, timeoutId, _ref, _ref1, _vastAd_mediaFiles_, _vastAd_mediaFiles_1, fetchOptions, response, vastXml, vastAd, bid, error;
786
+ return _ts_generator(this, function(_state) {
787
+ switch(_state.label){
788
+ case 0:
789
+ if (!initialized) {
790
+ throw new Error("VastManager not initialized. Call initialize() first.");
791
+ }
792
+ correlator = Math.floor(Math.random() * 1e12).toString();
793
+ url = VAST_TAG_URL.replace("[placeholder]", correlator);
794
+ log("Fetching VAST tag, correlator:", correlator);
795
+ controller = typeof AbortController !== "undefined" ? new AbortController() : null;
796
+ timeoutId = setTimeout(function() {
797
+ return controller === null || controller === void 0 ? void 0 : controller.abort();
798
+ }, DEFAULT_TIMEOUT_MS);
799
+ _state.label = 1;
800
+ case 1:
801
+ _state.trys.push([
802
+ 1,
803
+ 4,
804
+ ,
805
+ 5
806
+ ]);
807
+ fetchOptions = {
808
+ method: "GET",
809
+ mode: "cors",
810
+ credentials: "omit",
811
+ headers: {
812
+ Accept: "application/xml, text/xml, */*"
813
+ },
814
+ referrerPolicy: "no-referrer-when-downgrade"
815
+ };
816
+ if (controller) fetchOptions.signal = controller.signal;
817
+ return [
818
+ 4,
819
+ fetch(url, fetchOptions)
820
+ ];
821
+ case 2:
822
+ response = _state.sent();
823
+ clearTimeout(timeoutId);
824
+ if (!response.ok) {
825
+ throw new Error("VAST request returned HTTP ".concat(response.status));
826
+ }
827
+ return [
828
+ 4,
829
+ response.text()
830
+ ];
831
+ case 3:
832
+ vastXml = _state.sent();
833
+ log("VAST XML received, length:", vastXml.length);
834
+ vastAd = parseVastXml(vastXml, "mp4-first", "[VastManager]");
835
+ if (!vastAd) {
836
+ log("VAST parsed but no usable ad found");
837
+ return [
838
+ 2,
839
+ []
840
+ ];
841
+ }
842
+ log("Ad parsed: id=".concat(vastAd.id, ", duration=").concat(vastAd.duration, "s, mediaFiles=").concat(vastAd.mediaFiles.length));
843
+ bid = {
844
+ bidder: "vast-direct",
845
+ cpm: 0,
846
+ vastXml: vastXml,
847
+ width: (_ref = (_vastAd_mediaFiles_ = vastAd.mediaFiles[0]) === null || _vastAd_mediaFiles_ === void 0 ? void 0 : _vastAd_mediaFiles_.width) !== null && _ref !== void 0 ? _ref : 0,
848
+ height: (_ref1 = (_vastAd_mediaFiles_1 = vastAd.mediaFiles[0]) === null || _vastAd_mediaFiles_1 === void 0 ? void 0 : _vastAd_mediaFiles_1.height) !== null && _ref1 !== void 0 ? _ref1 : 0,
849
+ adId: vastAd.id,
850
+ impId: correlator,
851
+ creativeId: vastAd.id,
852
+ currency: "USD",
853
+ durationSec: vastAd.duration
854
+ };
855
+ return [
856
+ 2,
857
+ [
858
+ bid
859
+ ]
860
+ ];
861
+ case 4:
862
+ error = _state.sent();
863
+ clearTimeout(timeoutId);
864
+ if ((error === null || error === void 0 ? void 0 : error.name) === "AbortError") {
865
+ warn("VAST request timed out after ".concat(DEFAULT_TIMEOUT_MS, "ms"));
866
+ return [
867
+ 2,
868
+ []
869
+ ];
870
+ }
871
+ throw error;
872
+ case 5:
873
+ return [
874
+ 2
875
+ ];
876
+ }
877
+ });
878
+ })();
879
+ }
880
+ function requestBidsUntilResponse(context) {
881
+ return _async_to_generator(function() {
882
+ var _loop, lastError, attempt, _ret;
883
+ return _ts_generator(this, function(_state) {
884
+ switch(_state.label){
885
+ case 0:
886
+ _loop = function(attempt) {
887
+ var bids, err, delay;
888
+ return _ts_generator(this, function(_state) {
889
+ switch(_state.label){
890
+ case 0:
891
+ _state.trys.push([
892
+ 0,
893
+ 2,
894
+ ,
895
+ 3
896
+ ]);
897
+ return [
898
+ 4,
899
+ requestBids(context)
900
+ ];
901
+ case 1:
902
+ bids = _state.sent();
903
+ if (bids.length > 0) {
904
+ log("requestBidsUntilResponse: got ".concat(bids.length, " ad(s) on attempt ").concat(attempt));
905
+ return [
906
+ 2,
907
+ {
908
+ v: bids
909
+ }
910
+ ];
911
+ }
912
+ log("requestBidsUntilResponse: no ads on attempt ".concat(attempt, "/").concat(MAX_RETRIES));
913
+ return [
914
+ 3,
915
+ 3
916
+ ];
917
+ case 2:
918
+ err = _state.sent();
919
+ lastError = err;
920
+ warn("requestBidsUntilResponse: attempt ".concat(attempt, "/").concat(MAX_RETRIES, " failed:"), err);
921
+ return [
922
+ 3,
923
+ 3
924
+ ];
925
+ case 3:
926
+ if (!(attempt < MAX_RETRIES)) return [
927
+ 3,
928
+ 5
929
+ ];
930
+ delay = RETRY_BACKOFF_MS * attempt;
931
+ log("requestBidsUntilResponse: waiting ".concat(delay, "ms before retry"));
932
+ return [
933
+ 4,
934
+ new Promise(function(resolve) {
935
+ return setTimeout(resolve, delay);
936
+ })
937
+ ];
938
+ case 4:
939
+ _state.sent();
940
+ _state.label = 5;
941
+ case 5:
942
+ return [
943
+ 2
944
+ ];
945
+ }
946
+ });
947
+ };
948
+ if (!initialized) {
949
+ throw new Error("VastManager not initialized. Call initialize() first.");
950
+ }
951
+ attempt = 1;
952
+ _state.label = 1;
953
+ case 1:
954
+ if (!(attempt <= MAX_RETRIES)) return [
955
+ 3,
956
+ 4
957
+ ];
958
+ return [
959
+ 5,
960
+ _ts_values(_loop(attempt))
961
+ ];
962
+ case 2:
963
+ _ret = _state.sent();
964
+ if (_type_of(_ret) === "object") return [
965
+ 2,
966
+ _ret.v
967
+ ];
968
+ _state.label = 3;
969
+ case 3:
970
+ attempt++;
971
+ return [
972
+ 3,
973
+ 1
974
+ ];
975
+ case 4:
976
+ if (_instanceof(lastError, Error)) throw lastError;
977
+ return [
978
+ 2,
979
+ []
980
+ ];
981
+ }
982
+ });
983
+ })();
984
+ }
985
+ function destroy() {
986
+ initialized = false;
987
+ log("Destroyed");
988
+ }
989
+ return {
990
+ initialize: initialize,
991
+ requestBids: requestBids,
992
+ requestBidsUntilResponse: requestBidsUntilResponse,
993
+ destroy: destroy,
994
+ get isInitialized () {
995
+ return initialized;
996
+ }
997
+ };
1094
998
  }
1095
- // src/sdk/prebidAdLayer.ts
999
+ // src/sdk/vastAdLayer.ts
1096
1000
  var import_hls = __toESM(require("hls.js"), 1);
1097
- var LOG = "[PrebidAdLayer]";
1001
+ var LOG = "[VastAdLayer]";
1098
1002
  function resolveBidToVastAd(winner, logPrefix) {
1099
1003
  if (winner.vastXml) {
1100
1004
  var ad = parseVastXml(winner.vastXml, "mp4-first", logPrefix);
@@ -1105,15 +1009,17 @@ function resolveBidToVastAd(winner, logPrefix) {
1105
1009
  }
1106
1010
  return Promise.resolve(null);
1107
1011
  }
1108
- function createPrebidAdLayer(contentVideo, options) {
1109
- var _ref, _ref1;
1012
+ function createVastAdLayer(contentVideo, options) {
1013
+ var _ref, _ref1, _ref2, _ref3;
1110
1014
  var adPlaying = false;
1111
1015
  var originalMutedState = false;
1112
1016
  var originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));
1113
1017
  var listeners = /* @__PURE__ */ new Map();
1114
1018
  var mainHlsInstance = options === null || options === void 0 ? void 0 : options.mainHlsInstance;
1115
1019
  var continueLiveStreamDuringAds = (_ref = options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) !== null && _ref !== void 0 ? _ref : false;
1116
- var debug = (_ref1 = options === null || options === void 0 ? void 0 : options.debug) !== null && _ref1 !== void 0 ? _ref1 : false;
1020
+ var smartTVMode = (_ref1 = options === null || options === void 0 ? void 0 : options.smartTVMode) !== null && _ref1 !== void 0 ? _ref1 : false;
1021
+ var singleElementMode = (_ref2 = options === null || options === void 0 ? void 0 : options.singleElementMode) !== null && _ref2 !== void 0 ? _ref2 : false;
1022
+ var debug = (_ref3 = options === null || options === void 0 ? void 0 : options.debug) !== null && _ref3 !== void 0 ? _ref3 : false;
1117
1023
  var adVideoElement;
1118
1024
  var adHls;
1119
1025
  var adContainerEl;
@@ -1122,6 +1028,7 @@ function createPrebidAdLayer(contentVideo, options) {
1122
1028
  var destroyed = false;
1123
1029
  var tornDown = false;
1124
1030
  var trackingFired = createEmptyTrackingState();
1031
+ var currentAdEventHandlers;
1125
1032
  var preloadSlots = /* @__PURE__ */ new Map();
1126
1033
  function emit(event, payload) {
1127
1034
  var set = listeners.get(event);
@@ -1224,63 +1131,86 @@ function createPrebidAdLayer(contentVideo, options) {
1224
1131
  video.volume = 1;
1225
1132
  return video;
1226
1133
  }
1134
+ function removeAdEventListeners() {
1135
+ if (!currentAdEventHandlers || !adVideoElement) return;
1136
+ var el = adVideoElement;
1137
+ el.removeEventListener("timeupdate", currentAdEventHandlers.timeupdate);
1138
+ el.removeEventListener("playing", currentAdEventHandlers.playing);
1139
+ el.removeEventListener("ended", currentAdEventHandlers.ended);
1140
+ el.removeEventListener("error", currentAdEventHandlers.error);
1141
+ el.removeEventListener("volumechange", currentAdEventHandlers.volumechange);
1142
+ el.removeEventListener("pause", currentAdEventHandlers.pause);
1143
+ el.removeEventListener("play", currentAdEventHandlers.play);
1144
+ currentAdEventHandlers = void 0;
1145
+ }
1227
1146
  function setupAdEventListeners() {
1228
1147
  if (!adVideoElement) return;
1229
- adVideoElement.addEventListener("timeupdate", function() {
1230
- var ad = currentAd;
1231
- if (!ad || !adVideoElement) return;
1232
- var progress = adVideoElement.currentTime / ad.duration;
1233
- if (progress >= 0.25 && !trackingFired.firstQuartile) {
1234
- trackingFired.firstQuartile = true;
1235
- fireTrackingPixels2(ad.trackingUrls.firstQuartile);
1236
- }
1237
- if (progress >= 0.5 && !trackingFired.midpoint) {
1238
- trackingFired.midpoint = true;
1239
- fireTrackingPixels2(ad.trackingUrls.midpoint);
1240
- }
1241
- if (progress >= 0.75 && !trackingFired.thirdQuartile) {
1242
- trackingFired.thirdQuartile = true;
1243
- fireTrackingPixels2(ad.trackingUrls.thirdQuartile);
1244
- }
1245
- });
1246
- adVideoElement.addEventListener("playing", function() {
1247
- var ad = currentAd;
1248
- if (!ad || trackingFired.start) return;
1249
- trackingFired.start = true;
1250
- fireTrackingPixels2(ad.trackingUrls.start);
1251
- if (debug) console.log("".concat(LOG, " Ad started playing"));
1252
- });
1253
- adVideoElement.addEventListener("ended", function() {
1254
- if (tornDown || !currentAd || trackingFired.complete) return;
1255
- trackingFired.complete = true;
1256
- fireTrackingPixels2(currentAd.trackingUrls.complete);
1257
- if (debug) console.log("".concat(LOG, " Ad completed"));
1258
- handleAdComplete();
1259
- });
1260
- adVideoElement.addEventListener("error", function(e) {
1261
- if (tornDown) return;
1262
- console.error("".concat(LOG, " Ad video error:"), e);
1263
- if (currentAd) fireTrackingPixels2(currentAd.trackingUrls.error);
1264
- handleAdError();
1265
- });
1266
- adVideoElement.addEventListener("volumechange", function() {
1267
- if (!currentAd || !adVideoElement) return;
1268
- if (adVideoElement.muted) {
1269
- fireTrackingPixels2(currentAd.trackingUrls.mute);
1270
- } else {
1271
- fireTrackingPixels2(currentAd.trackingUrls.unmute);
1272
- }
1273
- });
1274
- adVideoElement.addEventListener("pause", function() {
1275
- if (currentAd && adVideoElement && !adVideoElement.ended) {
1276
- fireTrackingPixels2(currentAd.trackingUrls.pause);
1277
- }
1278
- });
1279
- adVideoElement.addEventListener("play", function() {
1280
- if (currentAd && adVideoElement && adVideoElement.currentTime > 0) {
1281
- fireTrackingPixels2(currentAd.trackingUrls.resume);
1148
+ removeAdEventListeners();
1149
+ var handlers = {
1150
+ timeupdate: function timeupdate() {
1151
+ var ad = currentAd;
1152
+ if (!ad || !adVideoElement) return;
1153
+ var progress = adVideoElement.currentTime / ad.duration;
1154
+ if (progress >= 0.25 && !trackingFired.firstQuartile) {
1155
+ trackingFired.firstQuartile = true;
1156
+ fireTrackingPixels2(ad.trackingUrls.firstQuartile);
1157
+ }
1158
+ if (progress >= 0.5 && !trackingFired.midpoint) {
1159
+ trackingFired.midpoint = true;
1160
+ fireTrackingPixels2(ad.trackingUrls.midpoint);
1161
+ }
1162
+ if (progress >= 0.75 && !trackingFired.thirdQuartile) {
1163
+ trackingFired.thirdQuartile = true;
1164
+ fireTrackingPixels2(ad.trackingUrls.thirdQuartile);
1165
+ }
1166
+ },
1167
+ playing: function playing() {
1168
+ var ad = currentAd;
1169
+ if (!ad || trackingFired.start) return;
1170
+ trackingFired.start = true;
1171
+ fireTrackingPixels2(ad.trackingUrls.start);
1172
+ if (debug) console.log("".concat(LOG, " Ad started playing"));
1173
+ },
1174
+ ended: function ended() {
1175
+ if (tornDown || !currentAd || trackingFired.complete) return;
1176
+ trackingFired.complete = true;
1177
+ fireTrackingPixels2(currentAd.trackingUrls.complete);
1178
+ if (debug) console.log("".concat(LOG, " Ad completed"));
1179
+ handleAdComplete();
1180
+ },
1181
+ error: function error(e) {
1182
+ if (tornDown) return;
1183
+ console.error("".concat(LOG, " Ad video error:"), e);
1184
+ if (currentAd) fireTrackingPixels2(currentAd.trackingUrls.error);
1185
+ handleAdError();
1186
+ },
1187
+ volumechange: function volumechange() {
1188
+ if (!currentAd || !adVideoElement) return;
1189
+ if (adVideoElement.muted) {
1190
+ fireTrackingPixels2(currentAd.trackingUrls.mute);
1191
+ } else {
1192
+ fireTrackingPixels2(currentAd.trackingUrls.unmute);
1193
+ }
1194
+ },
1195
+ pause: function pause() {
1196
+ if (currentAd && adVideoElement && !adVideoElement.ended) {
1197
+ fireTrackingPixels2(currentAd.trackingUrls.pause);
1198
+ }
1199
+ },
1200
+ play: function play() {
1201
+ if (currentAd && adVideoElement && adVideoElement.currentTime > 0) {
1202
+ fireTrackingPixels2(currentAd.trackingUrls.resume);
1203
+ }
1282
1204
  }
1283
- });
1205
+ };
1206
+ adVideoElement.addEventListener("timeupdate", handlers.timeupdate);
1207
+ adVideoElement.addEventListener("playing", handlers.playing);
1208
+ adVideoElement.addEventListener("ended", handlers.ended);
1209
+ adVideoElement.addEventListener("error", handlers.error);
1210
+ adVideoElement.addEventListener("volumechange", handlers.volumechange);
1211
+ adVideoElement.addEventListener("pause", handlers.pause);
1212
+ adVideoElement.addEventListener("play", handlers.play);
1213
+ currentAdEventHandlers = handlers;
1284
1214
  }
1285
1215
  function setAdPlayingFlag(isPlaying) {
1286
1216
  if (isPlaying) {
@@ -1303,6 +1233,7 @@ function createPrebidAdLayer(contentVideo, options) {
1303
1233
  }
1304
1234
  function handleAdError() {
1305
1235
  if (tornDown) return;
1236
+ if (!adPlaying) return;
1306
1237
  if (debug) console.log("".concat(LOG, " Handling ad error"));
1307
1238
  adPlaying = false;
1308
1239
  setAdPlayingFlag(false);
@@ -1313,14 +1244,19 @@ function createPrebidAdLayer(contentVideo, options) {
1313
1244
  emit("ad_error");
1314
1245
  }
1315
1246
  function teardownCurrentPlayback() {
1247
+ removeAdEventListeners();
1316
1248
  if (adHls) {
1317
1249
  adHls.destroy();
1318
1250
  adHls = void 0;
1319
1251
  }
1320
1252
  if (adVideoElement) {
1321
- adVideoElement.pause();
1322
- adVideoElement.removeAttribute("src");
1323
- adVideoElement.load();
1253
+ if (singleElementMode && adVideoElement === contentVideo) {
1254
+ contentVideo.pause();
1255
+ } else {
1256
+ adVideoElement.pause();
1257
+ adVideoElement.removeAttribute("src");
1258
+ adVideoElement.load();
1259
+ }
1324
1260
  }
1325
1261
  }
1326
1262
  function startNativePlayback(mediaFile) {
@@ -1353,8 +1289,17 @@ function createPrebidAdLayer(contentVideo, options) {
1353
1289
  handleAdError();
1354
1290
  });
1355
1291
  });
1292
+ var nonFatalNetworkErrors = 0;
1356
1293
  adHls.on(import_hls.default.Events.ERROR, function(_event, data) {
1357
- if (data.fatal) handleAdError();
1294
+ if (data.fatal) {
1295
+ handleAdError();
1296
+ } else if (data.type === import_hls.default.ErrorTypes.NETWORK_ERROR) {
1297
+ nonFatalNetworkErrors++;
1298
+ if (nonFatalNetworkErrors >= 3) {
1299
+ if (debug) console.warn("".concat(LOG, " Too many non-fatal HLS network errors (").concat(nonFatalNetworkErrors, "), treating as fatal"));
1300
+ handleAdError();
1301
+ }
1302
+ }
1358
1303
  });
1359
1304
  } else if (adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
1360
1305
  adVideoElement.src = mediaFile.url;
@@ -1377,7 +1322,7 @@ function createPrebidAdLayer(contentVideo, options) {
1377
1322
  }
1378
1323
  function playAd(bids) {
1379
1324
  return _async_to_generator(function() {
1380
- var winner, ad, _contentVideo_parentElement, container, contentVolume, adVolume, mediaFile;
1325
+ var winner, ad, contentVolume, _contentVideo_parentElement, container, adVolume, mediaFile;
1381
1326
  return _ts_generator(this, function(_state) {
1382
1327
  switch(_state.label){
1383
1328
  case 0:
@@ -1419,32 +1364,40 @@ function createPrebidAdLayer(contentVideo, options) {
1419
1364
  trackingFired = _object_spread({}, createEmptyTrackingState());
1420
1365
  fireTrackingPixels2(ad.trackingUrls.impression);
1421
1366
  trackingFired.impression = true;
1422
- if (!adContainerEl) {
1423
- ;
1424
- container = document.createElement("div");
1425
- container.style.position = "absolute";
1426
- container.style.left = "0";
1427
- container.style.top = "0";
1428
- container.style.right = "0";
1429
- container.style.bottom = "0";
1430
- container.style.display = "none";
1431
- container.style.alignItems = "center";
1432
- container.style.justifyContent = "center";
1433
- container.style.pointerEvents = "none";
1434
- container.style.zIndex = "10";
1435
- container.style.backgroundColor = "#000";
1436
- (_contentVideo_parentElement = contentVideo.parentElement) === null || _contentVideo_parentElement === void 0 ? void 0 : _contentVideo_parentElement.appendChild(container);
1437
- adContainerEl = container;
1438
- }
1439
- if (!adVideoElement) {
1440
- adVideoElement = createAdVideoElement();
1441
- adContainerEl.appendChild(adVideoElement);
1367
+ contentVolume = contentVideo.volume;
1368
+ originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
1369
+ if (singleElementMode) {
1370
+ mainHlsInstance === null || mainHlsInstance === void 0 ? void 0 : mainHlsInstance.detachMedia();
1371
+ teardownCurrentPlayback();
1372
+ adVideoElement = contentVideo;
1373
+ adHls = void 0;
1442
1374
  setupAdEventListeners();
1443
1375
  } else {
1444
- teardownCurrentPlayback();
1376
+ if (!adContainerEl) {
1377
+ ;
1378
+ container = document.createElement("div");
1379
+ container.style.position = "absolute";
1380
+ container.style.left = "0";
1381
+ container.style.top = "0";
1382
+ container.style.right = "0";
1383
+ container.style.bottom = "0";
1384
+ container.style.display = "none";
1385
+ container.style.alignItems = "center";
1386
+ container.style.justifyContent = "center";
1387
+ container.style.pointerEvents = "none";
1388
+ container.style.zIndex = "10";
1389
+ container.style.backgroundColor = "#000";
1390
+ (_contentVideo_parentElement = contentVideo.parentElement) === null || _contentVideo_parentElement === void 0 ? void 0 : _contentVideo_parentElement.appendChild(container);
1391
+ adContainerEl = container;
1392
+ }
1393
+ if (!adVideoElement) {
1394
+ adVideoElement = createAdVideoElement();
1395
+ adContainerEl.appendChild(adVideoElement);
1396
+ setupAdEventListeners();
1397
+ } else {
1398
+ teardownCurrentPlayback();
1399
+ }
1445
1400
  }
1446
- contentVolume = contentVideo.volume;
1447
- originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
1448
1401
  if (!continueLiveStreamDuringAds) {
1449
1402
  contentVideo.pause();
1450
1403
  }
@@ -1455,7 +1408,7 @@ function createPrebidAdLayer(contentVideo, options) {
1455
1408
  adVolume = originalMutedState ? 1 : originalVolume;
1456
1409
  adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
1457
1410
  adVideoElement.muted = false;
1458
- if (adContainerEl) {
1411
+ if (!singleElementMode && adContainerEl) {
1459
1412
  adContainerEl.style.display = "flex";
1460
1413
  adContainerEl.style.pointerEvents = "auto";
1461
1414
  }
@@ -1492,7 +1445,7 @@ function createPrebidAdLayer(contentVideo, options) {
1492
1445
  }
1493
1446
  function preloadAd(bids, token) {
1494
1447
  return _async_to_generator(function() {
1495
- var winner, ad, mediaFile, videoEl, container, hls, slot, slot1;
1448
+ var winner, ad, mediaFile, slot, videoEl, container, hls, slot1, slot2;
1496
1449
  return _ts_generator(this, function(_state) {
1497
1450
  switch(_state.label){
1498
1451
  case 0:
@@ -1517,6 +1470,20 @@ function createPrebidAdLayer(contentVideo, options) {
1517
1470
  if (!mediaFile) return [
1518
1471
  2
1519
1472
  ];
1473
+ if (smartTVMode || singleElementMode) {
1474
+ slot = {
1475
+ bids: bids,
1476
+ ad: ad,
1477
+ mediaFile: mediaFile,
1478
+ videoEl: null,
1479
+ ready: true
1480
+ };
1481
+ preloadSlots.set(token, slot);
1482
+ if (debug) console.log("".concat(LOG, " [preload] Metadata-only preload (smartTV/singleElement), token=").concat(token, ", url=").concat(mediaFile.url));
1483
+ return [
1484
+ 2
1485
+ ];
1486
+ }
1520
1487
  videoEl = createAdVideoElement();
1521
1488
  videoEl.style.visibility = "hidden";
1522
1489
  videoEl.style.pointerEvents = "none";
@@ -1530,7 +1497,7 @@ function createPrebidAdLayer(contentVideo, options) {
1530
1497
  });
1531
1498
  hls.loadSource(mediaFile.url);
1532
1499
  hls.attachMedia(videoEl);
1533
- slot = {
1500
+ slot1 = {
1534
1501
  bids: bids,
1535
1502
  ad: ad,
1536
1503
  mediaFile: mediaFile,
@@ -1538,7 +1505,7 @@ function createPrebidAdLayer(contentVideo, options) {
1538
1505
  hlsInstance: hls,
1539
1506
  ready: false
1540
1507
  };
1541
- preloadSlots.set(token, slot);
1508
+ preloadSlots.set(token, slot1);
1542
1509
  hls.on(import_hls.default.Events.MANIFEST_PARSED, function() {
1543
1510
  var s = preloadSlots.get(token);
1544
1511
  if (s) s.ready = true;
@@ -1555,14 +1522,14 @@ function createPrebidAdLayer(contentVideo, options) {
1555
1522
  } else {
1556
1523
  videoEl.src = mediaFile.url;
1557
1524
  videoEl.load();
1558
- slot1 = {
1525
+ slot2 = {
1559
1526
  bids: bids,
1560
1527
  ad: ad,
1561
1528
  mediaFile: mediaFile,
1562
1529
  videoEl: videoEl,
1563
1530
  ready: false
1564
1531
  };
1565
- preloadSlots.set(token, slot1);
1532
+ preloadSlots.set(token, slot2);
1566
1533
  videoEl.addEventListener("canplay", function() {
1567
1534
  var s = preloadSlots.get(token);
1568
1535
  if (s) s.ready = true;
@@ -1581,7 +1548,7 @@ function createPrebidAdLayer(contentVideo, options) {
1581
1548
  }
1582
1549
  function playPreloaded(token) {
1583
1550
  return _async_to_generator(function() {
1584
- var slot, contentVolume, adVolume, container;
1551
+ var slot, contentVolume, adVolume2, videoEl, container2, adVolume21, adVolume, container;
1585
1552
  return _ts_generator(this, function(_state) {
1586
1553
  if (destroyed) return [
1587
1554
  2,
@@ -1596,6 +1563,68 @@ function createPrebidAdLayer(contentVideo, options) {
1596
1563
  }
1597
1564
  preloadSlots.delete(token);
1598
1565
  if (debug) console.log("".concat(LOG, " [preload] Playing preloaded ad, token=").concat(token, ", ready=").concat(slot.ready));
1566
+ contentVolume = contentVideo.volume;
1567
+ originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
1568
+ sessionId = generateSessionId();
1569
+ currentAd = slot.ad;
1570
+ trackingFired = _object_spread({}, createEmptyTrackingState());
1571
+ fireTrackingPixels2(slot.ad.trackingUrls.impression);
1572
+ trackingFired.impression = true;
1573
+ if (singleElementMode) {
1574
+ mainHlsInstance === null || mainHlsInstance === void 0 ? void 0 : mainHlsInstance.detachMedia();
1575
+ teardownCurrentPlayback();
1576
+ adVideoElement = contentVideo;
1577
+ adHls = void 0;
1578
+ setupAdEventListeners();
1579
+ if (!continueLiveStreamDuringAds) {
1580
+ contentVideo.pause();
1581
+ }
1582
+ contentVideo.muted = true;
1583
+ contentVideo.volume = 0;
1584
+ adPlaying = true;
1585
+ setAdPlayingFlag(true);
1586
+ adVolume2 = originalMutedState ? 1 : originalVolume;
1587
+ contentVideo.volume = Math.max(0, Math.min(1, adVolume2));
1588
+ contentVideo.muted = false;
1589
+ emit("content_pause");
1590
+ if (debug) console.log("".concat(LOG, " [preload] singleElementMode: attaching ad to contentVideo, url=").concat(slot.mediaFile.url));
1591
+ startPlayback(slot.mediaFile);
1592
+ return [
1593
+ 2
1594
+ ];
1595
+ }
1596
+ if (smartTVMode && !slot.videoEl) {
1597
+ teardownCurrentPlayback();
1598
+ if (adVideoElement) {
1599
+ adVideoElement.remove();
1600
+ adVideoElement = void 0;
1601
+ }
1602
+ videoEl = createAdVideoElement();
1603
+ videoEl.style.visibility = "visible";
1604
+ videoEl.style.pointerEvents = "none";
1605
+ container2 = ensureAdContainer();
1606
+ container2.appendChild(videoEl);
1607
+ adVideoElement = videoEl;
1608
+ setupAdEventListeners();
1609
+ if (!continueLiveStreamDuringAds) {
1610
+ contentVideo.pause();
1611
+ }
1612
+ contentVideo.muted = true;
1613
+ contentVideo.volume = 0;
1614
+ adPlaying = true;
1615
+ setAdPlayingFlag(true);
1616
+ adVolume21 = originalMutedState ? 1 : originalVolume;
1617
+ adVideoElement.volume = Math.max(0, Math.min(1, adVolume21));
1618
+ adVideoElement.muted = false;
1619
+ container2.style.display = "flex";
1620
+ container2.style.pointerEvents = "auto";
1621
+ emit("content_pause");
1622
+ if (debug) console.log("".concat(LOG, " [preload] smartTVMode deferred: creating video element and loading, url=").concat(slot.mediaFile.url));
1623
+ startPlayback(slot.mediaFile);
1624
+ return [
1625
+ 2
1626
+ ];
1627
+ }
1599
1628
  teardownCurrentPlayback();
1600
1629
  if (adVideoElement && adVideoElement !== slot.videoEl) {
1601
1630
  adVideoElement.remove();
@@ -1605,13 +1634,6 @@ function createPrebidAdLayer(contentVideo, options) {
1605
1634
  adVideoElement = slot.videoEl;
1606
1635
  adHls = slot.hlsInstance;
1607
1636
  setupAdEventListeners();
1608
- sessionId = generateSessionId();
1609
- currentAd = slot.ad;
1610
- trackingFired = _object_spread({}, createEmptyTrackingState());
1611
- fireTrackingPixels2(slot.ad.trackingUrls.impression);
1612
- trackingFired.impression = true;
1613
- contentVolume = contentVideo.volume;
1614
- originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
1615
1637
  if (!continueLiveStreamDuringAds) {
1616
1638
  contentVideo.pause();
1617
1639
  }
@@ -1626,17 +1648,10 @@ function createPrebidAdLayer(contentVideo, options) {
1626
1648
  container.style.display = "flex";
1627
1649
  container.style.pointerEvents = "auto";
1628
1650
  emit("content_pause");
1629
- if (slot.hlsInstance) {
1630
- adVideoElement.play().catch(function(error) {
1631
- console.error("".concat(LOG, " [preload] Error playing preloaded HLS ad:"), error);
1632
- handleAdError();
1633
- });
1634
- } else {
1635
- adVideoElement.play().catch(function(error) {
1636
- console.error("".concat(LOG, " [preload] Error playing preloaded ad:"), error);
1637
- handleAdError();
1638
- });
1639
- }
1651
+ adVideoElement.play().catch(function(error) {
1652
+ console.error("".concat(LOG, " [preload] Error playing preloaded ad:"), error);
1653
+ handleAdError();
1654
+ });
1640
1655
  return [
1641
1656
  2
1642
1657
  ];
@@ -1650,10 +1665,12 @@ function createPrebidAdLayer(contentVideo, options) {
1650
1665
  if (slot.hlsInstance) {
1651
1666
  slot.hlsInstance.destroy();
1652
1667
  }
1653
- slot.videoEl.pause();
1654
- slot.videoEl.removeAttribute("src");
1655
- slot.videoEl.load();
1656
- slot.videoEl.remove();
1668
+ if (slot.videoEl) {
1669
+ slot.videoEl.pause();
1670
+ slot.videoEl.removeAttribute("src");
1671
+ slot.videoEl.load();
1672
+ slot.videoEl.remove();
1673
+ }
1657
1674
  if (debug) console.log("".concat(LOG, " [preload] Cancelled and cleaned up token=").concat(token));
1658
1675
  }
1659
1676
  return {
@@ -1701,20 +1718,27 @@ function createPrebidAdLayer(contentVideo, options) {
1701
1718
  setAdPlayingFlag(false);
1702
1719
  contentVideo.muted = originalMutedState;
1703
1720
  contentVideo.volume = originalMutedState ? 0 : originalVolume;
1704
- if (adContainerEl) {
1705
- adContainerEl.style.display = "none";
1706
- adContainerEl.style.pointerEvents = "none";
1707
- }
1708
1721
  contentVideo.style.visibility = "visible";
1709
1722
  contentVideo.style.opacity = "1";
1710
- if (continueLiveStreamDuringAds) {
1711
- contentVideo.play().catch(function() {});
1712
- }
1713
- teardownCurrentPlayback();
1714
- if (adVideoElement) {
1715
- adVideoElement.pause();
1716
- adVideoElement.removeAttribute("src");
1717
- adVideoElement.load();
1723
+ if (singleElementMode) {
1724
+ teardownCurrentPlayback();
1725
+ contentVideo.removeAttribute("src");
1726
+ contentVideo.load();
1727
+ adVideoElement = void 0;
1728
+ } else {
1729
+ if (adContainerEl) {
1730
+ adContainerEl.style.display = "none";
1731
+ adContainerEl.style.pointerEvents = "none";
1732
+ }
1733
+ if (continueLiveStreamDuringAds) {
1734
+ contentVideo.play().catch(function() {});
1735
+ }
1736
+ teardownCurrentPlayback();
1737
+ if (adVideoElement) {
1738
+ adVideoElement.pause();
1739
+ adVideoElement.removeAttribute("src");
1740
+ adVideoElement.load();
1741
+ }
1718
1742
  }
1719
1743
  currentAd = void 0;
1720
1744
  tornDown = false;
@@ -1754,9 +1778,14 @@ function createPrebidAdLayer(contentVideo, options) {
1754
1778
  }
1755
1779
  teardownCurrentPlayback();
1756
1780
  if (adVideoElement) {
1757
- adVideoElement.pause();
1758
- adVideoElement.removeAttribute("src");
1759
- adVideoElement.remove();
1781
+ if (singleElementMode && adVideoElement === contentVideo) {
1782
+ contentVideo.removeAttribute("src");
1783
+ contentVideo.load();
1784
+ } else {
1785
+ adVideoElement.pause();
1786
+ adVideoElement.removeAttribute("src");
1787
+ adVideoElement.remove();
1788
+ }
1760
1789
  adVideoElement = void 0;
1761
1790
  }
1762
1791
  if (adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.parentElement) {
@@ -2951,11 +2980,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2951
2980
  this.video = config.videoElement;
2952
2981
  this.adTransitionGapMs = (_this_config_adTransitionGapMs = this.config.adTransitionGapMs) !== null && _this_config_adTransitionGapMs !== void 0 ? _this_config_adTransitionGapMs : 100;
2953
2982
  logBrowserInfo(config.debugAdTiming);
2954
- this.prebidManager = createPrebidManager(config.debugAdTiming !== void 0 ? {
2983
+ this.vastManager = createVastManager(config.debugAdTiming !== void 0 ? {
2955
2984
  debug: !!config.debugAdTiming
2956
2985
  } : {});
2957
- this.adLayer = createPrebidAdLayer(this.video, {
2986
+ var browserForAdLayer = detectBrowser();
2987
+ this.adLayer = createVastAdLayer(this.video, {
2958
2988
  continueLiveStreamDuringAds: false,
2989
+ smartTVMode: browserForAdLayer.isSmartTV,
2990
+ singleElementMode: browserForAdLayer.isSmartTV,
2959
2991
  debug: !!config.debugAdTiming
2960
2992
  });
2961
2993
  }
@@ -2967,19 +2999,19 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2967
2999
  return _ts_generator(this, function(_state) {
2968
3000
  switch(_state.label){
2969
3001
  case 0:
2970
- if (this.config.disablePrebid) return [
3002
+ if (this.config.disableAds) return [
2971
3003
  2,
2972
3004
  []
2973
3005
  ];
2974
3006
  return [
2975
3007
  4,
2976
- this.prebidManager.initialize()
3008
+ this.vastManager.initialize()
2977
3009
  ];
2978
3010
  case 1:
2979
3011
  _state.sent();
2980
3012
  return [
2981
3013
  2,
2982
- this.prebidManager.requestBidsUntilResponse(context)
3014
+ this.vastManager.requestBidsUntilResponse(context)
2983
3015
  ];
2984
3016
  }
2985
3017
  });
@@ -3014,7 +3046,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3014
3046
  adBehavior: "vod (main video pauses during ads)"
3015
3047
  });
3016
3048
  }
3017
- if (!this.config.disablePrebid) {
3049
+ if (!this.config.disableAds) {
3018
3050
  this.adLayer.updateOptions({
3019
3051
  continueLiveStreamDuringAds: false,
3020
3052
  mainHlsInstance: null
@@ -3082,7 +3114,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3082
3114
  adBehavior: adBehavior
3083
3115
  });
3084
3116
  }
3085
- if (!this.config.disablePrebid) {
3117
+ if (!this.config.disableAds) {
3086
3118
  ;
3087
3119
  this.adLayer.updateOptions({
3088
3120
  continueLiveStreamDuringAds: this.shouldContinueLiveStreamDuringAds(),
@@ -3403,7 +3435,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3403
3435
  {
3404
3436
  key: "getAdSource",
3405
3437
  value: function getAdSource() {
3406
- return "prebid";
3438
+ return "vast";
3407
3439
  }
3408
3440
  },
3409
3441
  {
@@ -3649,7 +3681,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3649
3681
  this.attached = true;
3650
3682
  this.video.autoplay = !!this.config.autoplay;
3651
3683
  this.video.muted = !!this.config.muted;
3652
- if (!this.config.disablePrebid) {
3684
+ if (!this.config.disableAds) {
3653
3685
  this.adLayer.initialize();
3654
3686
  if (!this.config.disableFiller) {
3655
3687
  this.ensureFillerVideo();
@@ -3845,7 +3877,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3845
3877
  key: "onScte35Marker",
3846
3878
  value: function onScte35Marker(marker) {
3847
3879
  var _this = this;
3848
- if (this.config.disablePrebid) return;
3880
+ if (this.config.disableAds) return;
3849
3881
  if (this.config.debugAdTiming) {
3850
3882
  console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
3851
3883
  type: marker.type,
@@ -4317,13 +4349,17 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4317
4349
  if (!this.isLiveStream) {
4318
4350
  return false;
4319
4351
  }
4352
+ var browser = detectBrowser();
4353
+ if (browser.isSmartTV) {
4354
+ return false;
4355
+ }
4320
4356
  return true;
4321
4357
  }
4322
4358
  },
4323
4359
  {
4324
4360
  key: "startAdPrefetch",
4325
4361
  value: function startAdPrefetch(marker, fragmentSn) {
4326
- if (this.config.disablePrebid) return;
4362
+ if (this.config.disableAds) return;
4327
4363
  if (this.pendingAdBreak || this.inAdBreak) {
4328
4364
  return;
4329
4365
  }
@@ -4345,25 +4381,75 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4345
4381
  key: "runAdPrefetch",
4346
4382
  value: function runAdPrefetch(marker) {
4347
4383
  return _async_to_generator(function() {
4348
- var _this, _marker_durationSeconds, durSec, estimatedCount, context, fetches, results, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, result, token;
4384
+ var _this, _marker_durationSeconds, _ref, _firstBids_, durSec, context, firstBids, unused, adDurationSec, estimatedCount, firstToken, remaining, results, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, result, token;
4349
4385
  return _ts_generator(this, function(_state) {
4350
4386
  switch(_state.label){
4351
4387
  case 0:
4352
4388
  _this = this;
4353
4389
  durSec = (_marker_durationSeconds = marker.durationSeconds) !== null && _marker_durationSeconds !== void 0 ? _marker_durationSeconds : 60;
4354
- estimatedCount = Math.min(4, Math.max(1, Math.ceil(durSec / 30)));
4355
- if (this.config.debugAdTiming) {
4356
- console.log("[PREFETCH] Firing ".concat(estimatedCount, " parallel bid request(s) for ").concat(durSec, "s break"));
4357
- }
4358
4390
  context = {
4359
4391
  breakDurationSec: durSec,
4360
4392
  remainingBreakSec: durSec
4361
4393
  };
4362
- fetches = Array.from({
4363
- length: estimatedCount
4394
+ _state.label = 1;
4395
+ case 1:
4396
+ _state.trys.push([
4397
+ 1,
4398
+ 3,
4399
+ ,
4400
+ 4
4401
+ ]);
4402
+ return [
4403
+ 4,
4404
+ this.adRequest(_object_spread_props(_object_spread({}, context), {
4405
+ adIndex: 1
4406
+ }))
4407
+ ];
4408
+ case 2:
4409
+ firstBids = _state.sent();
4410
+ return [
4411
+ 3,
4412
+ 4
4413
+ ];
4414
+ case 3:
4415
+ unused = _state.sent();
4416
+ firstBids = [];
4417
+ return [
4418
+ 3,
4419
+ 4
4420
+ ];
4421
+ case 4:
4422
+ if (this.inAdBreak) return [
4423
+ 2
4424
+ ];
4425
+ if (firstBids.length === 0) {
4426
+ if (this.config.debugAdTiming) {
4427
+ console.log("[PREFETCH] First VAST request returned no ad, aborting prefetch");
4428
+ }
4429
+ return [
4430
+ 2
4431
+ ];
4432
+ }
4433
+ adDurationSec = (_ref = (_firstBids_ = firstBids[0]) === null || _firstBids_ === void 0 ? void 0 : _firstBids_.durationSec) !== null && _ref !== void 0 ? _ref : 30;
4434
+ estimatedCount = Math.max(1, Math.ceil(durSec / adDurationSec));
4435
+ if (this.config.debugAdTiming) {
4436
+ console.log("[PREFETCH] Ad duration=".concat(adDurationSec, "s, break=").concat(durSec, "s → ").concat(estimatedCount, " ad(s) needed"));
4437
+ }
4438
+ firstToken = "preload_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 7));
4439
+ this.preloadedTokens.push(firstToken);
4440
+ void this.adLayer.preloadAd(firstBids, firstToken);
4441
+ if (this.config.debugAdTiming) {
4442
+ console.log("[PREFETCH] First ad preloading, token=".concat(firstToken));
4443
+ }
4444
+ if (!(estimatedCount > 1)) return [
4445
+ 3,
4446
+ 6
4447
+ ];
4448
+ remaining = Array.from({
4449
+ length: estimatedCount - 1
4364
4450
  }, function(_, i) {
4365
4451
  return _this.adRequest(_object_spread_props(_object_spread({}, context), {
4366
- adIndex: i + 1
4452
+ adIndex: i + 2
4367
4453
  })).then(function(bids) {
4368
4454
  return {
4369
4455
  ok: true,
@@ -4377,9 +4463,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4377
4463
  });
4378
4464
  return [
4379
4465
  4,
4380
- Promise.all(fetches)
4466
+ Promise.all(remaining)
4381
4467
  ];
4382
- case 1:
4468
+ case 5:
4383
4469
  results = _state.sent();
4384
4470
  _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
4385
4471
  try {
@@ -4391,7 +4477,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4391
4477
  this.preloadedTokens.push(token);
4392
4478
  void this.adLayer.preloadAd(result.value, token);
4393
4479
  if (this.config.debugAdTiming) {
4394
- console.log("[PREFETCH] Bid received, preloading video token=".concat(token));
4480
+ console.log("[PREFETCH] Additional ad preloading, token=".concat(token));
4395
4481
  }
4396
4482
  }
4397
4483
  }
@@ -4409,6 +4495,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4409
4495
  }
4410
4496
  }
4411
4497
  }
4498
+ _state.label = 6;
4499
+ case 6:
4412
4500
  if (this.config.debugAdTiming) {
4413
4501
  console.log("[PREFETCH] Pre-fetch complete: ".concat(this.preloadedTokens.length, " ad(s) queued"));
4414
4502
  }
@@ -4472,7 +4560,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4472
4560
  switch(_state.label){
4473
4561
  case 0:
4474
4562
  _loop = function() {
4475
- var remaining, prefetchContext, bids, err, bids1, remainingNow, delay, elapsed, remaining1, context, bids2, remainingNow1, err1;
4563
+ var remaining, prefetchContext, bids, err, bids1, remainingNow, urgentNeedAd, delay, elapsed, remaining1, context, bids2, remainingNow1, err1, sleepMs;
4476
4564
  return _ts_generator(this, function(_state) {
4477
4565
  switch(_state.label){
4478
4566
  case 0:
@@ -4523,6 +4611,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4523
4611
  if (bids.length > 0) {
4524
4612
  _this.consecutiveFailures = 0;
4525
4613
  _this.pendingNextAdBids = bids;
4614
+ _this.totalAdsInBreak = Math.max(_this.totalAdsInBreak, _this.currentAdIndex + _this.preloadedTokens.length + 1);
4526
4615
  if (_this.config.debugAdTiming) {
4527
4616
  console.log("[CONTINUOUS-FETCH] Pre-fetched next ad stored as pending");
4528
4617
  }
@@ -4607,7 +4696,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4607
4696
  "continue"
4608
4697
  ];
4609
4698
  case 12:
4610
- delay = _this.lastAdRequestTime ? _this.minAdRequestIntervalMs + (_this.consecutiveFailures > 0 ? backoffMs() : 0) : 0;
4699
+ urgentNeedAd = _this.inAdBreak && !_this.adLayer.isAdPlaying();
4700
+ delay = _this.lastAdRequestTime ? _this.minAdRequestIntervalMs + (!urgentNeedAd && _this.consecutiveFailures > 0 ? backoffMs() : 0) : 0;
4611
4701
  elapsed = Date.now() - _this.lastAdRequestTime;
4612
4702
  if (!(elapsed < delay && _this.lastAdRequestTime > 0)) return [
4613
4703
  3,
@@ -4662,6 +4752,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4662
4752
  17
4663
4753
  ];
4664
4754
  _this.pendingNextAdBids = bids2;
4755
+ _this.totalAdsInBreak = Math.max(_this.totalAdsInBreak, _this.currentAdIndex + _this.preloadedTokens.length + 1);
4665
4756
  if (_this.config.debugAdTiming) {
4666
4757
  console.log("[CONTINUOUS-FETCH] Next ad response stored (ad currently playing or in transition)");
4667
4758
  }
@@ -4725,10 +4816,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4725
4816
  24
4726
4817
  ];
4727
4818
  case 24:
4819
+ sleepMs = _this.inAdBreak && !_this.adLayer.isAdPlaying() ? 0 : backoffMs();
4728
4820
  return [
4729
4821
  4,
4730
4822
  new Promise(function(r) {
4731
- return setTimeout(r, backoffMs());
4823
+ return setTimeout(r, sleepMs);
4732
4824
  })
4733
4825
  ];
4734
4826
  case 25:
@@ -4815,7 +4907,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4815
4907
  this.inAdBreak = true;
4816
4908
  this.currentAdBreakStartWallClockMs = Date.now();
4817
4909
  this.currentAdIndex = 0;
4818
- this.totalAdsInBreak = 1;
4910
+ this.totalAdsInBreak = Math.max(1, this.preloadedTokens.length);
4819
4911
  this.adPodQueue = [];
4820
4912
  if (!this.config.disableFiller) this.showAds = true;
4821
4913
  if (adBreakDurationMs != null) {
@@ -5040,6 +5132,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5040
5132
  3
5041
5133
  ];
5042
5134
  this.pendingNextAdBids = bids;
5135
+ this.totalAdsInBreak = Math.max(this.totalAdsInBreak, this.currentAdIndex + this.preloadedTokens.length);
5043
5136
  return [
5044
5137
  3,
5045
5138
  5
@@ -5408,40 +5501,45 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5408
5501
  var browser = detectBrowser();
5409
5502
  var isSmartTV = browser.tizenVersion !== void 0 || browser.webOSVersion !== void 0;
5410
5503
  if (isSmartTV && this.hls) {
5411
- if (!restoredMuted) {
5412
- var hlsRef = this.hls;
5413
- var savedMuted = restoredMuted;
5414
- var savedVolume = restoredVolume;
5415
- var onManifestParsedRestore = function onManifestParsedRestore1() {
5416
- hlsRef.off(import_hls2.default.Events.MANIFEST_PARSED, onManifestParsedRestore);
5417
- if (!_this.inAdBreak && !_this.adLayer.isAdPlaying()) {
5418
- if (_this.video.muted !== savedMuted) _this.video.muted = savedMuted;
5419
- if (Math.abs(_this.video.volume - savedVolume) > 0.01) _this.video.volume = savedVolume;
5420
- if (_this.config.debugAdTiming) {
5421
- console.log("[StormcloudVideoPlayer] Smart TV: audio state restored on MANIFEST_PARSED after re-attach");
5422
- }
5504
+ var hlsRef = this.hls;
5505
+ var savedMuted = restoredMuted;
5506
+ var savedVolume = restoredVolume;
5507
+ var onManifestParsedRestore = function onManifestParsedRestore1() {
5508
+ hlsRef.off(import_hls2.default.Events.MANIFEST_PARSED, onManifestParsedRestore);
5509
+ if (!_this.inAdBreak && !_this.adLayer.isAdPlaying()) {
5510
+ var _this_video_play;
5511
+ if (_this.video.muted !== savedMuted) _this.video.muted = savedMuted;
5512
+ if (Math.abs(_this.video.volume - savedVolume) > 0.01) _this.video.volume = savedVolume;
5513
+ if (_this.config.debugAdTiming) {
5514
+ console.log("[StormcloudVideoPlayer] Smart TV: audio state restored on MANIFEST_PARSED after re-attach");
5423
5515
  }
5424
- };
5425
- hlsRef.on(import_hls2.default.Events.MANIFEST_PARSED, onManifestParsedRestore);
5426
- }
5516
+ hlsRef.startLoad(-1);
5517
+ (_this_video_play = _this.video.play()) === null || _this_video_play === void 0 ? void 0 : _this_video_play.catch(function() {});
5518
+ if (_this.config.debugAdTiming) {
5519
+ console.log("[StormcloudVideoPlayer] Smart TV: seeking to live edge and resuming playback after re-attach");
5520
+ }
5521
+ }
5522
+ };
5523
+ hlsRef.on(import_hls2.default.Events.MANIFEST_PARSED, onManifestParsedRestore);
5427
5524
  this.hls.attachMedia(this.video);
5428
5525
  if (this.config.debugAdTiming) {
5429
5526
  console.log("[StormcloudVideoPlayer] Smart TV: re-attached HLS to video element after ad break to restore media pipeline");
5430
5527
  }
5431
- }
5432
- if (this.shouldContinueLiveStreamDuringAds()) {
5433
- var _this_video_play;
5434
- if (this.config.debugAdTiming) {
5435
- if (this.video.paused) {
5436
- console.log("[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback");
5437
- } else {
5438
- console.log("[StormcloudVideoPlayer] Content video already playing in live mode after ads");
5528
+ } else {
5529
+ if (this.shouldContinueLiveStreamDuringAds()) {
5530
+ var _this_video_play;
5531
+ if (this.config.debugAdTiming) {
5532
+ if (this.video.paused) {
5533
+ console.log("[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback");
5534
+ } else {
5535
+ console.log("[StormcloudVideoPlayer] Content video already playing in live mode after ads");
5536
+ }
5439
5537
  }
5538
+ (_this_video_play = this.video.play()) === null || _this_video_play === void 0 ? void 0 : _this_video_play.catch(function() {});
5539
+ } else if (this.video.paused) {
5540
+ var _this_video_play1;
5541
+ (_this_video_play1 = this.video.play()) === null || _this_video_play1 === void 0 ? void 0 : _this_video_play1.catch(function() {});
5440
5542
  }
5441
- (_this_video_play = this.video.play()) === null || _this_video_play === void 0 ? void 0 : _this_video_play.catch(function() {});
5442
- } else if (this.video.paused) {
5443
- var _this_video_play1;
5444
- (_this_video_play1 = this.video.play()) === null || _this_video_play1 === void 0 ? void 0 : _this_video_play1.catch(function() {});
5445
5543
  }
5446
5544
  this.syncMainContentAudioWhenVisible();
5447
5545
  if (!restoredMuted) {
@@ -5492,6 +5590,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5492
5590
  console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Max consecutive failures reached (".concat(this.consecutiveFailures, "), ending ad break gracefully"));
5493
5591
  }
5494
5592
  this.handleAdPodComplete();
5593
+ return;
5594
+ }
5595
+ if (this.inAdBreak && !this.config.disableFiller) {
5596
+ if (this.config.debugAdTiming) {
5597
+ console.log("[CONTINUOUS-FETCH] Ad failure in active break \u2014 showing filler while awaiting next ad");
5598
+ }
5599
+ this.showPlaceholderLayer();
5600
+ this.adLayer.showPlaceholder();
5495
5601
  }
5496
5602
  }
5497
5603
  },
@@ -5868,7 +5974,7 @@ var HlsPlayer = /*#__PURE__*/ function(_import_react2_Component) {
5868
5974
  if (_this1.props.licenseKey !== void 0) config.licenseKey = _this1.props.licenseKey;
5869
5975
  if (_this1.props.adFailsafeTimeoutMs !== void 0) config.adFailsafeTimeoutMs = _this1.props.adFailsafeTimeoutMs;
5870
5976
  if (_this1.props.minSegmentsBeforePlay !== void 0) config.minSegmentsBeforePlay = _this1.props.minSegmentsBeforePlay;
5871
- if (_this1.props.disablePrebid !== void 0) config.disablePrebid = _this1.props.disablePrebid;
5977
+ if (_this1.props.disableAds !== void 0) config.disableAds = _this1.props.disableAds;
5872
5978
  _this1.player = new StormcloudVideoPlayer(config);
5873
5979
  (_this_props_onMount = (_this_props = _this1.props).onMount) === null || _this_props_onMount === void 0 ? void 0 : _this_props_onMount.call(_this_props, _this1);
5874
5980
  return [