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