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