@xibosignage/xibo-layout-renderer 1.0.23 → 1.0.24

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.
@@ -72516,6 +72516,269 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
72516
72516
  videojs.registerPlugin('reloadSourceOnError', reloadSourceOnError);
72517
72517
  }
72518
72518
 
72519
+ function composeVideoSource($media, media) {
72520
+ // const videoSrc = await preloadMediaBlob(media.url as string, media.mediaType as MediaTypes);
72521
+ var vidType = videoFileType(getFileExt(media.uri));
72522
+ // Only add one source per type
72523
+ if ($media.querySelectorAll("source[type=\"".concat(vidType, "\"]")).length === 0) {
72524
+ var $videoSource = document.createElement('source');
72525
+ $videoSource.src = media.url;
72526
+ $videoSource.type = vidType;
72527
+ $media.insertBefore($videoSource, $media.lastElementChild);
72528
+ }
72529
+ return $media;
72530
+ }
72531
+ var defaultVjsOpts = {
72532
+ autoplay: false,
72533
+ muted: true,
72534
+ // Start muted to allow autoplay policies
72535
+ preload: 'auto',
72536
+ controls: false
72537
+ };
72538
+ var vjsDefaultOptions = function vjsDefaultOptions(opts) {
72539
+ return _objectSpread2({
72540
+ controls: false,
72541
+ preload: 'auto',
72542
+ autoplay: false,
72543
+ muted: true
72544
+ }, opts);
72545
+ };
72546
+ var reportToPlayerPlatform = [exports.ConsumerPlatform.CHROMEOS, exports.ConsumerPlatform.ELECTRON];
72547
+ function VideoMedia(media, xlr) {
72548
+ var mediaId = getMediaId(media);
72549
+ var videoPlayer = {
72550
+ duration: 0,
72551
+ init: function init() {
72552
+ var _this = this;
72553
+ var triggerTimeUpdate = false; // Used for media.duration === 0
72554
+ videoPlayer.duration = media.duration;
72555
+ var vjsPlayer = videojs(mediaId);
72556
+ if (vjsPlayer) {
72557
+ vjsPlayer.on('loadstart', function () {
72558
+ console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has started loading data . . ."));
72559
+ });
72560
+ vjsPlayer.on('loadedmetadata', function () {
72561
+ if (media.duration === 0) {
72562
+ videoPlayer.duration = vjsPlayer.duration();
72563
+ }
72564
+ console.debug('??? XLR.debug >> VideoMedia: loadedmetadata: Setting video duration to = ' + videoPlayer.duration);
72565
+ });
72566
+ vjsPlayer.on('canplay', function () {
72567
+ console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " can be played . . ."));
72568
+ });
72569
+ vjsPlayer.on('playing', function () {
72570
+ // Update duration
72571
+ if (videoPlayer.duration === 0) {
72572
+ videoPlayer.duration = vjsPlayer.duration();
72573
+ }
72574
+ console.debug('??? XLR.debug >> VideoMedia: playing: Showing Media ' + media.id + ' for ' + videoPlayer.duration + 's of Region ' + media.region.regionId);
72575
+ console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " is now playing . . ."));
72576
+ });
72577
+ // @NOTE: When video is paused due to fail in unmuting the video
72578
+ // and video has media.duration = 0, the video will stay paused and the video cycle won't end
72579
+ // @TODO: Add timer when video is paused due to unmuting fail and duration that is equal to 0
72580
+ // @NOTE: The pause issue when unmuting the video is mainly on a browser level.
72581
+ // Please visit https://developer.chrome.com/blog/autoplay/ for more info.
72582
+ vjsPlayer.ready(function () {
72583
+ // Add guard making sure that video element is present
72584
+ var videoElem = document.querySelector(".media--item.".concat(mediaId));
72585
+ if (!document.body.contains(videoElem)) {
72586
+ media.emitter.emit('cancelled', media);
72587
+ return;
72588
+ }
72589
+ if (vjsPlayer !== undefined) {
72590
+ vjsPlayer.muted(true);
72591
+ // Race promise between a 0.5s play and a 5s skip
72592
+ Promise.race([new Promise(function (resolve, reject) {
72593
+ return setTimeout( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
72594
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
72595
+ while (1) switch (_context.prev = _context.next) {
72596
+ case 0:
72597
+ console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Trying to force play after 0.1 seconds"));
72598
+ // Try to force play here
72599
+ _context.prev = 1;
72600
+ if (!(vjsPlayer.currentTime() === 0)) {
72601
+ _context.next = 6;
72602
+ break;
72603
+ }
72604
+ // Set video mute/unmute based on setting once playing
72605
+ vjsPlayer.muted(media.muted);
72606
+ _context.next = 6;
72607
+ return vjsPlayer.play();
72608
+ case 6:
72609
+ // Resolve if play works
72610
+ resolve(true);
72611
+ _context.next = 12;
72612
+ break;
72613
+ case 9:
72614
+ _context.prev = 9;
72615
+ _context.t0 = _context["catch"](1);
72616
+ // Reject race if play fails
72617
+ reject('Play failed');
72618
+ case 12:
72619
+ case "end":
72620
+ return _context.stop();
72621
+ }
72622
+ }, _callee, null, [[1, 9]]);
72623
+ })), 100);
72624
+ }), new Promise(function (_, reject) {
72625
+ return setTimeout(function () {
72626
+ return reject('Timeout');
72627
+ }, 5000);
72628
+ })]).then(function () {
72629
+ console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Autoplay started"));
72630
+ })["catch"]( /*#__PURE__*/function () {
72631
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(error) {
72632
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
72633
+ while (1) switch (_context2.prev = _context2.next) {
72634
+ case 0:
72635
+ if (error === 'Timeout') {
72636
+ console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Promise not resolved within 5 seconds. Move to next media"));
72637
+ _this.stop();
72638
+ } else {
72639
+ console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Autoplay error: ").concat(error));
72640
+ if (reportToPlayerPlatform.includes(xlr.config.platform)) {
72641
+ playerReportFault('Media autoplay error', media).then(function () {
72642
+ _this.stop();
72643
+ });
72644
+ }
72645
+ }
72646
+ case 1:
72647
+ case "end":
72648
+ return _context2.stop();
72649
+ }
72650
+ }, _callee2);
72651
+ }));
72652
+ return function (_x) {
72653
+ return _ref2.apply(this, arguments);
72654
+ };
72655
+ }());
72656
+ // Optional: Reset the flag automatically when a new video loads or the source changes
72657
+ vjsPlayer.on('loadstart', function () {
72658
+ triggerTimeUpdate = false;
72659
+ });
72660
+ if (media.duration === 0) {
72661
+ vjsPlayer.on('timeupdate', function () {
72662
+ var preloadBufferTimeMs = 2000;
72663
+ var mediaDuration = vjsPlayer.duration();
72664
+ var currentTime = vjsPlayer.currentTime();
72665
+ var regionHasMultipleMedia = media.region.totalMediaObjects > 1;
72666
+ var remainingTimeMs = 0;
72667
+ if (mediaDuration !== undefined && currentTime !== undefined) {
72668
+ remainingTimeMs = (mediaDuration - currentTime) * 1000;
72669
+ }
72670
+ if (regionHasMultipleMedia && remainingTimeMs === 0 && !triggerTimeUpdate) {
72671
+ // We don't have data yet and we must immediately prepare next media
72672
+ media.region.prepareNextMedia();
72673
+ } else if (regionHasMultipleMedia && remainingTimeMs <= preloadBufferTimeMs && !triggerTimeUpdate) {
72674
+ // Check if remaining time is less than preloadBufferTimeMs and the action hasn't been triggered yet
72675
+ console.log('Less than preloadBufferTimeMs remaining! Do something now.');
72676
+ // Prepare next media in region
72677
+ media.region.prepareNextMedia();
72678
+ triggerTimeUpdate = true; // Set the flag to prevent re-triggering
72679
+ }
72680
+ // Reset the flag if the user seeks back to a point where more than preloadBufferTimeMs remain
72681
+ if (remainingTimeMs > preloadBufferTimeMs) {
72682
+ triggerTimeUpdate = false;
72683
+ }
72684
+ });
72685
+ }
72686
+ }
72687
+ });
72688
+ vjsPlayer.on('error', /*#__PURE__*/function () {
72689
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(err) {
72690
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
72691
+ while (1) switch (_context3.prev = _context3.next) {
72692
+ case 0:
72693
+ console.debug("??? XLR.debug >> VideoMedia: Media Error: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id));
72694
+ if (reportToPlayerPlatform.includes(xlr.config.platform)) {
72695
+ playerReportFault('Video file source not supported', media).then(function () {
72696
+ _this.stop();
72697
+ });
72698
+ } else {
72699
+ // End media after 5 seconds
72700
+ setTimeout(function () {
72701
+ console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has ended . . ."));
72702
+ _this.stop();
72703
+ }, 5000);
72704
+ }
72705
+ case 2:
72706
+ case "end":
72707
+ return _context3.stop();
72708
+ }
72709
+ }, _callee3);
72710
+ }));
72711
+ return function (_x2) {
72712
+ return _ref3.apply(this, arguments);
72713
+ };
72714
+ }());
72715
+ if (media.duration === 0) {
72716
+ vjsPlayer.on('ended', function () {
72717
+ console.debug("??? XLR.debug >> VideoMedia: onended: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has ended playing . . ."));
72718
+ _this.stop();
72719
+ });
72720
+ }
72721
+ }
72722
+ },
72723
+ stop: function stop() {
72724
+ var disposeOnly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
72725
+ var vjsPlayer = media.player;
72726
+ console.debug('??? XLR.debug >> VideoMedia::stop', {
72727
+ vjsPlayer: vjsPlayer,
72728
+ isDisposed: vjsPlayer === null || vjsPlayer === void 0 ? void 0 : vjsPlayer.isDisposed_,
72729
+ el: vjsPlayer === null || vjsPlayer === void 0 ? void 0 : vjsPlayer.el_
72730
+ });
72731
+ // Expire the media and dispose the video
72732
+ if (vjsPlayer !== undefined && !vjsPlayer.isDisposed_) {
72733
+ if (!disposeOnly) {
72734
+ media.emitter.emit('end', media);
72735
+ }
72736
+ vjsPlayer.dispose();
72737
+ // Clear up media player
72738
+ media.player = undefined;
72739
+ } else {
72740
+ media.player = undefined;
72741
+ media.html = null;
72742
+ media.emitter.emit('end', media);
72743
+ }
72744
+ },
72745
+ play: function play() {
72746
+ var _this2 = this;
72747
+ var vjsPlayer = videojs(mediaId);
72748
+ if (vjsPlayer !== undefined) {
72749
+ var _vjsPlayer$play;
72750
+ (_vjsPlayer$play = vjsPlayer.play()) === null || _vjsPlayer$play === void 0 || _vjsPlayer$play["catch"]( /*#__PURE__*/function () {
72751
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(error) {
72752
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
72753
+ while (1) switch (_context4.prev = _context4.next) {
72754
+ case 0:
72755
+ if (error === 'Timeout') {
72756
+ console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Promise not resolved within 5 seconds. Move to next media"));
72757
+ _this2.stop();
72758
+ } else {
72759
+ console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Autoplay error: ").concat(error));
72760
+ if (reportToPlayerPlatform.includes(xlr.config.platform)) {
72761
+ playerReportFault('Media autoplay error', media).then(function () {
72762
+ _this2.stop();
72763
+ });
72764
+ }
72765
+ }
72766
+ case 1:
72767
+ case "end":
72768
+ return _context4.stop();
72769
+ }
72770
+ }, _callee4);
72771
+ }));
72772
+ return function (_x3) {
72773
+ return _ref4.apply(this, arguments);
72774
+ };
72775
+ }());
72776
+ }
72777
+ }
72778
+ };
72779
+ return videoPlayer;
72780
+ }
72781
+
72519
72782
  /*
72520
72783
  * Copyright (C) 2024 Xibo Signage Ltd
72521
72784
  *
@@ -72750,65 +73013,6 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
72750
73013
  return keyframes;
72751
73014
  };
72752
73015
 
72753
- function AudioMedia(media) {
72754
- var audioMediaObject = {
72755
- init: function init() {
72756
- var $audioMedia = document.getElementById(getMediaId(media));
72757
- var $playBtn = null;
72758
- if ($audioMedia) {
72759
- $audioMedia.onloadstart = function () {
72760
- console.debug("".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has started loading data . . ."));
72761
- };
72762
- $audioMedia.onloadeddata = function () {
72763
- if ($audioMedia.readyState >= 2) {
72764
- console.debug("".concat(capitalizeStr(media.mediaType), " data for media > ").concat(media.id, " has been fully loaded . . ."));
72765
- }
72766
- };
72767
- $audioMedia.oncanplay = function () {
72768
- console.debug("".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " can be played . . ."));
72769
- };
72770
- $audioMedia.onplaying = function () {
72771
- console.debug("".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " is now playing . . ."));
72772
- if ($playBtn !== null) {
72773
- $playBtn.remove();
72774
- }
72775
- };
72776
- var audioPlayPromise = $audioMedia.play();
72777
- if (audioPlayPromise !== undefined) {
72778
- audioPlayPromise.then(function () {
72779
- console.debug('autoplay started . . .');
72780
- // Autoplay restarted
72781
- })["catch"](function (error) {
72782
- if (error.name === 'NotAllowedError') {
72783
- var _$audioMedia$parentNo;
72784
- // Let's show a play audio button
72785
- $playBtn = document.createElement('button');
72786
- $playBtn.classList.add('play-audio-btn');
72787
- $playBtn.textContent = 'Play Audio';
72788
- $playBtn.addEventListener('click', function () {
72789
- $audioMedia.muted = false;
72790
- $audioMedia.play();
72791
- });
72792
- (_$audioMedia$parentNo = $audioMedia.parentNode) === null || _$audioMedia$parentNo === void 0 || _$audioMedia$parentNo.insertBefore($playBtn, $audioMedia.nextSibling);
72793
- }
72794
- });
72795
- }
72796
- if (media.duration === 0) {
72797
- $audioMedia.ondurationchange = function () {
72798
- console.debug('Showing Media ' + media.id + ' for ' + $audioMedia.duration + 's of Region ' + media.region.regionId);
72799
- };
72800
- $audioMedia.onended = function () {
72801
- var _media$emitter;
72802
- console.debug("".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has ended playing . . ."));
72803
- (_media$emitter = media.emitter) === null || _media$emitter === void 0 || _media$emitter.emit('end', media);
72804
- };
72805
- }
72806
- }
72807
- }
72808
- };
72809
- return audioMediaObject;
72810
- }
72811
-
72812
73016
  var BlobLoader = /*#__PURE__*/function () {
72813
73017
  function BlobLoader() {
72814
73018
  _classCallCheck(this, BlobLoader);
@@ -72950,1102 +73154,253 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
72950
73154
  PreviewTranslations["target"] = "Target";
72951
73155
  })(PreviewTranslations || (PreviewTranslations = {}));
72952
73156
 
72953
- function composeVideoSource($media, media) {
72954
- // const videoSrc = await preloadMediaBlob(media.url as string, media.mediaType as MediaTypes);
72955
- var vidType = videoFileType(getFileExt(media.uri));
72956
- // Only add one source per type
72957
- if ($media.querySelectorAll("source[type=\"".concat(vidType, "\"]")).length === 0) {
72958
- var $videoSource = document.createElement('source');
72959
- $videoSource.src = media.url;
72960
- $videoSource.type = vidType;
72961
- $media.insertBefore($videoSource, $media.lastElementChild);
73157
+ function nextId(options) {
73158
+ if (options.idCounter > 500) {
73159
+ options.idCounter = 0;
72962
73160
  }
72963
- return $media;
73161
+ options.idCounter = options.idCounter + 1;
73162
+ return options.idCounter;
72964
73163
  }
72965
- var defaultVjsOpts = {
72966
- autoplay: false,
72967
- muted: true,
72968
- // Start muted to allow autoplay policies
72969
- preload: 'auto',
72970
- controls: false
73164
+ var getMediaId = function getMediaId(_ref) {
73165
+ var mediaType = _ref.mediaType,
73166
+ containerName = _ref.containerName;
73167
+ var mediaId = containerName;
73168
+ if (mediaType === 'video') {
73169
+ mediaId = mediaId + '-vid';
73170
+ } else if (mediaType === 'audio') {
73171
+ mediaId = mediaId + '-aud';
73172
+ }
73173
+ return mediaId;
72971
73174
  };
72972
- var vjsDefaultOptions = function vjsDefaultOptions(opts) {
72973
- return _objectSpread2({
72974
- controls: false,
72975
- preload: 'auto',
72976
- autoplay: false,
72977
- muted: true
72978
- }, opts);
73175
+ var capitalizeStr = function capitalizeStr(inputStr) {
73176
+ if (inputStr === null) {
73177
+ return '';
73178
+ }
73179
+ return String(inputStr).charAt(0).toUpperCase() + String(inputStr).substring(1);
72979
73180
  };
72980
- function videoMediaHandler(media, platform) {
72981
- var videoPlayer = {
72982
- player: undefined,
72983
- duration: 0,
72984
- stop: function stop(disposeOnly) {}
72985
- };
72986
- var playerReportFault = /*#__PURE__*/function () {
72987
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(msg) {
72988
- var playerSW, hasSW;
72989
- return _regeneratorRuntime().wrap(function _callee$(_context) {
72990
- while (1) switch (_context.prev = _context.next) {
72991
- case 0:
72992
- // Immediately expire media and report a fault
72993
- playerSW = PwaSW();
72994
- _context.next = 3;
72995
- return playerSW.getSW();
72996
- case 3:
72997
- hasSW = _context.sent;
72998
- media.region.layout.state = exports.ELayoutState.ERROR;
72999
- media.region.layout.errorCode = 405;
73000
- if (hasSW) {
73001
- playerSW.postMsg({
73002
- type: 'MEDIA_FAULT',
73003
- code: 5002,
73004
- reason: msg,
73005
- mediaId: media.id,
73006
- regionId: media.region.id,
73007
- layoutId: media.region.layout.id,
73008
- date: format(new Date(), 'yyyy-MM-dd HH:mm:ss'),
73009
- // Temporary setting
73010
- expires: format(new Date(setExpiry(1)), 'yyyy-MM-dd HH:mm:ss')
73011
- })["finally"](function () {
73012
- videoPlayer.stop();
73013
- });
73014
- } else {
73015
- videoPlayer.stop();
73181
+ function getDataBlob(_x, _x2) {
73182
+ return _getDataBlob.apply(this, arguments);
73183
+ }
73184
+ function _getDataBlob() {
73185
+ _getDataBlob = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(src, jwtToken) {
73186
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
73187
+ while (1) switch (_context3.prev = _context3.next) {
73188
+ case 0:
73189
+ return _context3.abrupt("return", fetch(src, {
73190
+ method: 'GET',
73191
+ headers: {
73192
+ 'X-PREVIEW-JWT': jwtToken || ''
73016
73193
  }
73017
- case 7:
73018
- case "end":
73019
- return _context.stop();
73020
- }
73021
- }, _callee);
73022
- }));
73023
- return function playerReportFault(_x) {
73024
- return _ref.apply(this, arguments);
73025
- };
73026
- }();
73027
- videoPlayer.duration = media.duration;
73028
- if (media.player) {
73029
- videoPlayer.player = media.player;
73030
- } else {
73031
- // Load on demand if it has not been cached
73032
- var vjsElem = media.html;
73033
- var vidType = videoFileType(getFileExt(media.uri));
73034
- if (vjsElem === null) {
73035
- // Use media containerName instead for VJS id
73036
- vjsElem = media.containerName;
73037
- }
73038
- videoPlayer.player = videojs(vjsElem, _objectSpread2(_objectSpread2({}, defaultVjsOpts), {}, {
73039
- sources: [{
73040
- src: media.url,
73041
- type: vidType
73042
- }]
73043
- }));
73044
- media.player = videoPlayer.player;
73045
- }
73046
- videoPlayer.stop = function () {
73047
- var disposeOnly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
73048
- // Expire the media and dispose the video
73049
- if (videoPlayer.player !== undefined) {
73050
- if (!disposeOnly) {
73051
- media.emitter.emit('end', media);
73194
+ }).then(function (res) {
73195
+ return res.blob();
73196
+ }).then(function (blob) {
73197
+ return new Promise(function (res, rej) {
73198
+ var reader = new FileReader();
73199
+ reader.onloadend = function () {
73200
+ return res(reader.result);
73201
+ };
73202
+ reader.onerror = rej;
73203
+ reader.readAsDataURL(blob);
73204
+ });
73205
+ }));
73206
+ case 1:
73207
+ case "end":
73208
+ return _context3.stop();
73052
73209
  }
73053
- // Dispose player
73054
- videoPlayer.player.dispose();
73055
- // Clear up media player
73056
- videoPlayer.player = undefined;
73057
- media.player = undefined;
73058
- }
73059
- };
73060
- videoPlayer.player.on('loadstart', function () {
73061
- console.debug("??? XLR.debug >> VideoMedia - ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has started loading data . . ."));
73062
- });
73063
- videoPlayer.player.one('loadedmetadata', function () {
73064
- if (media.duration === 0 && videoPlayer.player !== undefined) {
73065
- videoPlayer.duration = videoPlayer.player.duration();
73066
- }
73067
- console.debug('??? XLR.debug >> VideoMedia - loadedmetadata: Setting video duration to = ' + videoPlayer.duration);
73068
- });
73069
- videoPlayer.player.one('playing', function () {
73070
- console.debug('??? XLR.debug >> VideoMedia - playing: Showing Media ' + media.id + ' for ' + videoPlayer.duration + 's of Region ' + media.region.regionId);
73071
- console.debug("??? XLR.debug >> VideoMedia - ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " is now playing . . ."));
73072
- videoPlayer.player && videoPlayer.player.muted(media.muted);
73073
- });
73074
- videoPlayer.player.on('error', /*#__PURE__*/function () {
73075
- var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(err) {
73076
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
73077
- while (1) switch (_context2.prev = _context2.next) {
73078
- case 0:
73079
- console.debug("??? XLR.debug >> VideoMedia - Media Error: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id));
73080
- if (!(platform === 'chromeOS')) {
73081
- _context2.next = 6;
73082
- break;
73210
+ }, _callee3);
73211
+ }));
73212
+ return _getDataBlob.apply(this, arguments);
73213
+ }
73214
+ function preloadMediaBlob(_x3, _x4, _x5) {
73215
+ return _preloadMediaBlob.apply(this, arguments);
73216
+ }
73217
+ function _preloadMediaBlob() {
73218
+ _preloadMediaBlob = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(src, type, jwtToken) {
73219
+ var res, blob, data;
73220
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
73221
+ while (1) switch (_context4.prev = _context4.next) {
73222
+ case 0:
73223
+ _context4.next = 2;
73224
+ return fetch(src, {
73225
+ method: 'GET',
73226
+ headers: {
73227
+ 'X-PREVIEW-JWT': jwtToken || ''
73083
73228
  }
73084
- _context2.next = 4;
73085
- return playerReportFault('Video file source not supported');
73086
- case 4:
73087
- _context2.next = 7;
73229
+ });
73230
+ case 2:
73231
+ res = _context4.sent;
73232
+ blob = new Blob();
73233
+ if (!(type === 'image')) {
73234
+ _context4.next = 8;
73088
73235
  break;
73089
- case 6:
73090
- // End media after 5 seconds
73091
- setTimeout(function () {
73092
- console.debug("??? XLR.debug >> VideoMedia - ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has ended . . ."));
73093
- videoPlayer.stop();
73094
- }, 5000);
73095
- case 7:
73096
- case "end":
73097
- return _context2.stop();
73098
- }
73099
- }, _callee2);
73100
- }));
73101
- return function (_x2) {
73102
- return _ref2.apply(this, arguments);
73103
- };
73104
- }());
73105
- // Register on.("end") when media.duration is 0
73106
- if (media.duration === 0) {
73107
- videoPlayer.player.on('ended', function () {
73108
- console.debug("??? XLR.debug >> VideoMedia - onended: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has ended playing . . ."));
73109
- videoPlayer.stop();
73110
- });
73111
- }
73112
- return videoPlayer;
73113
- }
73114
- function VideoMedia(media, xlr) {
73115
- var mediaId = getMediaId(media);
73116
- var videoPlayer = {
73117
- duration: 0,
73118
- init: function init() {
73119
- var _this = this;
73120
- var triggerTimeUpdate = false; // Used for media.duration === 0
73121
- videoPlayer.duration = media.duration;
73122
- var vjsPlayer = videojs(mediaId);
73123
- if (vjsPlayer) {
73124
- vjsPlayer.on('loadstart', function () {
73125
- console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has started loading data . . ."));
73126
- });
73127
- vjsPlayer.on('loadedmetadata', function () {
73128
- if (media.duration === 0) {
73129
- videoPlayer.duration = vjsPlayer.duration();
73130
73236
  }
73131
- console.debug('??? XLR.debug >> VideoMedia: loadedmetadata: Setting video duration to = ' + videoPlayer.duration);
73132
- });
73133
- vjsPlayer.on('canplay', function () {
73134
- console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " can be played . . ."));
73135
- });
73136
- vjsPlayer.on('playing', function () {
73137
- // Update duration
73138
- if (videoPlayer.duration === 0) {
73139
- videoPlayer.duration = vjsPlayer.duration();
73237
+ blob = new Blob();
73238
+ _context4.next = 19;
73239
+ break;
73240
+ case 8:
73241
+ if (!(type === 'video')) {
73242
+ _context4.next = 14;
73243
+ break;
73140
73244
  }
73141
- console.debug('??? XLR.debug >> VideoMedia: playing: Showing Media ' + media.id + ' for ' + videoPlayer.duration + 's of Region ' + media.region.regionId);
73142
- console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " is now playing . . ."));
73143
- });
73144
- // @NOTE: When video is paused due to fail in unmuting the video
73145
- // and video has media.duration = 0, the video will stay paused and the video cycle won't end
73146
- // @TODO: Add timer when video is paused due to unmuting fail and duration that is equal to 0
73147
- // @NOTE: The pause issue when unmuting the video is mainly on a browser level.
73148
- // Please visit https://developer.chrome.com/blog/autoplay/ for more info.
73149
- vjsPlayer.ready(function () {
73150
- // Add guard making sure that video element is present
73151
- var videoElem = document.querySelector(".media--item.".concat(mediaId));
73152
- if (!document.body.contains(videoElem)) {
73153
- media.emitter.emit('cancelled', media);
73154
- return;
73245
+ _context4.next = 11;
73246
+ return res.blob();
73247
+ case 11:
73248
+ blob = _context4.sent;
73249
+ _context4.next = 19;
73250
+ break;
73251
+ case 14:
73252
+ if (!(type === 'audio')) {
73253
+ _context4.next = 19;
73254
+ break;
73155
73255
  }
73156
- if (vjsPlayer !== undefined) {
73157
- vjsPlayer.muted(true);
73158
- // Race promise between a 0.5s play and a 5s skip
73159
- Promise.race([new Promise(function (resolve, reject) {
73160
- return setTimeout( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
73161
- return _regeneratorRuntime().wrap(function _callee3$(_context3) {
73162
- while (1) switch (_context3.prev = _context3.next) {
73163
- case 0:
73164
- console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Trying to force play after 0.1 seconds"));
73165
- // Try to force play here
73166
- _context3.prev = 1;
73167
- if (!(vjsPlayer.currentTime() === 0)) {
73168
- _context3.next = 6;
73169
- break;
73170
- }
73171
- // Set video mute/unmute based on setting once playing
73172
- vjsPlayer.muted(media.muted);
73173
- _context3.next = 6;
73174
- return vjsPlayer.play();
73175
- case 6:
73176
- // Resolve if play works
73177
- resolve(true);
73178
- _context3.next = 12;
73179
- break;
73180
- case 9:
73181
- _context3.prev = 9;
73182
- _context3.t0 = _context3["catch"](1);
73183
- // Reject race if play fails
73184
- reject('Play failed');
73185
- case 12:
73186
- case "end":
73187
- return _context3.stop();
73188
- }
73189
- }, _callee3, null, [[1, 9]]);
73190
- })), 100);
73191
- }), new Promise(function (_, reject) {
73192
- return setTimeout(function () {
73193
- return reject('Timeout');
73194
- }, 5000);
73195
- })]).then(function () {
73196
- console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Autoplay started"));
73197
- })["catch"]( /*#__PURE__*/function () {
73198
- var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(error) {
73199
- return _regeneratorRuntime().wrap(function _callee4$(_context4) {
73200
- while (1) switch (_context4.prev = _context4.next) {
73201
- case 0:
73202
- if (error === 'Timeout') {
73203
- console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Promise not resolved within 5 seconds. Move to next media"));
73204
- _this.stop();
73205
- } else {
73206
- console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Autoplay error: ").concat(error));
73207
- if (xlr.config.platform === exports.ConsumerPlatform.CHROMEOS) {
73208
- playerReportFault('Media autoplay error', media).then(function () {
73209
- _this.stop();
73210
- });
73211
- }
73212
- }
73213
- case 1:
73214
- case "end":
73215
- return _context4.stop();
73216
- }
73217
- }, _callee4);
73218
- }));
73219
- return function (_x3) {
73220
- return _ref4.apply(this, arguments);
73221
- };
73222
- }());
73223
- // Optional: Reset the flag automatically when a new video loads or the source changes
73224
- vjsPlayer.on('loadstart', function () {
73225
- triggerTimeUpdate = false;
73226
- });
73227
- if (media.duration === 0) {
73228
- vjsPlayer.on('timeupdate', function () {
73229
- var preloadBufferTimeMs = 2000;
73230
- var mediaDuration = vjsPlayer.duration();
73231
- var currentTime = vjsPlayer.currentTime();
73232
- var regionHasMultipleMedia = media.region.totalMediaObjects > 1;
73233
- var remainingTimeMs = 0;
73234
- if (mediaDuration !== undefined && currentTime !== undefined) {
73235
- remainingTimeMs = (mediaDuration - currentTime) * 1000;
73236
- }
73237
- if (regionHasMultipleMedia && remainingTimeMs === 0 && !triggerTimeUpdate) {
73238
- // We don't have data yet and we must immediately prepare next media
73239
- media.region.prepareNextMedia();
73240
- } else if (regionHasMultipleMedia && remainingTimeMs <= preloadBufferTimeMs && !triggerTimeUpdate) {
73241
- // Check if remaining time is less than preloadBufferTimeMs and the action hasn't been triggered yet
73242
- console.log('Less than preloadBufferTimeMs remaining! Do something now.');
73243
- // Prepare next media in region
73244
- media.region.prepareNextMedia();
73245
- triggerTimeUpdate = true; // Set the flag to prevent re-triggering
73246
- }
73247
- // Reset the flag if the user seeks back to a point where more than preloadBufferTimeMs remain
73248
- if (remainingTimeMs > preloadBufferTimeMs) {
73249
- triggerTimeUpdate = false;
73250
- }
73251
- });
73252
- }
73253
- }
73254
- });
73255
- vjsPlayer.on('error', /*#__PURE__*/function () {
73256
- var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(err) {
73257
- return _regeneratorRuntime().wrap(function _callee5$(_context5) {
73258
- while (1) switch (_context5.prev = _context5.next) {
73259
- case 0:
73260
- console.debug("??? XLR.debug >> VideoMedia: Media Error: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id));
73261
- if (xlr.config.platform === exports.ConsumerPlatform.CHROMEOS) {
73262
- playerReportFault('Video file source not supported', media).then(function () {
73263
- _this.stop();
73264
- });
73265
- } else {
73266
- // End media after 5 seconds
73267
- setTimeout(function () {
73268
- console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has ended . . ."));
73269
- _this.stop();
73270
- }, 5000);
73271
- }
73272
- case 2:
73273
- case "end":
73274
- return _context5.stop();
73275
- }
73276
- }, _callee5);
73277
- }));
73278
- return function (_x4) {
73279
- return _ref5.apply(this, arguments);
73280
- };
73281
- }());
73282
- if (media.duration === 0) {
73283
- vjsPlayer.on('ended', function () {
73284
- console.debug("??? XLR.debug >> VideoMedia: onended: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has ended playing . . ."));
73285
- _this.stop();
73256
+ _context4.next = 17;
73257
+ return res.arrayBuffer();
73258
+ case 17:
73259
+ data = _context4.sent;
73260
+ blob = new Blob([data], {
73261
+ type: audioFileType(getFileExt(src))
73286
73262
  });
73287
- }
73263
+ case 19:
73264
+ return _context4.abrupt("return", URL.createObjectURL(blob));
73265
+ case 20:
73266
+ case "end":
73267
+ return _context4.stop();
73288
73268
  }
73289
- },
73290
- stop: function stop() {
73291
- var disposeOnly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
73292
- var vjsPlayer = media.player;
73293
- console.debug('??? XLR.debug >> VideoMedia::stop', {
73294
- vjsPlayer: vjsPlayer,
73295
- isDisposed: vjsPlayer === null || vjsPlayer === void 0 ? void 0 : vjsPlayer.isDisposed_,
73296
- el: vjsPlayer === null || vjsPlayer === void 0 ? void 0 : vjsPlayer.el_
73297
- });
73298
- // Expire the media and dispose the video
73299
- if (vjsPlayer !== undefined && !vjsPlayer.isDisposed_) {
73300
- if (!disposeOnly) {
73301
- media.emitter.emit('end', media);
73302
- }
73303
- vjsPlayer.dispose();
73304
- // Clear up media player
73305
- media.player = undefined;
73306
- } else {
73307
- media.player = undefined;
73308
- media.html = null;
73309
- media.emitter.emit('end', media);
73269
+ }, _callee4);
73270
+ }));
73271
+ return _preloadMediaBlob.apply(this, arguments);
73272
+ }
73273
+ function fetchJSON(_x6, _x7) {
73274
+ return _fetchJSON.apply(this, arguments);
73275
+ }
73276
+ function _fetchJSON() {
73277
+ _fetchJSON = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(url, jwtToken) {
73278
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
73279
+ while (1) switch (_context5.prev = _context5.next) {
73280
+ case 0:
73281
+ return _context5.abrupt("return", fetch(url, {
73282
+ method: 'GET',
73283
+ headers: {
73284
+ 'X-PREVIEW-JWT': jwtToken || ''
73285
+ }
73286
+ }).then(function (res) {
73287
+ return res.json();
73288
+ })["catch"](function (err) {
73289
+ console.debug(err);
73290
+ }));
73291
+ case 1:
73292
+ case "end":
73293
+ return _context5.stop();
73310
73294
  }
73311
- },
73312
- play: function play() {
73313
- var _this2 = this;
73314
- var vjsPlayer = videojs(mediaId);
73315
- if (vjsPlayer !== undefined) {
73316
- var _vjsPlayer$play;
73317
- (_vjsPlayer$play = vjsPlayer.play()) === null || _vjsPlayer$play === void 0 || _vjsPlayer$play["catch"]( /*#__PURE__*/function () {
73318
- var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(error) {
73319
- return _regeneratorRuntime().wrap(function _callee6$(_context6) {
73320
- while (1) switch (_context6.prev = _context6.next) {
73321
- case 0:
73322
- if (error === 'Timeout') {
73323
- console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Promise not resolved within 5 seconds. Move to next media"));
73324
- _this2.stop();
73325
- } else {
73326
- console.debug("??? XLR.debug >> VideoMedia: ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " : Autoplay error: ").concat(error));
73327
- if (xlr.config.platform === exports.ConsumerPlatform.CHROMEOS) {
73328
- playerReportFault('Media autoplay error', media).then(function () {
73329
- _this2.stop();
73330
- });
73331
- }
73332
- }
73333
- case 1:
73334
- case "end":
73335
- return _context6.stop();
73336
- }
73337
- }, _callee6);
73295
+ }, _callee5);
73296
+ }));
73297
+ return _fetchJSON.apply(this, arguments);
73298
+ }
73299
+ function fetchText(_x8, _x9) {
73300
+ return _fetchText.apply(this, arguments);
73301
+ }
73302
+ function _fetchText() {
73303
+ _fetchText = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(url, jwtToken) {
73304
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
73305
+ while (1) switch (_context6.prev = _context6.next) {
73306
+ case 0:
73307
+ return _context6.abrupt("return", fetch(url, {
73308
+ method: 'GET',
73309
+ headers: {
73310
+ 'X-PREVIEW-JWT': jwtToken || ''
73311
+ }
73312
+ }).then(function (res) {
73313
+ return res.text();
73314
+ }).then(function (responseText) {
73315
+ if (String(responseText).length > 0) {
73316
+ return responseText;
73317
+ } else {
73318
+ return '';
73319
+ }
73320
+ })["catch"](function (err) {
73321
+ console.debug(err);
73322
+ return err === null || err === void 0 ? void 0 : err.message;
73338
73323
  }));
73339
- return function (_x5) {
73340
- return _ref6.apply(this, arguments);
73341
- };
73342
- }());
73324
+ case 1:
73325
+ case "end":
73326
+ return _context6.stop();
73343
73327
  }
73344
- }
73328
+ }, _callee6);
73329
+ }));
73330
+ return _fetchText.apply(this, arguments);
73331
+ }
73332
+ function getFileExt(filename) {
73333
+ var filenameArr = String(filename).split('.');
73334
+ return filenameArr[filenameArr.length - 1];
73335
+ }
73336
+ function audioFileType(str) {
73337
+ var validAudioTypes = {
73338
+ 'mp3': 'audio/mp3',
73339
+ 'wav': 'audio/wav',
73340
+ 'ogg': 'audio/ogg'
73345
73341
  };
73346
- return videoPlayer;
73342
+ if (Boolean(validAudioTypes[str])) {
73343
+ return validAudioTypes[str];
73344
+ }
73345
+ return undefined;
73347
73346
  }
73348
-
73349
- var Media = /*#__PURE__*/function () {
73350
- function Media(region, mediaId, xml, options, xlr) {
73351
- var _this$xml,
73352
- _this$xml2,
73353
- _this$xml3,
73354
- _this$xml4,
73355
- _this$xml5,
73356
- _this = this;
73357
- _classCallCheck(this, Media);
73358
- _defineProperty(this, "attachedAudio", false);
73359
- _defineProperty(this, "checkIframeStatus", false);
73360
- _defineProperty(this, "containerName", '');
73361
- _defineProperty(this, "divHeight", 0);
73362
- _defineProperty(this, "divWidth", 0);
73363
- _defineProperty(this, "duration", 0);
73364
- _defineProperty(this, "emitter", createNanoEvents());
73365
- _defineProperty(this, "enableStat", false);
73366
- _defineProperty(this, "fileId", '');
73367
- _defineProperty(this, "finished", false);
73368
- _defineProperty(this, "html", null);
73369
- _defineProperty(this, "id", '');
73370
- _defineProperty(this, "idCounter", 0);
73371
- _defineProperty(this, "iframe", null);
73372
- _defineProperty(this, "iframeName", '');
73373
- _defineProperty(this, "index", 0);
73374
- _defineProperty(this, "loadIframeOnRun", false);
73375
- _defineProperty(this, "loop", false);
73376
- _defineProperty(this, "mediaId", '');
73377
- _defineProperty(this, "mediaType", '');
73378
- _defineProperty(this, "muted", false);
73379
- _defineProperty(this, "options", {});
73380
- _defineProperty(this, "player", undefined);
73381
- _defineProperty(this, "ready", true);
73382
- _defineProperty(this, "region", {});
73383
- _defineProperty(this, "render", 'html');
73384
- _defineProperty(this, "schemaVersion", '1');
73385
- _defineProperty(this, "singlePlay", false);
73386
- _defineProperty(this, "state", MediaState.IDLE);
73387
- _defineProperty(this, "tempSrc", '');
73388
- _defineProperty(this, "timeoutId", setTimeout(function () {}, 0));
73389
- _defineProperty(this, "type", '');
73390
- _defineProperty(this, "uri", '');
73391
- _defineProperty(this, "url", null);
73392
- _defineProperty(this, "useDuration", false);
73393
- _defineProperty(this, "xml", null);
73394
- _defineProperty(this, "videoHandler", void 0);
73395
- _defineProperty(this, "mediaTimer", void 0);
73396
- _defineProperty(this, "mediaTimeCount", 0);
73397
- _defineProperty(this, "xlr", {});
73398
- _defineProperty(this, "statsBC", new BroadcastChannel('statsBC'));
73399
- _defineProperty(this, "hasCommandExecuted", void 0);
73400
- this.region = region;
73401
- this.id = mediaId;
73402
- this.mediaId = this.id;
73403
- this.xml = xml;
73404
- this.options = options;
73405
- this.xlr = xlr;
73406
- this.fileId = ((_this$xml = this.xml) === null || _this$xml === void 0 ? void 0 : _this$xml.getAttribute('fileId')) || '';
73407
- this.idCounter = nextId(this.options);
73408
- this.containerName = "M-".concat(this.id, "-").concat(this.idCounter);
73409
- this.iframeName = "".concat(this.containerName, "-iframe");
73410
- this.mediaType = ((_this$xml2 = this.xml) === null || _this$xml2 === void 0 ? void 0 : _this$xml2.getAttribute('type')) || '';
73411
- this.render = ((_this$xml3 = this.xml) === null || _this$xml3 === void 0 ? void 0 : _this$xml3.getAttribute('render')) || '';
73412
- this.duration = parseInt((_this$xml4 = this.xml) === null || _this$xml4 === void 0 ? void 0 : _this$xml4.getAttribute('duration')) || 0;
73413
- this.enableStat = Boolean(((_this$xml5 = this.xml) === null || _this$xml5 === void 0 ? void 0 : _this$xml5.getAttribute('enableStat')) || false);
73414
- this.hasCommandExecuted = false;
73415
- this.on('start', function (media) {
73416
- if (media.state === MediaState.PLAYING) return;
73417
- media.state = MediaState.PLAYING;
73418
- if (media.mediaType === 'video') {
73419
- var videoMedia = VideoMedia(media, _this.xlr);
73420
- videoMedia.init();
73421
- if (media.duration > 0) {
73422
- _this.startMediaTimer(media);
73423
- }
73424
- } else if (media.mediaType === 'audio') {
73425
- AudioMedia(media).init();
73426
- if (media.duration > 0) {
73427
- _this.startMediaTimer(media);
73428
- }
73429
- } else if (media.mediaType === 'shellcommand') {
73430
- if (_this.hasCommandExecuted && !_this.loop) {
73431
- return;
73432
- }
73433
- _this.hasCommandExecuted = true;
73434
- _this.emitCommand(media);
73435
- if (media.duration > 0) {
73436
- _this.startMediaTimer(media);
73437
- }
73438
- } else {
73439
- _this.startMediaTimer(media);
73440
- }
73441
- // Check if stats are enabled for the layout
73442
- if (media.enableStat) {
73443
- _this.statsBC.postMessage({
73444
- action: 'START_STAT',
73445
- mediaId: parseInt(media.id),
73446
- layoutId: media.region.layout.id,
73447
- scheduleId: media.region.layout.scheduleId,
73448
- type: 'media'
73449
- });
73450
- }
73451
- // Emit media/widget start event
73452
- console.debug('Media::Emitter > Start - Calling widgetStart event');
73453
- _this.xlr.emitter.emit('widgetStart', parseInt(media.id));
73454
- });
73455
- this.on('end', function (media) {
73456
- if (media.state === MediaState.ENDED) return;
73457
- media.state = MediaState.ENDED;
73458
- if (_this.mediaTimer) {
73459
- clearInterval(_this.mediaTimer);
73460
- _this.mediaTimeCount = 0;
73461
- }
73462
- // Check if stats are enabled for the layout
73463
- if (media.enableStat) {
73464
- _this.statsBC.postMessage({
73465
- action: 'END_STAT',
73466
- mediaId: parseInt(media.id),
73467
- layoutId: media.region.layout.id,
73468
- scheduleId: media.region.layout.scheduleId,
73469
- type: 'media'
73470
- });
73471
- }
73472
- // Emit media/widget end event
73473
- console.debug('Media::Emitter > End - Calling widgetEnd event', {
73474
- mediaId: media.id,
73475
- regionId: media.region.id,
73476
- layoutId: media.region.layout.id
73477
- });
73478
- _this.xlr.emitter.emit('widgetEnd', parseInt(media.id));
73479
- media.region.playNextMedia();
73480
- });
73481
- this.on('cancelled', function (media) {
73482
- if (media.state === MediaState.CANCELLED) return;
73483
- media.state = MediaState.CANCELLED;
73484
- if (_this.mediaTimer) {
73485
- clearInterval(_this.mediaTimer);
73486
- _this.mediaTimeCount = 0;
73487
- }
73488
- // Check if stats are enabled for the layout
73489
- if (media.enableStat) {
73490
- _this.statsBC.postMessage({
73491
- action: 'END_STAT',
73492
- mediaId: parseInt(media.id),
73493
- layoutId: media.region.layout.id,
73494
- scheduleId: media.region.layout.scheduleId,
73495
- type: 'media'
73496
- });
73497
- }
73498
- // Emit media/widget end event
73499
- console.debug('Media::Emitter > End - Calling widgetEnd event', {
73500
- mediaId: media.id,
73501
- regionId: media.region.id,
73502
- layoutId: media.region.layout.id
73503
- });
73504
- _this.xlr.emitter.emit('widgetEnd', parseInt(media.id));
73505
- media.region.playNextMedia();
73506
- });
73507
- // Initialize Media object
73508
- this.init();
73347
+ function videoFileType(str) {
73348
+ var validVideoTypes = {
73349
+ 'mp4': 'video/mp4',
73350
+ 'webm': 'video/webm',
73351
+ 'wmv': 'video/x-ms-wmv'
73352
+ };
73353
+ if (Boolean(validVideoTypes[str])) {
73354
+ return validVideoTypes[str];
73509
73355
  }
73510
- return _createClass(Media, [{
73511
- key: "startMediaTimer",
73512
- value: function startMediaTimer(media) {
73513
- var _this2 = this;
73514
- var preloadTimeMs = 2000;
73515
- var preloadTimeBufferMs = media.duration * 1000 - preloadTimeMs;
73516
- var isPreparingNextMedia = false;
73517
- if (preloadTimeBufferMs < preloadTimeMs) {
73518
- // Use media duration when preloadTimeBufferMs is less than the preloadTimeMs
73519
- preloadTimeBufferMs = media.duration * 1000;
73520
- }
73521
- this.mediaTimer = setInterval(function () {
73522
- _this2.mediaTimeCount++;
73523
- var elapsedTimeMs = _this2.mediaTimeCount * 1000;
73524
- // prepare region's next media
73525
- if (_this2.region.totalMediaObjects > 1 && elapsedTimeMs >= preloadTimeBufferMs && !isPreparingNextMedia) {
73526
- isPreparingNextMedia = true;
73527
- _this2.region.prepareNextMedia();
73528
- }
73529
- if (_this2.mediaTimeCount > media.duration) {
73530
- console.debug('??? XLR.debug >> Media::startMediaTimer: emit>end: on media ' + media.id + ' of Region ' + media.region.regionId);
73531
- console.debug('??? XLR.debug >> Media::startMediaTimer - Media::Emitter > End', {
73532
- currentLayout: _this2.xlr.currentLayout,
73533
- media: media,
73534
- region: media.region,
73535
- layout: media.region.layout
73536
- });
73537
- media.emitter.emit('end', media);
73538
- if (media.mediaType === 'video') {
73539
- // Dispose the video media
73540
- console.debug("??? XLR.debug >> VideoMedia::stop - ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has ended playing . . ."));
73541
- if (media.player !== undefined) {
73542
- VideoMedia(media, _this2.xlr).stop(true);
73543
- }
73544
- }
73545
- }
73546
- }, 1000);
73547
- console.debug('startMediaTimer: Showing Media ' + media.id + ' for ' + media.duration + 's of Region ' + media.region.regionId);
73548
- }
73549
- }, {
73550
- key: "on",
73551
- value: function on(event, callback) {
73552
- return this.emitter.on(event, callback);
73356
+ return undefined;
73357
+ }
73358
+ function composeResourceUrlByPlatform(options, params) {
73359
+ var resourceUrl = '';
73360
+ if (params.regionOptions && Boolean(params.regionOptions.getResourceUrl)) {
73361
+ resourceUrl = params.regionOptions.getResourceUrl.replace(":regionId", params.regionId).replace(":id", params.mediaId) + '?preview=1&layoutPreview=1';
73362
+ }
73363
+ if (options.platform === exports.ConsumerPlatform.CMS && Boolean(params.regionOptions.previewJwt)) {
73364
+ resourceUrl += '&jwt=' + params.regionOptions.previewJwt;
73365
+ }
73366
+ if (options.platform === exports.ConsumerPlatform.CHROMEOS) {
73367
+ var resourceEndpoint = '/required-files/resource/';
73368
+ if (!params.isGlobalContent && params.isImageOrVideo) {
73369
+ resourceUrl = resourceEndpoint + params.fileId + '?saveAs=' + params.uri;
73553
73370
  }
73554
- }, {
73555
- key: "init",
73556
- value: function init() {
73557
- var _this$xml6;
73558
- var mediaOptions = (_this$xml6 = this.xml) === null || _this$xml6 === void 0 ? void 0 : _this$xml6.getElementsByTagName('options');
73559
- if (mediaOptions) {
73560
- for (var _i = 0, _Array$from = Array.from(mediaOptions); _i < _Array$from.length; _i++) {
73561
- var _options = _Array$from[_i];
73562
- // Get options
73563
- var _mediaOptions = _options.children;
73564
- for (var _i2 = 0, _Array$from2 = Array.from(_mediaOptions); _i2 < _Array$from2.length; _i2++) {
73565
- var mediaOption = _Array$from2[_i2];
73566
- this.options[mediaOption.nodeName.toLowerCase()] = mediaOption.textContent;
73567
- }
73568
- }
73569
- }
73570
- // Check for options.uri and add it to media
73571
- if (Boolean(this.options['uri'])) {
73572
- this.uri = this.options['uri'];
73573
- }
73574
- // Show in fullscreen?
73575
- if (this.options.showfullscreen === "1") {
73576
- // Set dimensions as the layout ones
73577
- this.divWidth = this.region.layout.sWidth;
73578
- this.divHeight = this.region.layout.sHeight;
73579
- } else {
73580
- // Set dimensions as the region ones
73581
- this.divWidth = this.region.sWidth;
73582
- this.divHeight = this.region.sHeight;
73583
- }
73584
- var resourceUrlParams = _objectSpread2(_objectSpread2({}, this.xlr.config.config), {}, {
73585
- regionOptions: this.region.options,
73586
- layoutId: this.region.layout.layoutId,
73587
- regionId: this.region.id,
73588
- mediaId: this.id,
73589
- fileId: this.fileId,
73590
- scaleFactor: this.region.layout.scaleFactor,
73591
- uri: this.uri,
73592
- isGlobalContent: this.mediaType === 'global',
73593
- isImageOrVideo: this.mediaType === 'image' || this.mediaType === 'video'
73594
- });
73595
- if (this.mediaType === 'image' || this.mediaType === 'video') {
73596
- resourceUrlParams.mediaType = this.mediaType;
73597
- }
73598
- var tmpUrl = '';
73599
- if (this.xlr.config.platform === exports.ConsumerPlatform.CMS) {
73600
- tmpUrl = composeResourceUrlByPlatform(this.xlr.config, resourceUrlParams);
73601
- } else if (this.xlr.config.platform === exports.ConsumerPlatform.CHROMEOS) {
73602
- tmpUrl = composeResourceUrl(this.xlr.config, resourceUrlParams);
73603
- if (this.mediaType === 'image' || this.mediaType === 'video' || this.mediaType === 'audio') {
73604
- tmpUrl = composeMediaUrl(resourceUrlParams);
73605
- // this is an SSP Layout
73606
- if (this.region.layout.layoutId === -1) {
73607
- tmpUrl = this.uri;
73608
- }
73609
- }
73610
- }
73611
- this.url = tmpUrl;
73612
- // Loop if media has loop, or if region has loop and a single media
73613
- this.loop = this.options['loop'] == '1' || this.region.options['loop'] == '1' && this.region.totalMediaObjects == 1;
73614
- this.html = createMediaElement(this);
73371
+ } else if (options.platform === exports.ConsumerPlatform.ELECTRON) {
73372
+ if (params.render === 'html' || params.mediaType === 'ticker' || params.mediaType === 'webpage') {
73373
+ resourceUrl = options.appHost + 'layout_' + params.layoutId + '_region_' + params.regionId + '_media_' + params.mediaId + '.html';
73374
+ } else if (params.render === 'native' && params.isImageOrVideo) {
73375
+ resourceUrl = options.appHost + params.uri;
73615
73376
  }
73616
- }, {
73617
- key: "run",
73618
- value: function run() {
73619
- var _this3 = this;
73620
- var transInDuration = 1;
73621
- var transInDirection = 'E';
73622
- if (Boolean(this.options['transinduration'])) {
73623
- transInDuration = Number(this.options.transinduration);
73624
- }
73625
- if (Boolean(this.options['transindirection'])) {
73626
- transInDirection = this.options.transindirection;
73627
- }
73628
- var defaultTransInOptions = {
73629
- duration: transInDuration
73630
- };
73631
- var transIn = transitionElement('defaultIn', {
73632
- duration: defaultTransInOptions.duration
73633
- });
73634
- if (Boolean(this.options['transin'])) {
73635
- var transInName = this.options['transin'];
73636
- if (transInName === 'fly') {
73637
- transInName = "".concat(transInName, "In");
73638
- defaultTransInOptions.keyframes = flyTransitionKeyframes({
73639
- trans: 'in',
73640
- direction: transInDirection,
73641
- height: this.divHeight,
73642
- width: this.divWidth
73643
- });
73644
- }
73645
- transIn = transitionElement(transInName, defaultTransInOptions);
73646
- }
73647
- var showCurrentMedia = function showCurrentMedia() {
73648
- var mediaId = getMediaId({
73649
- mediaType: _this3.mediaType,
73650
- containerName: _this3.containerName
73651
- });
73652
- var $region = document.querySelector('#' + _this3.region.containerName);
73653
- var $media = $region !== null && $region.querySelector('.' + mediaId);
73654
- if (!$media) {
73655
- $media = getNewMedia();
73656
- }
73657
- console.debug('??? XLR.debug >> Media run - show current media:', {
73658
- inDOM: document.body.contains($media),
73659
- mediaId: mediaId,
73660
- $media: $media,
73661
- mediaObject: _this3
73662
- });
73663
- if ($media) {
73664
- if (_this3.mediaType === 'video') {
73665
- var _this3$player, _this3$player2, _this3$player3, _this3$player4;
73666
- console.debug('??? XLR.debug >> Media.run() > showCurrentMedia() - Video media::START', {
73667
- mediaPlayer: _this3.player,
73668
- isDisposed: (_this3$player = _this3.player) === null || _this3$player === void 0 ? void 0 : _this3$player.isDisposed(),
73669
- el: (_this3$player2 = _this3.player) === null || _this3$player2 === void 0 ? void 0 : _this3$player2.el_
73670
- });
73671
- // Make sure that vjs is available on the media
73672
- // Else, re-initialize
73673
- if (_this3.player !== undefined) {
73674
- var existingPlayer = videojs(mediaId);
73675
- if (existingPlayer) {
73676
- _this3.player = existingPlayer;
73677
- } else {
73678
- if (_this3.player.isDisposed_) {
73679
- _this3.player = undefined;
73680
- _this3.player = videojs(mediaId, _objectSpread2({}, vjsDefaultOptions({
73681
- errorDisplay: _this3.xlr.config.platform !== exports.ConsumerPlatform.CHROMEOS,
73682
- loop: _this3.loop
73683
- })));
73684
- }
73685
- }
73686
- }
73687
- console.debug('??? XLR.debug >> Media.run() > showCurrentMedia() - Video media::END', {
73688
- mediaPlayer: _this3.player,
73689
- isDisposed: (_this3$player3 = _this3.player) === null || _this3$player3 === void 0 ? void 0 : _this3$player3.isDisposed(),
73690
- el: (_this3$player4 = _this3.player) === null || _this3$player4 === void 0 ? void 0 : _this3$player4.el_
73691
- });
73692
- if (_this3.player !== undefined && _this3.player.el_ !== null) {
73693
- _this3.player.el().style.setProperty('visibility', 'visible');
73694
- _this3.player.el().style.setProperty('z-index', '10');
73695
- _this3.player.el().style.setProperty('opacity', '1');
73696
- }
73697
- } else {
73698
- console.debug('??? XLR.debug >> Media::run() > showCurrentMedia', {
73699
- mediaType: _this3.mediaType,
73700
- render: _this3.render,
73701
- $media: $media,
73702
- state: _this3.state
73703
- });
73704
- $media.style.setProperty('visibility', 'visible');
73705
- $media.style.setProperty('z-index', '10');
73706
- $media.style.setProperty('opacity', '1');
73707
- }
73708
- if (Boolean(_this3.options['transin'])) {
73709
- $media.animate(transIn.keyframes, transIn.timing);
73710
- }
73711
- if (!_this3.region.layout.isOverlay || _this3.region.layout.isOverlay && _this3.region.totalMediaObjects > 1) {
73712
- _this3.emitter.emit('start', _this3);
73713
- }
73714
- }
73715
- };
73716
- var getNewMedia = function getNewMedia() {
73717
- var $region = document.getElementById("".concat(_this3.region.containerName));
73718
- // This function is for checking whether
73719
- // the region still has to show a media item
73720
- // when another region is not finished yet
73721
- if (_this3.region.complete && !_this3.region.layout.allEnded) {
73722
- // Add currentMedia to the region
73723
- $region && $region.insertBefore(_this3.html, $region.lastElementChild);
73724
- return _this3.html;
73725
- }
73726
- return null;
73727
- };
73728
- showCurrentMedia();
73729
- }
73730
- }, {
73731
- key: "stop",
73732
- value: function () {
73733
- var _stop = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
73734
- var $media;
73735
- return _regeneratorRuntime().wrap(function _callee$(_context) {
73736
- while (1) switch (_context.prev = _context.next) {
73737
- case 0:
73738
- $media = document.getElementById(getMediaId({
73739
- mediaType: this.mediaType,
73740
- containerName: this.containerName
73741
- }));
73742
- if ($media) {
73743
- $media.style.display = 'none';
73744
- $media.remove();
73745
- }
73746
- // Release blob URLs for image media to prevent memory leaks on long-running signage
73747
- if (this.mediaType === 'image' && this.url) {
73748
- BlobLoader.release(this.url);
73749
- }
73750
- case 3:
73751
- case "end":
73752
- return _context.stop();
73753
- }
73754
- }, _callee, this);
73755
- }));
73756
- function stop() {
73757
- return _stop.apply(this, arguments);
73758
- }
73759
- return stop;
73760
- }()
73761
- /**
73762
- * Emits a command from the shell command widget.
73763
- *
73764
- * @param media
73765
- * @private
73766
- */
73767
- }, {
73768
- key: "emitCommand",
73769
- value: function emitCommand(media) {
73770
- if (media.mediaType !== 'shellcommand') {
73771
- return;
73772
- }
73773
- var options = media.options;
73774
- if (options.commandtype === 'storedCommand' && options.commandcode) {
73775
- console.debug('Media::Emitter > Shell Command - Calling commandCodeReceived event');
73776
- this.xlr.emitter.emit('commandCodeReceived', options.commandcode);
73777
- return;
73778
- }
73779
- var commandString = '';
73780
- if (options.useglobalcommand === '1') {
73781
- commandString = options.globalcommand || '';
73782
- } else {
73783
- // Use platform-specific command when available
73784
- if (this.xlr.config.platform === exports.ConsumerPlatform.CHROMEOS) {
73785
- commandString = options.chromeoscommand || '';
73786
- } else if (this.xlr.config.platform === exports.ConsumerPlatform.ANDROID) {
73787
- commandString = options.androidcommand || '';
73788
- } else if (this.xlr.config.platform === exports.ConsumerPlatform.LINUX) {
73789
- commandString = options.linuxcommand || '';
73790
- } else if (this.xlr.config.platform === exports.ConsumerPlatform.TIZEN) {
73791
- commandString = options.tizencommand || '';
73792
- } else if (this.xlr.config.platform === exports.ConsumerPlatform.WEBOS) {
73793
- commandString = options.weboscommand || '';
73794
- } else if (this.xlr.config.platform === exports.ConsumerPlatform.WINDOWS) {
73795
- commandString = options.windowscommand || '';
73796
- }
73797
- // Fall back to the global command if the platform-specific one
73798
- // is missing, not configured, or not supported yet
73799
- if (!commandString && options.globalcommand) {
73800
- commandString = options.globalcommand;
73801
- }
73802
- }
73803
- if (commandString) {
73804
- console.debug('Media::Emitter > Shell Command - Calling commandStringReceived event');
73805
- this.xlr.emitter.emit('commandStringReceived', commandString);
73806
- return;
73807
- }
73808
- }
73809
- }]);
73810
- }();
73811
-
73812
- function nextId(options) {
73813
- if (options.idCounter > 500) {
73814
- options.idCounter = 0;
73377
+ } else if (!Boolean(params['mediaType'])) {
73378
+ resourceUrl += '&scale_override=' + params.scaleFactor;
73815
73379
  }
73816
- options.idCounter = options.idCounter + 1;
73817
- return options.idCounter;
73380
+ return resourceUrl;
73818
73381
  }
73819
- var getMediaId = function getMediaId(_ref) {
73820
- var mediaType = _ref.mediaType,
73821
- containerName = _ref.containerName;
73822
- var mediaId = containerName;
73823
- if (mediaType === 'video') {
73824
- mediaId = mediaId + '-vid';
73825
- } else if (mediaType === 'audio') {
73826
- mediaId = mediaId + '-aud';
73827
- }
73828
- return mediaId;
73829
- };
73830
- var capitalizeStr = function capitalizeStr(inputStr) {
73831
- if (inputStr === null) {
73832
- return '';
73833
- }
73834
- return String(inputStr).charAt(0).toUpperCase() + String(inputStr).substring(1);
73835
- };
73836
- function getDataBlob(_x, _x2) {
73837
- return _getDataBlob.apply(this, arguments);
73382
+ function composeResourceUrl(options, params) {
73383
+ var _options$config, _options$config2, _options$config3;
73384
+ var schemaVersion = options && ((_options$config = options.config) === null || _options$config === void 0 ? void 0 : _options$config.schemaVersion);
73385
+ var hardwareKey = options && ((_options$config2 = options.config) === null || _options$config2 === void 0 ? void 0 : _options$config2.hardwareKey);
73386
+ var serverKey = options && ((_options$config3 = options.config) === null || _options$config3 === void 0 ? void 0 : _options$config3.cmsKey);
73387
+ return '/pwa/getResource' + '?v=' + schemaVersion + '&serverKey=' + serverKey + '&hardwareKey=' + hardwareKey + '&layoutId=' + params.layoutId + '&regionId=' + params.regionId + '&mediaId=' + params.mediaId;
73838
73388
  }
73839
- function _getDataBlob() {
73840
- _getDataBlob = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(src, jwtToken) {
73841
- return _regeneratorRuntime().wrap(function _callee3$(_context3) {
73842
- while (1) switch (_context3.prev = _context3.next) {
73843
- case 0:
73844
- return _context3.abrupt("return", fetch(src, {
73845
- method: 'GET',
73846
- headers: {
73847
- 'X-PREVIEW-JWT': jwtToken || ''
73848
- }
73849
- }).then(function (res) {
73850
- return res.blob();
73851
- }).then(function (blob) {
73852
- return new Promise(function (res, rej) {
73853
- var reader = new FileReader();
73854
- reader.onloadend = function () {
73855
- return res(reader.result);
73856
- };
73857
- reader.onerror = rej;
73858
- reader.readAsDataURL(blob);
73859
- });
73860
- }));
73861
- case 1:
73862
- case "end":
73863
- return _context3.stop();
73864
- }
73865
- }, _callee3);
73866
- }));
73867
- return _getDataBlob.apply(this, arguments);
73389
+ function composeMediaUrl(params) {
73390
+ return '/xmds.php?file=' + params.uri;
73868
73391
  }
73869
- function preloadMediaBlob(_x3, _x4, _x5) {
73870
- return _preloadMediaBlob.apply(this, arguments);
73871
- }
73872
- function _preloadMediaBlob() {
73873
- _preloadMediaBlob = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(src, type, jwtToken) {
73874
- var res, blob, data;
73875
- return _regeneratorRuntime().wrap(function _callee4$(_context4) {
73876
- while (1) switch (_context4.prev = _context4.next) {
73877
- case 0:
73878
- _context4.next = 2;
73879
- return fetch(src, {
73880
- method: 'GET',
73881
- headers: {
73882
- 'X-PREVIEW-JWT': jwtToken || ''
73883
- }
73884
- });
73885
- case 2:
73886
- res = _context4.sent;
73887
- blob = new Blob();
73888
- if (!(type === 'image')) {
73889
- _context4.next = 8;
73890
- break;
73891
- }
73892
- blob = new Blob();
73893
- _context4.next = 19;
73894
- break;
73895
- case 8:
73896
- if (!(type === 'video')) {
73897
- _context4.next = 14;
73898
- break;
73899
- }
73900
- _context4.next = 11;
73901
- return res.blob();
73902
- case 11:
73903
- blob = _context4.sent;
73904
- _context4.next = 19;
73905
- break;
73906
- case 14:
73907
- if (!(type === 'audio')) {
73908
- _context4.next = 19;
73909
- break;
73910
- }
73911
- _context4.next = 17;
73912
- return res.arrayBuffer();
73913
- case 17:
73914
- data = _context4.sent;
73915
- blob = new Blob([data], {
73916
- type: audioFileType(getFileExt(src))
73917
- });
73918
- case 19:
73919
- return _context4.abrupt("return", URL.createObjectURL(blob));
73920
- case 20:
73921
- case "end":
73922
- return _context4.stop();
73923
- }
73924
- }, _callee4);
73925
- }));
73926
- return _preloadMediaBlob.apply(this, arguments);
73927
- }
73928
- function fetchJSON(_x6, _x7) {
73929
- return _fetchJSON.apply(this, arguments);
73930
- }
73931
- function _fetchJSON() {
73932
- _fetchJSON = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(url, jwtToken) {
73933
- return _regeneratorRuntime().wrap(function _callee5$(_context5) {
73934
- while (1) switch (_context5.prev = _context5.next) {
73935
- case 0:
73936
- return _context5.abrupt("return", fetch(url, {
73937
- method: 'GET',
73938
- headers: {
73939
- 'X-PREVIEW-JWT': jwtToken || ''
73940
- }
73941
- }).then(function (res) {
73942
- return res.json();
73943
- })["catch"](function (err) {
73944
- console.debug(err);
73945
- }));
73946
- case 1:
73947
- case "end":
73948
- return _context5.stop();
73949
- }
73950
- }, _callee5);
73951
- }));
73952
- return _fetchJSON.apply(this, arguments);
73953
- }
73954
- function fetchText(_x8, _x9) {
73955
- return _fetchText.apply(this, arguments);
73956
- }
73957
- function _fetchText() {
73958
- _fetchText = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(url, jwtToken) {
73959
- return _regeneratorRuntime().wrap(function _callee6$(_context6) {
73960
- while (1) switch (_context6.prev = _context6.next) {
73961
- case 0:
73962
- return _context6.abrupt("return", fetch(url, {
73963
- method: 'GET',
73964
- headers: {
73965
- 'X-PREVIEW-JWT': jwtToken || ''
73966
- }
73967
- }).then(function (res) {
73968
- return res.text();
73969
- }).then(function (responseText) {
73970
- if (String(responseText).length > 0) {
73971
- return responseText;
73972
- } else {
73973
- return '';
73974
- }
73975
- })["catch"](function (err) {
73976
- console.debug(err);
73977
- return err === null || err === void 0 ? void 0 : err.message;
73978
- }));
73979
- case 1:
73980
- case "end":
73981
- return _context6.stop();
73982
- }
73983
- }, _callee6);
73984
- }));
73985
- return _fetchText.apply(this, arguments);
73986
- }
73987
- function getFileExt(filename) {
73988
- var filenameArr = String(filename).split('.');
73989
- return filenameArr[filenameArr.length - 1];
73990
- }
73991
- function audioFileType(str) {
73992
- var validAudioTypes = {
73993
- 'mp3': 'audio/mp3',
73994
- 'wav': 'audio/wav',
73995
- 'ogg': 'audio/ogg'
73996
- };
73997
- if (Boolean(validAudioTypes[str])) {
73998
- return validAudioTypes[str];
73999
- }
74000
- return undefined;
74001
- }
74002
- function videoFileType(str) {
74003
- var validVideoTypes = {
74004
- 'mp4': 'video/mp4',
74005
- 'webm': 'video/webm',
74006
- 'wmv': 'video/x-ms-wmv'
74007
- };
74008
- if (Boolean(validVideoTypes[str])) {
74009
- return validVideoTypes[str];
74010
- }
74011
- return undefined;
74012
- }
74013
- function composeResourceUrlByPlatform(options, params) {
74014
- var resourceUrl = params.regionOptions.getResourceUrl.replace(":regionId", params.regionId).replace(":id", params.mediaId) + '?preview=1&layoutPreview=1';
74015
- if (options.platform === 'CMS') {
74016
- resourceUrl += '&jwt=' + params.regionOptions.previewJwt;
74017
- }
74018
- if (options.platform === 'chromeOS') {
74019
- var resourceEndpoint = '/required-files/resource/';
74020
- if (!params.isGlobalContent && params.isImageOrVideo) {
74021
- resourceUrl = resourceEndpoint + params.fileId + '?saveAs=' + params.uri;
74022
- }
74023
- } else if (!Boolean(params['mediaType'])) {
74024
- resourceUrl += '&scale_override=' + params.scaleFactor;
74025
- }
74026
- return resourceUrl;
74027
- }
74028
- function composeResourceUrl(options, params) {
74029
- var _options$config, _options$config2, _options$config3;
74030
- var schemaVersion = options && ((_options$config = options.config) === null || _options$config === void 0 ? void 0 : _options$config.schemaVersion);
74031
- var hardwareKey = options && ((_options$config2 = options.config) === null || _options$config2 === void 0 ? void 0 : _options$config2.hardwareKey);
74032
- var serverKey = options && ((_options$config3 = options.config) === null || _options$config3 === void 0 ? void 0 : _options$config3.cmsKey);
74033
- return '/pwa/getResource' + '?v=' + schemaVersion + '&serverKey=' + serverKey + '&hardwareKey=' + hardwareKey + '&layoutId=' + params.layoutId + '&regionId=' + params.regionId + '&mediaId=' + params.mediaId;
74034
- }
74035
- function composeMediaUrl(params) {
74036
- return '/xmds.php?file=' + params.uri;
74037
- }
74038
- function composeBgUrlByPlatform(platform, params) {
74039
- var bgImageUrl = '';
74040
- if (platform === 'CMS') {
74041
- bgImageUrl = params.layoutBackgroundDownloadUrl.replace(":id", params.layout.id) + '&preview=1&width=' + params.layout.sWidth + '&height=' + params.layout.sHeight + '&dynamic&proportional=0';
74042
- } else if (platform === 'chromeOS') {
74043
- bgImageUrl = composeMediaUrl({
74044
- uri: params.layout.bgImage
74045
- });
74046
- }
74047
- // @TODO: Add condition to handle electron platform
74048
- return bgImageUrl;
73392
+ function composeBgUrlByPlatform(platform, params) {
73393
+ var bgImageUrl = '';
73394
+ if (platform === exports.ConsumerPlatform.CMS) {
73395
+ bgImageUrl = params.options.layoutBackgroundDownloadUrl.replace(":id", params.id) + '&preview=1&width=' + params.sWidth + '&height=' + params.sHeight + '&dynamic&proportional=0';
73396
+ } else if (platform === exports.ConsumerPlatform.CHROMEOS) {
73397
+ bgImageUrl = composeMediaUrl({
73398
+ uri: params.bgImage
73399
+ });
73400
+ } else if (platform === exports.ConsumerPlatform.ELECTRON) {
73401
+ bgImageUrl = params.options.appHost + params.bgImage;
73402
+ }
73403
+ return bgImageUrl;
74049
73404
  }
74050
73405
  function getIndexByLayoutId(layoutsInput, layoutId) {
74051
73406
  var layoutIndexes = layoutsInput.reduce(function (a, b, indx) {
@@ -74246,218 +73601,755 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
74246
73601
  case "end":
74247
73602
  return _context.stop();
74248
73603
  }
74249
- }, _callee);
74250
- }))();
73604
+ }, _callee);
73605
+ }))();
73606
+ }
73607
+ }
73608
+ // Check if the media has fade-in/out transitions
73609
+ if (Boolean(self.options['transin']) && Boolean(self.options['transinduration'])) {
73610
+ var transInDuration = Number(self.options.transinduration);
73611
+ var fadeInTrans = transitionElement('fadeIn', {
73612
+ duration: transInDuration
73613
+ });
73614
+ $media.animate(fadeInTrans.keyframes, fadeInTrans.timing);
73615
+ }
73616
+ // Add media to the region
73617
+ // Second media if exists, will be off-canvas
73618
+ // All added media will be hidden by default
73619
+ // It will start showing when region.nextMedia() function is called
73620
+ // When there's only 1 item and loop = false, don't remove the item but leave it at its last state
73621
+ // For image, and only 1 item, it should still have the transition for next state
73622
+ // Add conditions for video duration being 0 or 1 and also the loop property
73623
+ // For video url, we have to create a URL out of the XLF video URL
73624
+ /**
73625
+ * @DONE
73626
+ * Case 1: Video duration = 0, this will play the video for its entire duration
73627
+ * Case 2: Video duration is set > 0 and loop = false
73628
+ * E.g. Set duration = 100s, video duration = 62s
73629
+ * the video will play until 62s and will stop to its last frame until 100s
73630
+ * After 100s, it will expire
73631
+ * Case 3: Video duration is set > 0 and loop = true
73632
+ * E.g. Set duration = 100s, video duration = 62s, loop = true
73633
+ * the video will play until 62s and will loop through until the remaining 38s
73634
+ * to complete the 100s set duration
73635
+ */
73636
+ // Add html node to media for
73637
+ // self.html = $media;
73638
+ return $media;
73639
+ }
73640
+ function prepareVideoMedia(media, region) {
73641
+ var mediaId = getMediaId(media);
73642
+ // Check if html is ready and is in the DOM
73643
+ if (media.html !== null) {
73644
+ // Clean up video.js instance
73645
+ var existingPlayer = videojs.getPlayer(mediaId);
73646
+ if (existingPlayer !== undefined) {
73647
+ existingPlayer.dispose();
73648
+ media.player = undefined;
73649
+ }
73650
+ var $layout = region.layout.html;
73651
+ var layoutSelector = '#' + region.layout.containerName + '[data-sequence="' + region.layout.index + '"]';
73652
+ var $layoutWithIndex = document.querySelector(layoutSelector);
73653
+ var $region = document.querySelector('#' + region.containerName);
73654
+ var mediaInRegion = $region === null || $region === void 0 ? void 0 : $region.querySelector('.' + mediaId);
73655
+ console.debug('??? XLR.debug >> [Generators::prepareVideoMedia]', {
73656
+ layoutSelector: layoutSelector,
73657
+ $layoutWithIndex: $layoutWithIndex,
73658
+ $region: $region,
73659
+ mediaInRegion: mediaInRegion,
73660
+ mediaHtml: media.html,
73661
+ existingPlayer: existingPlayer,
73662
+ mediaId: mediaId,
73663
+ layoutInDOM: document.body.contains($layout)
73664
+ });
73665
+ if (!mediaInRegion) {
73666
+ media.html = createMediaElement(media);
73667
+ } else {
73668
+ mediaInRegion.remove();
73669
+ media.html = createMediaElement(media);
73670
+ }
73671
+ // Append fresh copy of the media into the region
73672
+ $region !== null && $region.appendChild(media.html);
73673
+ var isMediaInDOM = document.body.contains(media.html);
73674
+ console.debug('??? XLR.debug >> [Generators::prepareVideoMedia]', {
73675
+ isMediaInDOM: isMediaInDOM,
73676
+ mediaHtml: media.html,
73677
+ mediaId: mediaId
73678
+ });
73679
+ // Initialize video.js
73680
+ media.player = videojs(mediaId, _objectSpread2(_objectSpread2({}, defaultVjsOpts), {}, {
73681
+ errorDisplay: region.xlr.config.platform !== exports.ConsumerPlatform.CHROMEOS,
73682
+ loop: media.loop
73683
+ }));
73684
+ media.player.on('error', /*#__PURE__*/function () {
73685
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(err) {
73686
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
73687
+ while (1) switch (_context2.prev = _context2.next) {
73688
+ case 0:
73689
+ if (media.region.xlr.config.platform === exports.ConsumerPlatform.CHROMEOS) {
73690
+ playerReportFault('Video file not supported', media).then(function () {
73691
+ media.emitter.emit('end', media);
73692
+ });
73693
+ }
73694
+ case 1:
73695
+ case "end":
73696
+ return _context2.stop();
73697
+ }
73698
+ }, _callee2);
73699
+ }));
73700
+ return function (_x10) {
73701
+ return _ref3.apply(this, arguments);
73702
+ };
73703
+ }());
73704
+ media.player.el().style.setProperty('visibility', 'hidden');
73705
+ media.player.el().style.setProperty('opacity', '0');
73706
+ media.player.el().style.setProperty('z-index', '-99');
73707
+ }
73708
+ }
73709
+ function prepareImageMedia(media, region) {
73710
+ var mediaId = getMediaId(media);
73711
+ media.html.style.setProperty('background-image', "url(".concat(media.url));
73712
+ // Check if media in region
73713
+ // Remove old copy before inserting fresh copy
73714
+ var mediaInRegion = region.html.querySelector('.' + mediaId);
73715
+ if (mediaInRegion) {
73716
+ mediaInRegion.remove();
73717
+ }
73718
+ // Append media to its region
73719
+ var $region = document.querySelector('#' + region.containerName);
73720
+ $region !== null && $region.appendChild(media.html);
73721
+ }
73722
+ function prepareAudioMedia(media, region) {
73723
+ var mediaId = getMediaId(media);
73724
+ if (media.url !== null) {
73725
+ media.html.src = media.url;
73726
+ }
73727
+ // Check if media in region
73728
+ // Remove old copy before inserting fresh copy of the media
73729
+ var mediaInRegion = region.html.querySelector('.' + mediaId);
73730
+ if (mediaInRegion) {
73731
+ mediaInRegion.remove();
73732
+ }
73733
+ // Append media to its region
73734
+ var $region = document.querySelector('#' + region.containerName);
73735
+ $region !== null && $region.appendChild(media.html);
73736
+ }
73737
+ function prepareHtmlMedia(media, region) {
73738
+ // Set state as false ( for now )
73739
+ media.ready = false;
73740
+ if (media.html) {
73741
+ var mediaId = getMediaId(media);
73742
+ // Clean up old copy of the media
73743
+ // before inserting fresh copy
73744
+ var $layout = document.querySelector("#".concat(region.layout.containerName, "[data-sequence=\"").concat(region.layout.index, "\"]"));
73745
+ var $region = $layout.querySelector('#' + region.containerName);
73746
+ var mediaInRegion = $region.querySelector('.' + mediaId);
73747
+ console.debug('<><> XLR.debug >> [Media] - [Generators::prepareHtmlMedia]', {
73748
+ mediaId: mediaId,
73749
+ mediaInRegion: mediaInRegion
73750
+ });
73751
+ // Append iframe
73752
+ media.html.innerHTML = '';
73753
+ media.html.appendChild(media.iframe);
73754
+ if (!mediaInRegion) {
73755
+ // Add fresh copy of the media into the region
73756
+ var _$region = document.querySelector('#' + region.containerName);
73757
+ _$region !== null && _$region.appendChild(media.html);
73758
+ media.ready = true;
73759
+ }
73760
+ }
73761
+ }
73762
+ function playerReportFault(_x11, _x12) {
73763
+ return _playerReportFault.apply(this, arguments);
73764
+ }
73765
+ function _playerReportFault() {
73766
+ _playerReportFault = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(msg, media) {
73767
+ var playerSW, hasSW;
73768
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
73769
+ while (1) switch (_context7.prev = _context7.next) {
73770
+ case 0:
73771
+ // Immediately expire media and report a fault
73772
+ playerSW = PwaSW();
73773
+ _context7.next = 3;
73774
+ return playerSW.getSW();
73775
+ case 3:
73776
+ hasSW = _context7.sent;
73777
+ if (hasSW) {
73778
+ playerSW.postMsg({
73779
+ type: 'MEDIA_FAULT',
73780
+ code: 5002,
73781
+ reason: msg,
73782
+ mediaId: media.id,
73783
+ regionId: media.region.id,
73784
+ layoutId: media.region.layout.id,
73785
+ date: format(new Date(), 'yyyy-MM-dd HH:mm:ss'),
73786
+ // Temporary setting
73787
+ expires: format(new Date(setExpiry(1)), 'yyyy-MM-dd HH:mm:ss')
73788
+ }).then(function () {
73789
+ // We try to prepare next media if we have more than 1 media
73790
+ if (media.region.totalMediaObjects > 1) {
73791
+ media.region.prepareNextMedia();
73792
+ }
73793
+ })["finally"](function () {
73794
+ // Stopping media as we have reported the error as fault
73795
+ console.debug('??? XLR.debug >> VideoMedia - Done reporting media fault', {
73796
+ mediaId: media.id,
73797
+ regionItems: media.region.totalMediaObjects
73798
+ });
73799
+ });
73800
+ }
73801
+ case 5:
73802
+ case "end":
73803
+ return _context7.stop();
73804
+ }
73805
+ }, _callee7);
73806
+ }));
73807
+ return _playerReportFault.apply(this, arguments);
73808
+ }
73809
+
73810
+ const urlAlphabet =
73811
+ 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
73812
+
73813
+ /* @ts-self-types="./index.d.ts" */
73814
+ let nanoid = (size = 21) => {
73815
+ let id = '';
73816
+ let bytes = crypto.getRandomValues(new Uint8Array((size |= 0)));
73817
+ while (size--) {
73818
+ id += urlAlphabet[bytes[size] & 63];
73819
+ }
73820
+ return id
73821
+ };
73822
+
73823
+ function AudioMedia(media) {
73824
+ var audioMediaObject = {
73825
+ init: function init() {
73826
+ var $audioMedia = document.getElementById(getMediaId(media));
73827
+ var $playBtn = null;
73828
+ if ($audioMedia) {
73829
+ $audioMedia.onloadstart = function () {
73830
+ console.debug("".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has started loading data . . ."));
73831
+ };
73832
+ $audioMedia.onloadeddata = function () {
73833
+ if ($audioMedia.readyState >= 2) {
73834
+ console.debug("".concat(capitalizeStr(media.mediaType), " data for media > ").concat(media.id, " has been fully loaded . . ."));
73835
+ }
73836
+ };
73837
+ $audioMedia.oncanplay = function () {
73838
+ console.debug("".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " can be played . . ."));
73839
+ };
73840
+ $audioMedia.onplaying = function () {
73841
+ console.debug("".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " is now playing . . ."));
73842
+ if ($playBtn !== null) {
73843
+ $playBtn.remove();
73844
+ }
73845
+ };
73846
+ var audioPlayPromise = $audioMedia.play();
73847
+ if (audioPlayPromise !== undefined) {
73848
+ audioPlayPromise.then(function () {
73849
+ console.debug('autoplay started . . .');
73850
+ // Autoplay restarted
73851
+ })["catch"](function (error) {
73852
+ if (error.name === 'NotAllowedError') {
73853
+ var _$audioMedia$parentNo;
73854
+ // Let's show a play audio button
73855
+ $playBtn = document.createElement('button');
73856
+ $playBtn.classList.add('play-audio-btn');
73857
+ $playBtn.textContent = 'Play Audio';
73858
+ $playBtn.addEventListener('click', function () {
73859
+ $audioMedia.muted = false;
73860
+ $audioMedia.play();
73861
+ });
73862
+ (_$audioMedia$parentNo = $audioMedia.parentNode) === null || _$audioMedia$parentNo === void 0 || _$audioMedia$parentNo.insertBefore($playBtn, $audioMedia.nextSibling);
73863
+ }
73864
+ });
73865
+ }
73866
+ if (media.duration === 0) {
73867
+ $audioMedia.ondurationchange = function () {
73868
+ console.debug('Showing Media ' + media.id + ' for ' + $audioMedia.duration + 's of Region ' + media.region.regionId);
73869
+ };
73870
+ $audioMedia.onended = function () {
73871
+ var _media$emitter;
73872
+ console.debug("".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has ended playing . . ."));
73873
+ (_media$emitter = media.emitter) === null || _media$emitter === void 0 || _media$emitter.emit('end', media);
73874
+ };
73875
+ }
73876
+ }
73877
+ }
73878
+ };
73879
+ return audioMediaObject;
73880
+ }
73881
+
73882
+ var Media = /*#__PURE__*/function () {
73883
+ function Media(region, mediaId, xml, options, xlr) {
73884
+ var _this$xml,
73885
+ _this$xml2,
73886
+ _this$xml3,
73887
+ _this$xml4,
73888
+ _this$xml5,
73889
+ _this = this;
73890
+ _classCallCheck(this, Media);
73891
+ _defineProperty(this, "attachedAudio", false);
73892
+ _defineProperty(this, "checkIframeStatus", false);
73893
+ _defineProperty(this, "containerName", '');
73894
+ _defineProperty(this, "divHeight", 0);
73895
+ _defineProperty(this, "divWidth", 0);
73896
+ _defineProperty(this, "duration", 0);
73897
+ _defineProperty(this, "emitter", createNanoEvents());
73898
+ _defineProperty(this, "enableStat", false);
73899
+ _defineProperty(this, "fileId", '');
73900
+ _defineProperty(this, "finished", false);
73901
+ _defineProperty(this, "html", null);
73902
+ _defineProperty(this, "id", '');
73903
+ _defineProperty(this, "idCounter", 0);
73904
+ _defineProperty(this, "iframe", null);
73905
+ _defineProperty(this, "iframeName", '');
73906
+ _defineProperty(this, "index", 0);
73907
+ _defineProperty(this, "loadIframeOnRun", false);
73908
+ _defineProperty(this, "loop", false);
73909
+ _defineProperty(this, "mediaId", '');
73910
+ _defineProperty(this, "mediaType", '');
73911
+ _defineProperty(this, "muted", false);
73912
+ _defineProperty(this, "options", {});
73913
+ _defineProperty(this, "player", undefined);
73914
+ _defineProperty(this, "ready", true);
73915
+ _defineProperty(this, "region", {});
73916
+ _defineProperty(this, "render", 'html');
73917
+ _defineProperty(this, "schemaVersion", '1');
73918
+ _defineProperty(this, "singlePlay", false);
73919
+ _defineProperty(this, "state", MediaState.IDLE);
73920
+ _defineProperty(this, "tempSrc", '');
73921
+ _defineProperty(this, "timeoutId", setTimeout(function () {}, 0));
73922
+ _defineProperty(this, "type", '');
73923
+ _defineProperty(this, "uri", '');
73924
+ _defineProperty(this, "url", null);
73925
+ _defineProperty(this, "useDuration", false);
73926
+ _defineProperty(this, "xml", null);
73927
+ _defineProperty(this, "videoHandler", void 0);
73928
+ _defineProperty(this, "mediaTimer", void 0);
73929
+ _defineProperty(this, "mediaTimeCount", 0);
73930
+ _defineProperty(this, "xlr", {});
73931
+ _defineProperty(this, "statsBC", new BroadcastChannel('statsBC'));
73932
+ _defineProperty(this, "hasCommandExecuted", void 0);
73933
+ this.region = region;
73934
+ this.id = mediaId;
73935
+ this.mediaId = this.id;
73936
+ this.xml = xml;
73937
+ this.options = options;
73938
+ this.xlr = xlr;
73939
+ this.fileId = ((_this$xml = this.xml) === null || _this$xml === void 0 ? void 0 : _this$xml.getAttribute('fileId')) || '';
73940
+ this.idCounter = nextId(this.options);
73941
+ this.containerName = "M-".concat(this.id, "-").concat(this.idCounter);
73942
+ this.iframeName = "".concat(this.containerName, "-iframe");
73943
+ this.mediaType = ((_this$xml2 = this.xml) === null || _this$xml2 === void 0 ? void 0 : _this$xml2.getAttribute('type')) || '';
73944
+ this.render = ((_this$xml3 = this.xml) === null || _this$xml3 === void 0 ? void 0 : _this$xml3.getAttribute('render')) || '';
73945
+ this.duration = parseInt((_this$xml4 = this.xml) === null || _this$xml4 === void 0 ? void 0 : _this$xml4.getAttribute('duration')) || 0;
73946
+ this.enableStat = Boolean(((_this$xml5 = this.xml) === null || _this$xml5 === void 0 ? void 0 : _this$xml5.getAttribute('enableStat')) || false);
73947
+ this.hasCommandExecuted = false;
73948
+ this.on('start', function (media) {
73949
+ if (media.state === MediaState.PLAYING) return;
73950
+ media.state = MediaState.PLAYING;
73951
+ if (media.mediaType === 'video') {
73952
+ var videoMedia = VideoMedia(media, _this.xlr);
73953
+ videoMedia.init();
73954
+ if (media.duration > 0) {
73955
+ _this.startMediaTimer(media);
73956
+ }
73957
+ } else if (media.mediaType === 'audio') {
73958
+ AudioMedia(media).init();
73959
+ if (media.duration > 0) {
73960
+ _this.startMediaTimer(media);
73961
+ }
73962
+ } else if (media.mediaType === 'shellcommand') {
73963
+ if (_this.hasCommandExecuted && !_this.loop) {
73964
+ return;
73965
+ }
73966
+ _this.hasCommandExecuted = true;
73967
+ _this.emitCommand(media);
73968
+ if (media.duration > 0) {
73969
+ _this.startMediaTimer(media);
73970
+ }
73971
+ } else {
73972
+ _this.startMediaTimer(media);
73973
+ }
73974
+ // Check if stats are enabled for the layout
73975
+ if (media.enableStat) {
73976
+ _this.statsBC.postMessage({
73977
+ action: 'START_STAT',
73978
+ mediaId: parseInt(media.id),
73979
+ layoutId: media.region.layout.id,
73980
+ scheduleId: media.region.layout.scheduleId,
73981
+ type: 'media'
73982
+ });
73983
+ }
73984
+ // Emit media/widget start event
73985
+ console.debug('Media::Emitter > Start - Calling widgetStart event');
73986
+ _this.xlr.emitter.emit('widgetStart', parseInt(media.id));
73987
+ });
73988
+ this.on('end', function (media) {
73989
+ if (media.state === MediaState.ENDED) return;
73990
+ media.state = MediaState.ENDED;
73991
+ if (_this.mediaTimer) {
73992
+ clearInterval(_this.mediaTimer);
73993
+ _this.mediaTimeCount = 0;
73994
+ }
73995
+ // Check if stats are enabled for the layout
73996
+ if (media.enableStat) {
73997
+ _this.statsBC.postMessage({
73998
+ action: 'END_STAT',
73999
+ mediaId: parseInt(media.id),
74000
+ layoutId: media.region.layout.id,
74001
+ scheduleId: media.region.layout.scheduleId,
74002
+ type: 'media'
74003
+ });
74004
+ }
74005
+ // Emit media/widget end event
74006
+ console.debug('Media::Emitter > End - Calling widgetEnd event', {
74007
+ mediaId: media.id,
74008
+ regionId: media.region.id,
74009
+ layoutId: media.region.layout.id
74010
+ });
74011
+ _this.xlr.emitter.emit('widgetEnd', parseInt(media.id));
74012
+ media.region.playNextMedia();
74013
+ });
74014
+ this.on('cancelled', function (media) {
74015
+ if (media.state === MediaState.CANCELLED) return;
74016
+ media.state = MediaState.CANCELLED;
74017
+ if (_this.mediaTimer) {
74018
+ clearInterval(_this.mediaTimer);
74019
+ _this.mediaTimeCount = 0;
74020
+ }
74021
+ // Check if stats are enabled for the layout
74022
+ if (media.enableStat) {
74023
+ _this.statsBC.postMessage({
74024
+ action: 'END_STAT',
74025
+ mediaId: parseInt(media.id),
74026
+ layoutId: media.region.layout.id,
74027
+ scheduleId: media.region.layout.scheduleId,
74028
+ type: 'media'
74029
+ });
74030
+ }
74031
+ // Emit media/widget end event
74032
+ console.debug('Media::Emitter > End - Calling widgetEnd event', {
74033
+ mediaId: media.id,
74034
+ regionId: media.region.id,
74035
+ layoutId: media.region.layout.id
74036
+ });
74037
+ _this.xlr.emitter.emit('widgetEnd', parseInt(media.id));
74038
+ media.region.playNextMedia();
74039
+ });
74040
+ // Initialize Media object
74041
+ this.init();
74042
+ }
74043
+ return _createClass(Media, [{
74044
+ key: "startMediaTimer",
74045
+ value: function startMediaTimer(media) {
74046
+ var _this2 = this;
74047
+ var preloadTimeMs = 2000;
74048
+ var preloadTimeBufferMs = media.duration * 1000 / 2 - preloadTimeMs;
74049
+ var isPreparingNextMedia = false;
74050
+ if (preloadTimeBufferMs < preloadTimeMs) {
74051
+ // Use media duration when preloadTimeBufferMs is less than the preloadTimeMs
74052
+ preloadTimeBufferMs = media.duration / 2 * 1000;
74053
+ }
74054
+ console.debug('<><> XLR.debug >> [Media::startMediaTimer]', {
74055
+ preloadTimeMs: preloadTimeMs,
74056
+ preloadTimeBufferMs: preloadTimeBufferMs,
74057
+ isPreparingNextMedia: isPreparingNextMedia,
74058
+ mediaDuration: media.duration
74059
+ });
74060
+ this.mediaTimer = setInterval(function () {
74061
+ _this2.mediaTimeCount++;
74062
+ var elapsedTimeMs = _this2.mediaTimeCount * 1000;
74063
+ // prepare region's next media
74064
+ if (_this2.region.totalMediaObjects > 1 && elapsedTimeMs >= preloadTimeBufferMs && !isPreparingNextMedia) {
74065
+ isPreparingNextMedia = true;
74066
+ _this2.region.prepareNextMedia();
74067
+ }
74068
+ if (_this2.mediaTimeCount > media.duration) {
74069
+ console.debug('??? XLR.debug >> Media::startMediaTimer: emit>end: on media ' + media.id + ' of Region ' + media.region.regionId);
74070
+ console.debug('??? XLR.debug >> Media::startMediaTimer - Media::Emitter > End', {
74071
+ currentLayout: _this2.xlr.currentLayout,
74072
+ media: media,
74073
+ region: media.region,
74074
+ layout: media.region.layout
74075
+ });
74076
+ media.emitter.emit('end', media);
74077
+ if (media.mediaType === 'video') {
74078
+ // Dispose the video media
74079
+ console.debug("??? XLR.debug >> VideoMedia::stop - ".concat(capitalizeStr(media.mediaType), " for media > ").concat(media.id, " has ended playing . . ."));
74080
+ if (media.player !== undefined) {
74081
+ VideoMedia(media, _this2.xlr).stop(true);
74082
+ }
74083
+ }
74084
+ }
74085
+ }, 1000);
74086
+ console.debug('startMediaTimer: Showing Media ' + media.id + ' for ' + media.duration + 's of Region ' + media.region.regionId);
74251
74087
  }
74252
- }
74253
- // Check if the media has fade-in/out transitions
74254
- if (Boolean(self.options['transin']) && Boolean(self.options['transinduration'])) {
74255
- var transInDuration = Number(self.options.transinduration);
74256
- var fadeInTrans = transitionElement('fadeIn', {
74257
- duration: transInDuration
74258
- });
74259
- $media.animate(fadeInTrans.keyframes, fadeInTrans.timing);
74260
- }
74261
- // Add media to the region
74262
- // Second media if exists, will be off-canvas
74263
- // All added media will be hidden by default
74264
- // It will start showing when region.nextMedia() function is called
74265
- // When there's only 1 item and loop = false, don't remove the item but leave it at its last state
74266
- // For image, and only 1 item, it should still have the transition for next state
74267
- // Add conditions for video duration being 0 or 1 and also the loop property
74268
- // For video url, we have to create a URL out of the XLF video URL
74269
- /**
74270
- * @DONE
74271
- * Case 1: Video duration = 0, this will play the video for its entire duration
74272
- * Case 2: Video duration is set > 0 and loop = false
74273
- * E.g. Set duration = 100s, video duration = 62s
74274
- * the video will play until 62s and will stop to its last frame until 100s
74275
- * After 100s, it will expire
74276
- * Case 3: Video duration is set > 0 and loop = true
74277
- * E.g. Set duration = 100s, video duration = 62s, loop = true
74278
- * the video will play until 62s and will loop through until the remaining 38s
74279
- * to complete the 100s set duration
74280
- */
74281
- // Add html node to media for
74282
- // self.html = $media;
74283
- return $media;
74284
- }
74285
- function prepareVideoMedia(media, region) {
74286
- var mediaId = getMediaId(media);
74287
- // Check if html is ready and is in the DOM
74288
- if (media.html !== null) {
74289
- // Clean up video.js instance
74290
- var existingPlayer = videojs.getPlayer(mediaId);
74291
- if (existingPlayer !== undefined) {
74292
- existingPlayer.dispose();
74293
- media.player = undefined;
74088
+ }, {
74089
+ key: "on",
74090
+ value: function on(event, callback) {
74091
+ return this.emitter.on(event, callback);
74294
74092
  }
74295
- var $layout = region.layout.html;
74296
- var layoutSelector = '#' + region.layout.containerName + '[data-sequence="' + region.layout.index + '"]';
74297
- var $layoutWithIndex = document.querySelector(layoutSelector);
74298
- var $region = document.querySelector('#' + region.containerName);
74299
- var mediaInRegion = $region === null || $region === void 0 ? void 0 : $region.querySelector('.' + mediaId);
74300
- console.debug('??? XLR.debug >> [Generators::prepareVideoMedia]', {
74301
- layoutSelector: layoutSelector,
74302
- $layoutWithIndex: $layoutWithIndex,
74303
- $region: $region,
74304
- mediaInRegion: mediaInRegion,
74305
- mediaHtml: media.html,
74306
- existingPlayer: existingPlayer,
74307
- mediaId: mediaId,
74308
- layoutInDOM: document.body.contains($layout)
74309
- });
74310
- if (!mediaInRegion) {
74311
- media.html = createMediaElement(media);
74312
- } else {
74313
- mediaInRegion.remove();
74314
- media.html = createMediaElement(media);
74093
+ }, {
74094
+ key: "init",
74095
+ value: function init() {
74096
+ var _this$xml6;
74097
+ var mediaOptions = (_this$xml6 = this.xml) === null || _this$xml6 === void 0 ? void 0 : _this$xml6.getElementsByTagName('options');
74098
+ if (mediaOptions) {
74099
+ for (var _i = 0, _Array$from = Array.from(mediaOptions); _i < _Array$from.length; _i++) {
74100
+ var _options = _Array$from[_i];
74101
+ // Get options
74102
+ var _mediaOptions = _options.children;
74103
+ for (var _i2 = 0, _Array$from2 = Array.from(_mediaOptions); _i2 < _Array$from2.length; _i2++) {
74104
+ var mediaOption = _Array$from2[_i2];
74105
+ this.options[mediaOption.nodeName.toLowerCase()] = mediaOption.textContent;
74106
+ }
74107
+ }
74108
+ }
74109
+ // Check for options.uri and add it to media
74110
+ if (Boolean(this.options['uri'])) {
74111
+ this.uri = this.options['uri'];
74112
+ }
74113
+ // Show in fullscreen?
74114
+ if (this.options.showfullscreen === "1") {
74115
+ // Set dimensions as the layout ones
74116
+ this.divWidth = this.region.layout.sWidth;
74117
+ this.divHeight = this.region.layout.sHeight;
74118
+ } else {
74119
+ // Set dimensions as the region ones
74120
+ this.divWidth = this.region.sWidth;
74121
+ this.divHeight = this.region.sHeight;
74122
+ }
74123
+ var resourceUrlParams = _objectSpread2(_objectSpread2({}, this.xlr.config.config), {}, {
74124
+ regionOptions: this.region.options,
74125
+ layoutId: this.region.layout.layoutId,
74126
+ regionId: this.region.id,
74127
+ mediaId: this.id,
74128
+ fileId: this.fileId,
74129
+ scaleFactor: this.region.layout.scaleFactor,
74130
+ uri: this.uri,
74131
+ isGlobalContent: this.mediaType === 'global',
74132
+ isImageOrVideo: this.mediaType === 'image' || this.mediaType === 'video',
74133
+ render: this.render
74134
+ });
74135
+ if (this.mediaType === 'image' || this.mediaType === 'video') {
74136
+ resourceUrlParams.mediaType = this.mediaType;
74137
+ }
74138
+ var tmpUrl = '';
74139
+ if (this.xlr.config.platform === exports.ConsumerPlatform.CMS) {
74140
+ tmpUrl = composeResourceUrlByPlatform(this.xlr.config, resourceUrlParams);
74141
+ } else if (this.xlr.config.platform === exports.ConsumerPlatform.CHROMEOS) {
74142
+ tmpUrl = composeResourceUrl(this.xlr.config, resourceUrlParams);
74143
+ if (this.mediaType === 'image' || this.mediaType === 'video' || this.mediaType === 'audio') {
74144
+ tmpUrl = composeMediaUrl(resourceUrlParams);
74145
+ // this is an SSP Layout
74146
+ if (this.region.layout.layoutId === -1) {
74147
+ tmpUrl = this.uri;
74148
+ }
74149
+ }
74150
+ } else if (this.xlr.config.platform === exports.ConsumerPlatform.ELECTRON) {
74151
+ tmpUrl = composeResourceUrlByPlatform(this.xlr.config, resourceUrlParams);
74152
+ }
74153
+ this.url = tmpUrl;
74154
+ // Loop if media has loop, or if region has loop and a single media
74155
+ this.loop = this.options['loop'] == '1' || this.region.options['loop'] == '1' && this.region.totalMediaObjects == 1;
74156
+ this.html = createMediaElement(this);
74315
74157
  }
74316
- // Append fresh copy of the media into the region
74317
- $region !== null && $region.appendChild(media.html);
74318
- var isMediaInDOM = document.body.contains(media.html);
74319
- console.debug('??? XLR.debug >> [Generators::prepareVideoMedia]', {
74320
- isMediaInDOM: isMediaInDOM,
74321
- mediaHtml: media.html,
74322
- mediaId: mediaId
74323
- });
74324
- // Initialize video.js
74325
- media.player = videojs(mediaId, _objectSpread2(_objectSpread2({}, defaultVjsOpts), {}, {
74326
- errorDisplay: region.xlr.config.platform !== exports.ConsumerPlatform.CHROMEOS,
74327
- loop: media.loop
74328
- }));
74329
- media.player.on('error', /*#__PURE__*/function () {
74330
- var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(err) {
74331
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
74332
- while (1) switch (_context2.prev = _context2.next) {
74158
+ }, {
74159
+ key: "run",
74160
+ value: function run() {
74161
+ var _this3 = this;
74162
+ var transInDuration = 1;
74163
+ var transInDirection = 'E';
74164
+ if (Boolean(this.options['transinduration'])) {
74165
+ transInDuration = Number(this.options.transinduration);
74166
+ }
74167
+ if (Boolean(this.options['transindirection'])) {
74168
+ transInDirection = this.options.transindirection;
74169
+ }
74170
+ var defaultTransInOptions = {
74171
+ duration: transInDuration
74172
+ };
74173
+ var transIn = transitionElement('defaultIn', {
74174
+ duration: defaultTransInOptions.duration
74175
+ });
74176
+ if (Boolean(this.options['transin'])) {
74177
+ var transInName = this.options['transin'];
74178
+ if (transInName === 'fly') {
74179
+ transInName = "".concat(transInName, "In");
74180
+ defaultTransInOptions.keyframes = flyTransitionKeyframes({
74181
+ trans: 'in',
74182
+ direction: transInDirection,
74183
+ height: this.divHeight,
74184
+ width: this.divWidth
74185
+ });
74186
+ }
74187
+ transIn = transitionElement(transInName, defaultTransInOptions);
74188
+ }
74189
+ var showCurrentMedia = function showCurrentMedia() {
74190
+ var mediaId = getMediaId({
74191
+ mediaType: _this3.mediaType,
74192
+ containerName: _this3.containerName
74193
+ });
74194
+ var $region = document.querySelector('#' + _this3.region.containerName);
74195
+ var $media = $region !== null && $region.querySelector('.' + mediaId);
74196
+ if (!$media) {
74197
+ $media = getNewMedia();
74198
+ }
74199
+ console.debug('??? XLR.debug >> Media run - show current media:', {
74200
+ inDOM: document.body.contains($media),
74201
+ mediaId: mediaId,
74202
+ $media: $media,
74203
+ mediaObject: _this3
74204
+ });
74205
+ if ($media) {
74206
+ if (_this3.mediaType === 'video') {
74207
+ var _this3$player, _this3$player2, _this3$player3, _this3$player4;
74208
+ console.debug('??? XLR.debug >> Media.run() > showCurrentMedia() - Video media::START', {
74209
+ mediaPlayer: _this3.player,
74210
+ isDisposed: (_this3$player = _this3.player) === null || _this3$player === void 0 ? void 0 : _this3$player.isDisposed(),
74211
+ el: (_this3$player2 = _this3.player) === null || _this3$player2 === void 0 ? void 0 : _this3$player2.el_
74212
+ });
74213
+ // Make sure that vjs is available on the media
74214
+ // Else, re-initialize
74215
+ if (_this3.player !== undefined) {
74216
+ var existingPlayer = videojs(mediaId);
74217
+ if (existingPlayer) {
74218
+ _this3.player = existingPlayer;
74219
+ } else {
74220
+ if (_this3.player.isDisposed_) {
74221
+ _this3.player = undefined;
74222
+ _this3.player = videojs(mediaId, _objectSpread2({}, vjsDefaultOptions({
74223
+ errorDisplay: _this3.xlr.config.platform !== exports.ConsumerPlatform.CHROMEOS,
74224
+ loop: _this3.loop
74225
+ })));
74226
+ }
74227
+ }
74228
+ }
74229
+ console.debug('??? XLR.debug >> Media.run() > showCurrentMedia() - Video media::END', {
74230
+ mediaPlayer: _this3.player,
74231
+ isDisposed: (_this3$player3 = _this3.player) === null || _this3$player3 === void 0 ? void 0 : _this3$player3.isDisposed(),
74232
+ el: (_this3$player4 = _this3.player) === null || _this3$player4 === void 0 ? void 0 : _this3$player4.el_
74233
+ });
74234
+ if (_this3.player !== undefined && _this3.player.el_ !== null) {
74235
+ _this3.player.el().style.setProperty('visibility', 'visible');
74236
+ _this3.player.el().style.setProperty('z-index', '10');
74237
+ _this3.player.el().style.setProperty('opacity', '1');
74238
+ }
74239
+ } else {
74240
+ console.debug('??? XLR.debug >> Media::run() > showCurrentMedia', {
74241
+ mediaType: _this3.mediaType,
74242
+ render: _this3.render,
74243
+ $media: $media,
74244
+ state: _this3.state
74245
+ });
74246
+ $media.style.setProperty('visibility', 'visible');
74247
+ $media.style.setProperty('z-index', '10');
74248
+ $media.style.setProperty('opacity', '1');
74249
+ }
74250
+ if (Boolean(_this3.options['transin'])) {
74251
+ $media.animate(transIn.keyframes, transIn.timing);
74252
+ }
74253
+ if (!_this3.region.layout.isOverlay || _this3.region.layout.isOverlay && _this3.region.totalMediaObjects > 1) {
74254
+ _this3.emitter.emit('start', _this3);
74255
+ }
74256
+ }
74257
+ };
74258
+ var getNewMedia = function getNewMedia() {
74259
+ var $region = document.getElementById("".concat(_this3.region.containerName));
74260
+ // This function is for checking whether
74261
+ // the region still has to show a media item
74262
+ // when another region is not finished yet
74263
+ if (_this3.region.complete && !_this3.region.layout.allEnded) {
74264
+ // Add currentMedia to the region
74265
+ $region && $region.insertBefore(_this3.html, $region.lastElementChild);
74266
+ return _this3.html;
74267
+ }
74268
+ return null;
74269
+ };
74270
+ showCurrentMedia();
74271
+ }
74272
+ }, {
74273
+ key: "stop",
74274
+ value: function () {
74275
+ var _stop = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
74276
+ var $media;
74277
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
74278
+ while (1) switch (_context.prev = _context.next) {
74333
74279
  case 0:
74334
- if (media.region.xlr.config.platform === exports.ConsumerPlatform.CHROMEOS) {
74335
- playerReportFault('Video file not supported', media).then(function () {
74336
- media.emitter.emit('end', media);
74337
- });
74280
+ $media = document.getElementById(getMediaId({
74281
+ mediaType: this.mediaType,
74282
+ containerName: this.containerName
74283
+ }));
74284
+ if ($media) {
74285
+ $media.style.display = 'none';
74286
+ $media.remove();
74338
74287
  }
74339
- case 1:
74288
+ // Release blob URLs for image media to prevent memory leaks on long-running signage
74289
+ if (this.mediaType === 'image' && this.url) {
74290
+ BlobLoader.release(this.url);
74291
+ }
74292
+ case 3:
74340
74293
  case "end":
74341
- return _context2.stop();
74294
+ return _context.stop();
74342
74295
  }
74343
- }, _callee2);
74296
+ }, _callee, this);
74344
74297
  }));
74345
- return function (_x10) {
74346
- return _ref3.apply(this, arguments);
74347
- };
74348
- }());
74349
- media.player.el().style.setProperty('visibility', 'hidden');
74350
- media.player.el().style.setProperty('opacity', '0');
74351
- media.player.el().style.setProperty('z-index', '-99');
74352
- }
74353
- }
74354
- function prepareImageMedia(media, region) {
74355
- var mediaId = getMediaId(media);
74356
- media.html.style.setProperty('background-image', "url(".concat(media.url));
74357
- // Check if media in region
74358
- // Remove old copy before inserting fresh copy
74359
- var mediaInRegion = region.html.querySelector('.' + mediaId);
74360
- if (mediaInRegion) {
74361
- mediaInRegion.remove();
74362
- }
74363
- // Append media to its region
74364
- var $region = document.querySelector('#' + region.containerName);
74365
- $region !== null && $region.appendChild(media.html);
74366
- }
74367
- function prepareAudioMedia(media, region) {
74368
- var mediaId = getMediaId(media);
74369
- if (media.url !== null) {
74370
- media.html.src = media.url;
74371
- }
74372
- // Check if media in region
74373
- // Remove old copy before inserting fresh copy of the media
74374
- var mediaInRegion = region.html.querySelector('.' + mediaId);
74375
- if (mediaInRegion) {
74376
- mediaInRegion.remove();
74377
- }
74378
- // Append media to its region
74379
- var $region = document.querySelector('#' + region.containerName);
74380
- $region !== null && $region.appendChild(media.html);
74381
- }
74382
- function prepareHtmlMedia(media, region) {
74383
- // Set state as false ( for now )
74384
- media.ready = false;
74385
- if (media.html) {
74386
- var mediaId = getMediaId(media);
74387
- // Clean up old copy of the media
74388
- // before inserting fresh copy
74389
- var mediaInRegion = region.html.querySelector('.' + mediaId);
74390
- // Append iframe
74391
- media.html.innerHTML = '';
74392
- media.html.appendChild(media.iframe);
74393
- if (!mediaInRegion) {
74394
- // Add fresh copy of the media into the region
74395
- var $region = document.querySelector('#' + region.containerName);
74396
- $region !== null && $region.appendChild(media.html);
74397
- media.ready = true;
74398
- }
74399
- }
74400
- }
74401
- function playerReportFault(_x11, _x12) {
74402
- return _playerReportFault.apply(this, arguments);
74403
- }
74404
- function _playerReportFault() {
74405
- _playerReportFault = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(msg, media) {
74406
- var playerSW, hasSW;
74407
- return _regeneratorRuntime().wrap(function _callee7$(_context7) {
74408
- while (1) switch (_context7.prev = _context7.next) {
74409
- case 0:
74410
- // Immediately expire media and report a fault
74411
- playerSW = PwaSW();
74412
- _context7.next = 3;
74413
- return playerSW.getSW();
74414
- case 3:
74415
- hasSW = _context7.sent;
74416
- if (hasSW) {
74417
- playerSW.postMsg({
74418
- type: 'MEDIA_FAULT',
74419
- code: 5002,
74420
- reason: msg,
74421
- mediaId: media.id,
74422
- regionId: media.region.id,
74423
- layoutId: media.region.layout.id,
74424
- date: format(new Date(), 'yyyy-MM-dd HH:mm:ss'),
74425
- // Temporary setting
74426
- expires: format(new Date(setExpiry(1)), 'yyyy-MM-dd HH:mm:ss')
74427
- }).then(function () {
74428
- // We try to prepare next media if we have more than 1 media
74429
- if (media.region.totalMediaObjects > 1) {
74430
- media.region.prepareNextMedia();
74431
- }
74432
- })["finally"](function () {
74433
- // Stopping media as we have reported the error as fault
74434
- console.debug('??? XLR.debug >> VideoMedia - Done reporting media fault', {
74435
- mediaId: media.id,
74436
- regionItems: media.region.totalMediaObjects
74437
- });
74438
- });
74439
- }
74440
- case 5:
74441
- case "end":
74442
- return _context7.stop();
74298
+ function stop() {
74299
+ return _stop.apply(this, arguments);
74443
74300
  }
74444
- }, _callee7);
74445
- }));
74446
- return _playerReportFault.apply(this, arguments);
74447
- }
74448
-
74449
- const urlAlphabet =
74450
- 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
74451
-
74452
- /* @ts-self-types="./index.d.ts" */
74453
- let nanoid = (size = 21) => {
74454
- let id = '';
74455
- let bytes = crypto.getRandomValues(new Uint8Array((size |= 0)));
74456
- while (size--) {
74457
- id += urlAlphabet[bytes[size] & 63];
74458
- }
74459
- return id
74460
- };
74301
+ return stop;
74302
+ }()
74303
+ /**
74304
+ * Emits a command from the shell command widget.
74305
+ *
74306
+ * @param media
74307
+ * @private
74308
+ */
74309
+ }, {
74310
+ key: "emitCommand",
74311
+ value: function emitCommand(media) {
74312
+ if (media.mediaType !== 'shellcommand') {
74313
+ return;
74314
+ }
74315
+ var options = media.options;
74316
+ if (options.commandtype === 'storedCommand' && options.commandcode) {
74317
+ console.debug('Media::Emitter > Shell Command - Calling commandCodeReceived event');
74318
+ this.xlr.emitter.emit('commandCodeReceived', options.commandcode);
74319
+ return;
74320
+ }
74321
+ var commandString = '';
74322
+ if (options.useglobalcommand === '1') {
74323
+ commandString = options.globalcommand || '';
74324
+ } else {
74325
+ // Use platform-specific command when available
74326
+ if (this.xlr.config.platform === exports.ConsumerPlatform.CHROMEOS) {
74327
+ commandString = options.chromeoscommand || '';
74328
+ } else if (this.xlr.config.platform === exports.ConsumerPlatform.ANDROID) {
74329
+ commandString = options.androidcommand || '';
74330
+ } else if (this.xlr.config.platform === exports.ConsumerPlatform.LINUX) {
74331
+ commandString = options.linuxcommand || '';
74332
+ } else if (this.xlr.config.platform === exports.ConsumerPlatform.TIZEN) {
74333
+ commandString = options.tizencommand || '';
74334
+ } else if (this.xlr.config.platform === exports.ConsumerPlatform.WEBOS) {
74335
+ commandString = options.weboscommand || '';
74336
+ } else if (this.xlr.config.platform === exports.ConsumerPlatform.WINDOWS) {
74337
+ commandString = options.windowscommand || '';
74338
+ }
74339
+ // Fall back to the global command if the platform-specific one
74340
+ // is missing, not configured, or not supported yet
74341
+ if (!commandString && options.globalcommand) {
74342
+ commandString = options.globalcommand;
74343
+ }
74344
+ }
74345
+ if (commandString) {
74346
+ console.debug('Media::Emitter > Shell Command - Calling commandStringReceived event');
74347
+ this.xlr.emitter.emit('commandStringReceived', commandString);
74348
+ return;
74349
+ }
74350
+ }
74351
+ }]);
74352
+ }();
74461
74353
 
74462
74354
  var Region = /*#__PURE__*/function () {
74463
74355
  // ===== Constructor =====
@@ -74615,10 +74507,6 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
74615
74507
  });
74616
74508
  // Prepare first media
74617
74509
  if (this.mediaObjects.length > 0) {
74618
- // Clean up region first
74619
- // if (this.html?.children.length > 0) {
74620
- // this.html.innerHTML = '';
74621
- // }
74622
74510
  this.prepareFirstMedia();
74623
74511
  }
74624
74512
  }
@@ -74651,6 +74539,11 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
74651
74539
  value: function prepareNextMedia() {
74652
74540
  var nextMediaIndex = (this.currentMediaIndex + 1) % this.totalMediaObjects;
74653
74541
  var nextMedia = this.mediaObjects[nextMediaIndex];
74542
+ console.debug('<><> XLR.debug >> [Media] - [Region::prepareNextMedia()] - Preparing next media', {
74543
+ currentMediaIndex: this.currentMediaIndex,
74544
+ nextMediaIndex: nextMediaIndex,
74545
+ nextMediaId: nextMedia.mediaId
74546
+ });
74654
74547
  this.prepareMedia(nextMedia);
74655
74548
  }
74656
74549
  }, {
@@ -74669,36 +74562,6 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
74669
74562
  regionId: this.id,
74670
74563
  oldMedia: (_this$oldMedia = this.oldMedia) === null || _this$oldMedia === void 0 ? void 0 : _this$oldMedia.containerName
74671
74564
  });
74672
- // const $region = document.getElementById(`${this.containerName}`);
74673
- // Preload first item
74674
- // if (this.currentMediaIndex > 0 && this.nxtMedia) {
74675
- // // Prepare next items
74676
- // this.prepareMedia(this.nxtMedia);
74677
- // } else {
74678
- // this.prepareMedia(this.currMedia);
74679
- // }
74680
- // Append available media to region DOM
74681
- // if (this.currMedia) {
74682
- //
74683
- // this.currEl = createMediaElement(this.currMedia);
74684
- // this.currMedia.html = this.currEl;
74685
- //
74686
- // console.debug('<> XLR.debug prepareMediaObjects::currMedia', {
74687
- // currentMedia: this.currMedia.containerName,
74688
- // regionId: this.id,
74689
- // });
74690
- // ($region) && $region.insertBefore(this.currEl as Node, $region.lastElementChild);
74691
- // }
74692
- // if (this.totalMediaObjects > 1 && this.nxtMedia) {
74693
- // this.nxtEl = createMediaElement(this.nxtMedia);
74694
- // this.nxtMedia.html = this.nxtEl;
74695
- //
74696
- // console.debug('<> XLR.debug prepareMediaObjects::nxtMedia', {
74697
- // nextMedia: this.nxtMedia.containerName,
74698
- // regionId: this.id,
74699
- // });
74700
- // ($region) && $region.insertBefore(this.nxtEl as Node, $region.lastElementChild);
74701
- // }
74702
74565
  }
74703
74566
  }
74704
74567
  }, {
@@ -74712,116 +74575,6 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
74712
74575
  this.layout.regions[this.index] = this;
74713
74576
  this.layout.regionExpired();
74714
74577
  }
74715
- }, {
74716
- key: "prepareVideo",
74717
- value: function () {
74718
- var _prepareVideo = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(media, container) {
74719
- var _this2 = this;
74720
- var video;
74721
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
74722
- while (1) switch (_context2.prev = _context2.next) {
74723
- case 0:
74724
- video = media.html;
74725
- if (media.url !== null) {
74726
- video.src = media.url;
74727
- }
74728
- container !== null && container.appendChild(media.html);
74729
- return _context2.abrupt("return", new Promise(function (resolve) {
74730
- var _media$videoHandler$p;
74731
- var vidType = videoFileType(getFileExt(media.uri));
74732
- // Initialize Video.js
74733
- media.player = videojs(video, _objectSpread2(_objectSpread2({}, defaultVjsOpts), {}, {
74734
- errorDisplay: _this2.xlr.config.platform !== exports.ConsumerPlatform.CHROMEOS,
74735
- loop: media.loop,
74736
- sources: [{
74737
- src: media.url,
74738
- type: vidType
74739
- }] // Adjust MIME type if dynamic
74740
- }));
74741
- media.player.el().style.setProperty('visibility', 'hidden');
74742
- media.player.el().style.setProperty('z-index', '0');
74743
- media.player.el().style.setProperty('opacity', '0');
74744
- // Register video handler
74745
- media.videoHandler = videoMediaHandler(media, _this2.xlr.config.platform);
74746
- (_media$videoHandler$p = media.videoHandler.player) === null || _media$videoHandler$p === void 0 || _media$videoHandler$p.one('canplaythrough', function () {
74747
- resolve();
74748
- });
74749
- }));
74750
- case 4:
74751
- case "end":
74752
- return _context2.stop();
74753
- }
74754
- }, _callee2);
74755
- }));
74756
- function prepareVideo(_x3, _x4) {
74757
- return _prepareVideo.apply(this, arguments);
74758
- }
74759
- return prepareVideo;
74760
- }()
74761
- }, {
74762
- key: "prepareImage",
74763
- value: function () {
74764
- var _prepareImage = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(media, container) {
74765
- var blobUrl, img;
74766
- return _regeneratorRuntime().wrap(function _callee3$(_context3) {
74767
- while (1) switch (_context3.prev = _context3.next) {
74768
- case 0:
74769
- _context3.next = 2;
74770
- return BlobLoader.load(media.url);
74771
- case 2:
74772
- blobUrl = _context3.sent;
74773
- img = new Image(); // Wait for decoding to finish so there is no visual glitch
74774
- return _context3.abrupt("return", new Promise(function (resolve, reject) {
74775
- img.onload = function () {
74776
- return resolve();
74777
- };
74778
- img.onerror = function (e) {
74779
- return reject(e);
74780
- };
74781
- img.src = blobUrl;
74782
- if (media.html) {
74783
- media.html.style.setProperty('background-image', "url(".concat(blobUrl, ")"));
74784
- }
74785
- container !== null && container.appendChild(media.html);
74786
- }));
74787
- case 5:
74788
- case "end":
74789
- return _context3.stop();
74790
- }
74791
- }, _callee3);
74792
- }));
74793
- function prepareImage(_x5, _x6) {
74794
- return _prepareImage.apply(this, arguments);
74795
- }
74796
- return prepareImage;
74797
- }()
74798
- }, {
74799
- key: "prepareIframe",
74800
- value: function prepareIframe(media, container) {
74801
- console.debug('??? XLR.debug >> Region prepareIframe - start');
74802
- return new Promise(function (resolve, reject) {
74803
- var iframe = media.iframe;
74804
- console.debug('??? XLR.debug >> Region prepareIframe - promise', {
74805
- iframe: iframe,
74806
- mediaType: media.mediaType,
74807
- container: container
74808
- });
74809
- if (iframe !== null) {
74810
- iframe.onload = function () {
74811
- return resolve();
74812
- };
74813
- iframe.onerror = function (e) {
74814
- return reject(e);
74815
- };
74816
- // Append iframe to html
74817
- if (media.html) {
74818
- media.html.innerHTML = '';
74819
- media.html.appendChild(iframe);
74820
- }
74821
- container !== null && container.appendChild(media.html);
74822
- }
74823
- });
74824
- }
74825
74578
  }, {
74826
74579
  key: "run",
74827
74580
  value: function run() {
@@ -74835,7 +74588,7 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
74835
74588
  }, {
74836
74589
  key: "transitionNodes",
74837
74590
  value: function transitionNodes(oldMedia, newMedia) {
74838
- var _this3 = this;
74591
+ var _this2 = this;
74839
74592
  var transOutDuration = 1;
74840
74593
  var transOutDirection = 'E';
74841
74594
  if (newMedia) {
@@ -74851,7 +74604,7 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
74851
74604
  var transOut = transitionElement('defaultOut', {
74852
74605
  duration: defaultTransOutOptions.duration
74853
74606
  });
74854
- var transOutName;
74607
+ var transOutName = '';
74855
74608
  if (oldMedia && Boolean(oldMedia.options['transout'])) {
74856
74609
  transOutName = oldMedia.options['transout'];
74857
74610
  if (transOutName === 'fly') {
@@ -74865,11 +74618,18 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
74865
74618
  }
74866
74619
  transOut = transitionElement(transOutName, defaultTransOutOptions);
74867
74620
  }
74621
+ console.debug('??? XLR.debug >> Region > transitionNodes - transOut options', {
74622
+ transOutName: transOutName,
74623
+ transOut: transOut,
74624
+ transOutDuration: transOutDuration,
74625
+ transOutDirection: transOutDirection,
74626
+ totalMediaObjects: this.totalMediaObjects
74627
+ });
74868
74628
  var hideOldMedia = function hideOldMedia() {
74869
74629
  // Hide oldMedia
74870
74630
  if (oldMedia) {
74871
- var _this3$layout$html;
74872
- var $region = (_this3$layout$html = _this3.layout.html) === null || _this3$layout$html === void 0 ? void 0 : _this3$layout$html.querySelector('#' + _this3.containerName);
74631
+ var $layout = document.querySelector("#".concat(_this2.layout.containerName, "[data-sequence=\"").concat(_this2.layout.index, "\"]"));
74632
+ var $region = $layout.querySelector('#' + _this2.containerName);
74873
74633
  var $oldMedia = $region ? $region.querySelector('.' + getMediaId(oldMedia)) : null;
74874
74634
  if ($oldMedia) {
74875
74635
  var removeOldMedia = function removeOldMedia() {
@@ -74908,7 +74668,7 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
74908
74668
  if (Boolean(oldMedia.options['transout'])) {
74909
74669
  oldMediaAnimate = $oldMedia.animate(transOut.keyframes, transOut.timing);
74910
74670
  }
74911
- if (Boolean(oldMedia.options['transout']) && _this3.totalMediaObjects > 1) {
74671
+ if (Boolean(oldMedia.options['transout']) && _this2.totalMediaObjects > 1) {
74912
74672
  if (transOutName === 'flyOut') {
74913
74673
  // Reset last item to original position and state
74914
74674
  oldMediaAnimate ? oldMediaAnimate.finished.then(function () {
@@ -74934,9 +74694,6 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
74934
74694
  } else {
74935
74695
  console.debug('??? XLR.debug >> Region transitionNode - hideOldMedia' + 'no transout and only 1 media');
74936
74696
  removeOldMedia();
74937
- // Resolve this right away
74938
- // As a result, the transition between two media object
74939
- // seems like a cross-over
74940
74697
  }
74941
74698
  }
74942
74699
  }
@@ -75202,7 +74959,7 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
75202
74959
  };
75203
74960
  }
75204
74961
  // Only render webhook controller in CMS
75205
- if (this.parent.xlr.config.platform !== 'CMS') {
74962
+ if (this.parent.xlr.config.platform !== exports.ConsumerPlatform.CMS) {
75206
74963
  this.$actionController.style.display = 'none';
75207
74964
  return;
75208
74965
  }
@@ -75300,10 +75057,10 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
75300
75057
  key: "runAction",
75301
75058
  value: function runAction(actionData, options) {
75302
75059
  if (actionData.actiontype == 'navLayout') {
75303
- if (this.parent.xlr.config.platform === 'CMS') {
75060
+ if (this.parent.xlr.config.platform === exports.ConsumerPlatform.CMS) {
75304
75061
  // Open layout preview in a new tab
75305
75062
  this.openLayoutInNewTab(actionData.layoutcode, options);
75306
- } else if (this.parent.xlr.config.platform === 'chromeOS') {
75063
+ } else if (this.parent.xlr.config.platform === exports.ConsumerPlatform.CHROMEOS) {
75307
75064
  // Set target layout as active layout
75308
75065
  this.openLayoutInPlayer(actionData.layoutcode, options);
75309
75066
  }
@@ -75465,6 +75222,12 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
75465
75222
  fetchOptions.headers = {
75466
75223
  'Content-Type': 'text/xml'
75467
75224
  };
75225
+ } else if (layoutOptions.platform === exports.ConsumerPlatform.ELECTRON) {
75226
+ xlfUrl = layoutOptions.appHost + layoutOptions.xlfUrl;
75227
+ fetchOptions.mode = 'no-cors';
75228
+ fetchOptions.headers = {
75229
+ 'Content-Type': 'text/xml'
75230
+ };
75468
75231
  } else if (layoutOptions.appHost !== null) {
75469
75232
  xlfUrl = layoutOptions.appHost + layoutOptions.xlfUrl;
75470
75233
  }
@@ -75794,9 +75557,10 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
75794
75557
  if (!(this.bgImage === "" || typeof this.bgImage === 'undefined')) {
75795
75558
  /* Extract the image ID from the filename */
75796
75559
  this.bgId = this.bgImage.substring(0, this.bgImage.indexOf('.'));
75797
- var bgImageUrl = composeBgUrlByPlatform(this.xlr.config.platform, _objectSpread2(_objectSpread2({}, this.options), {}, {
75798
- layout: this
75799
- }));
75560
+ var bgImageUrl = composeBgUrlByPlatform(this.xlr.config.platform, this);
75561
+ console.debug('>>> XLR.debug Layout::parseXlf - Composed background image URL > ', {
75562
+ bgImageUrl: bgImageUrl
75563
+ });
75800
75564
  if ($layout) {
75801
75565
  if (!this.isOverlay) {
75802
75566
  $layout.style.setProperty('background-image', "url(\"".concat(bgImageUrl, "\")"));
@@ -76061,7 +75825,7 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
76061
75825
  case 0:
76062
75826
  $previewSplash.classList.add('preview-splash');
76063
75827
  // Don't show Xibo logo on CMS Preview
76064
- if (config && config.platform !== 'CMS') {
75828
+ if (config && config.platform !== exports.ConsumerPlatform.CMS) {
76065
75829
  splashScreenImg = img$1;
76066
75830
  if ((_config$icons = config.icons) !== null && _config$icons !== void 0 && _config$icons.splashScreen && config.icons.splashScreen.length > 0) {
76067
75831
  splashScreenImg = config.icons.splashScreen;
@@ -76079,7 +75843,7 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
76079
75843
  $previewLoader.classList.add('preview-loader');
76080
75844
  $previewLoaderCaption.classList.add('preview-loaderCaption');
76081
75845
  // Show loader bar and text on CMS Preview
76082
- if (config && config.platform === 'CMS') {
75846
+ if (config && config.platform === exports.ConsumerPlatform.CMS) {
76083
75847
  $previewLoader.style.setProperty('background-image', "url(".concat(img, ")"));
76084
75848
  $previewLoaderCaption.innerHTML = '<p>Loading Layout...</p>';
76085
75849
  }
@@ -76796,7 +76560,7 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
76796
76560
  };
76797
76561
  };
76798
76562
  xlrObject.getLayout = function (inputLayout) {
76799
- var isCMS = this.config.platform === 'CMS';
76563
+ var isCMS = this.config.platform === exports.ConsumerPlatform.CMS;
76800
76564
  if (!isCMS && Object.keys(this.uniqueLayouts).length === 0) {
76801
76565
  return;
76802
76566
  }
@@ -76941,9 +76705,9 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
76941
76705
  self = this; // Compose layout props first
76942
76706
  // Clone options to avoid mutating the shared xlfUrl template
76943
76707
  newOptions = _objectSpread2({}, props.options);
76944
- if (self.config.platform === 'CMS' && inputLayout && Boolean(inputLayout.layoutId)) {
76708
+ if (self.config.platform === exports.ConsumerPlatform.CMS && inputLayout && Boolean(inputLayout.layoutId)) {
76945
76709
  newOptions.xlfUrl = newOptions.xlfUrl.replace(':layoutId', String(inputLayout.layoutId));
76946
- } else if (self.config.platform === 'chromeOS' && inputLayout !== undefined) {
76710
+ } else if ((self.config.platform === exports.ConsumerPlatform.CHROMEOS || self.config.platform === exports.ConsumerPlatform.ELECTRON) && inputLayout !== undefined) {
76947
76711
  newOptions.xlfUrl = inputLayout.path;
76948
76712
  }
76949
76713
  if (!(inputLayout && inputLayout.layoutNode === undefined)) {
@@ -77171,13 +76935,16 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
77171
76935
  exports.flyInElem = flyInElem;
77172
76936
  exports.flyOutElem = flyOutElem;
77173
76937
  exports.flyTransitionKeyframes = flyTransitionKeyframes;
76938
+ exports.getAllAttributes = getAllAttributes;
77174
76939
  exports.getDataBlob = getDataBlob;
77175
76940
  exports.getFileExt = getFileExt;
77176
76941
  exports.getIndexByLayoutId = getIndexByLayoutId;
77177
76942
  exports.getLayout = getLayout;
76943
+ exports.getLayoutIndexByLayoutId = getLayoutIndexByLayoutId;
77178
76944
  exports.getMediaId = getMediaId;
77179
76945
  exports.getXlf = getXlf;
77180
76946
  exports.hasDefaultOnly = hasDefaultOnly;
76947
+ exports.hasSspLayout = hasSspLayout;
77181
76948
  exports.initRenderingDOM = initRenderingDOM;
77182
76949
  exports.initialLayout = initialLayout;
77183
76950
  exports.initialMedia = initialMedia;
@@ -77186,11 +76953,15 @@ ${segmentInfoString(segmentInfo)}`); // If there's an init segment associated wi
77186
76953
  exports.isEmpty = isEmpty;
77187
76954
  exports.isLayoutValid = isLayoutValid;
77188
76955
  exports.nextId = nextId;
76956
+ exports.playerReportFault = playerReportFault;
77189
76957
  exports.preloadMediaBlob = preloadMediaBlob;
76958
+ exports.prepareAudioMedia = prepareAudioMedia;
76959
+ exports.prepareHtmlMedia = prepareHtmlMedia;
76960
+ exports.prepareImageMedia = prepareImageMedia;
76961
+ exports.prepareVideoMedia = prepareVideoMedia;
77190
76962
  exports.setExpiry = setExpiry;
77191
76963
  exports.transitionElement = transitionElement;
77192
76964
  exports.videoFileType = videoFileType;
77193
- exports.videoMediaHandler = videoMediaHandler;
77194
76965
  exports.vjsDefaultOptions = vjsDefaultOptions;
77195
76966
 
77196
76967
  Object.defineProperty(exports, '__esModule', { value: true });