@gcorevideo/player 2.22.3 → 2.22.5

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.
Files changed (39) hide show
  1. package/assets/audio-selector/style.scss +4 -2
  2. package/assets/audio-selector/track-selector.ejs +2 -2
  3. package/assets/level-selector/button.ejs +1 -1
  4. package/assets/level-selector/list.ejs +10 -4
  5. package/assets/level-selector/style.scss +8 -3
  6. package/dist/core.js +1 -1
  7. package/dist/index.css +1435 -1429
  8. package/dist/index.js +402 -419
  9. package/dist/plugins/index.css +1192 -1186
  10. package/dist/plugins/index.js +428 -438
  11. package/lib/index.plugins.d.ts +3 -1
  12. package/lib/index.plugins.d.ts.map +1 -1
  13. package/lib/index.plugins.js +3 -1
  14. package/lib/plugins/audio-selector/AudioSelector.d.ts +3 -9
  15. package/lib/plugins/audio-selector/AudioSelector.d.ts.map +1 -1
  16. package/lib/plugins/audio-selector/AudioSelector.js +34 -57
  17. package/lib/plugins/level-selector/LevelSelector.d.ts +6 -5
  18. package/lib/plugins/level-selector/LevelSelector.d.ts.map +1 -1
  19. package/lib/plugins/level-selector/LevelSelector.js +11 -8
  20. package/lib/plugins/level-selector/QualityLevels.d.ts +112 -0
  21. package/lib/plugins/level-selector/QualityLevels.d.ts.map +1 -0
  22. package/lib/plugins/level-selector/QualityLevels.js +280 -0
  23. package/lib/plugins/vast-ads/VastAds.d.ts +1 -0
  24. package/lib/plugins/vast-ads/VastAds.d.ts.map +1 -1
  25. package/lib/plugins/vast-ads/VastAds.js +6 -3
  26. package/lib/testUtils.d.ts +2 -0
  27. package/lib/testUtils.d.ts.map +1 -1
  28. package/lib/testUtils.js +2 -0
  29. package/package.json +1 -1
  30. package/src/index.plugins.ts +3 -1
  31. package/src/plugins/audio-selector/AudioSelector.ts +36 -72
  32. package/src/plugins/audio-selector/__tests__/AudioSelector.test.ts +176 -0
  33. package/src/plugins/audio-selector/__tests__/__snapshots__/AudioSelector.test.ts.snap +67 -0
  34. package/src/plugins/level-selector/{LevelSelector.ts → QualityLevels.ts} +19 -13
  35. package/src/plugins/level-selector/__tests__/{LevelSelector.test.ts → QualityLevels.test.ts} +20 -6
  36. package/src/plugins/level-selector/__tests__/__snapshots__/{LevelSelector.test.ts.snap → QualityLevels.test.ts.snap} +58 -25
  37. package/src/plugins/vast-ads/VastAds.ts +8 -4
  38. package/src/testUtils.ts +2 -0
  39. package/tsconfig.tsbuildinfo +1 -1
@@ -8858,14 +8858,6 @@ Loader.registerPlayback(HTMLImg);
8858
8858
  Loader.registerPlayback(HTML5Audio);
8859
8859
  Loader.registerPlayback(HTML5Video);
8860
8860
 
8861
- /**
8862
- * @public
8863
- * @param msg
8864
- * @param data
8865
- */
8866
- function trace(msg, data = {}) {
8867
- }
8868
-
8869
8861
  const global$1 = (typeof global !== "undefined" ? global :
8870
8862
  typeof self !== "undefined" ? self :
8871
8863
  typeof window !== "undefined" ? window : {});
@@ -9775,11 +9767,12 @@ function ifError(err) {
9775
9767
  // export const CLAPPR_VERSION: string = process.env.CLAPPR_VERSION || '0.11.3';
9776
9768
  const CLAPPR_VERSION = '0.11.3';
9777
9769
 
9778
- const pluginHtml$7 = "<button data-audiotracks-button class='gcore-skin-button-color' id=\"audiotracks-button\">\n <span class='audio-text'><%= title %></span> <span class=\"audio-arrow\"></span>\n</button>\n<ul class='gcore-skin-bg-color' id=\"audiotracks-select\">\n <% for (const track of tracks) { %>\n <li>\n <a href=\"#\" class='gcore-skin-text-color' data-audiotracks-select=\"<%= track.id %>\">\n <%= track.label %>\n </a>\n </li>\n <% }; %>\n</ul>\n";
9770
+ const pluginHtml$7 = "<button data-audiotracks-button class='gcore-skin-button-color' id=\"audiotracks-button\">\n <span class='audio-text'><%= title %></span> <span class=\"audio-arrow\"><%= icon %></span>\n</button>\n<ul class='gcore-skin-bg-color menu hidden' id=\"audiotracks-select\">\n <% for (const track of tracks) { %>\n <li>\n <a href=\"#\" class='gcore-skin-text-color' data-audiotracks-select=\"<%= track.id %>\">\n <%= track.label %>\n </a>\n </li>\n <% }; %>\n</ul>\n";
9779
9771
 
9780
9772
  const audioArrow = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"9px\" height=\"6px\" viewBox=\"0 0 9 6\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <!-- Generator: Sketch 49 (51002) - http://www.bohemiancoding.com/sketch -->\n <title>quality-arrow</title>\n <desc>Created with Sketch.</desc>\n <defs></defs>\n <g id=\"quality-arrow\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <path\n d=\"M5.07079194,5.78553848 C4.91457318,5.94277844 4.70551573,6.00941824 4.50028717,5.99893557 C4.2950586,6.00941824 4.08676693,5.94277844 3.92978239,5.78553848 L0.221118462,1.2997069 C-0.0737061539,1.00469478 -0.0737061539,0.526236029 0.221118462,0.231972666 C0.515177299,-0.0630394586 1.23500883,0.00734414472 1.64852907,0.00734414472 L7.77475484,0.00734414472 C8.21201421,0.00734414472 8.48539703,-0.0630394586 8.77945587,0.231972666 C9.07351471,0.526236029 9.07351471,1.00469478 8.77945587,1.2997069 L5.07079194,5.78553848 Z\"\n fill=\"#FFFFFE\"></path>\n </g>\n</svg>\n";
9781
9773
 
9782
- const VERSION$6 = '0.0.1';
9774
+ const VERSION$6 = '2.22.4';
9775
+ // const T = 'plugins.audiotracks'
9783
9776
  /**
9784
9777
  * `PLUGIN` that makes possible to switch audio tracks via the media control UI.
9785
9778
  * @beta
@@ -9790,14 +9783,14 @@ const VERSION$6 = '0.0.1';
9790
9783
  *
9791
9784
  * - {@link MediaControl}
9792
9785
  */
9793
- class AudioSelector extends UICorePlugin {
9786
+ class AudioTracks extends UICorePlugin {
9794
9787
  currentTrack = null;
9795
9788
  tracks = [];
9796
9789
  /**
9797
9790
  * @internal
9798
9791
  */
9799
9792
  get name() {
9800
- return 'audio_selector';
9793
+ return 'audio_selector'; // TODO rename to audiotracks
9801
9794
  }
9802
9795
  /**
9803
9796
  * @internal
@@ -9826,52 +9819,43 @@ class AudioSelector extends UICorePlugin {
9826
9819
  get events() {
9827
9820
  return {
9828
9821
  'click [data-audiotracks-select]': 'onTrackSelect',
9829
- 'click [data-audiotracks-button]': 'onShowLevelSelectMenu',
9822
+ 'click #audiotracks-button': 'toggleContextMenu',
9830
9823
  };
9831
9824
  }
9832
9825
  /**
9833
9826
  * @internal
9834
9827
  */
9835
9828
  bindEvents() {
9836
- this.listenTo(this.core, Events.CORE_READY, this.onCoreReady);
9829
+ this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady);
9837
9830
  this.listenTo(this.core, Events.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChanged);
9838
9831
  }
9839
9832
  onCoreReady() {
9840
9833
  const mediaControl = this.core.getPlugin('media_control');
9841
9834
  assert(mediaControl, 'media_control plugin is required');
9842
- this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.render);
9843
- this.listenTo(mediaControl, Events.MEDIACONTROL_HIDE, this.hideSelectTrackMenu);
9835
+ this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, () => {
9836
+ mediaControl.putElement('audiotracks', this.$el);
9837
+ });
9838
+ this.listenTo(mediaControl, Events.MEDIACONTROL_HIDE, this.hideMenu);
9844
9839
  }
9845
- bindPlaybackEvents() {
9840
+ onActiveContainerChanged() {
9846
9841
  this.currentTrack = null;
9847
- this.listenTo(this.core.activePlayback, Events.PLAYBACK_STOP, this.onStop);
9848
- this.setupAudioTrackListeners();
9849
- }
9850
- setupAudioTrackListeners() {
9851
- this.listenTo(this.core.activePlayback, Events.PLAYBACK_AUDIO_AVAILABLE, (tracks) => {
9842
+ this.listenTo(this.core.activeContainer, Events.CONTAINER_AUDIO_AVAILABLE, (tracks) => {
9852
9843
  this.currentTrack =
9853
- tracks.find((track) => track.kind === 'main') ?? null;
9854
- this.fillTracks(tracks);
9844
+ tracks.find((track) => track.kind === 'main') ?? null; // TODO test
9845
+ this.tracks = tracks;
9846
+ this.render();
9855
9847
  });
9856
- this.listenTo(this.core.activePlayback, Events.PLAYBACK_AUDIO_CHANGED, (track) => {
9848
+ this.listenTo(this.core.activeContainer, Events.CONTAINER_AUDIO_CHANGED, (track) => {
9857
9849
  this.currentTrack = track;
9858
9850
  this.highlightCurrentTrack();
9859
9851
  this.buttonElement().removeClass('changing');
9860
9852
  this.updateText();
9861
9853
  });
9862
9854
  }
9863
- onStop() {
9864
- }
9865
- onActiveContainerChanged() {
9866
- this.bindPlaybackEvents();
9867
- }
9868
9855
  shouldRender() {
9869
- if (!this.core.activePlayback) {
9870
- return false;
9871
- }
9872
- this.tracks = this.core.activePlayback.audioTracks;
9856
+ // Render is called from the parent class constructor so tracks aren't available
9873
9857
  // Only care if we have at least 2 to choose from
9874
- return this.tracks && this.tracks.length > 1;
9858
+ return this.tracks?.length > 1;
9875
9859
  }
9876
9860
  /**
9877
9861
  * @internal
@@ -9880,43 +9864,35 @@ class AudioSelector extends UICorePlugin {
9880
9864
  if (!this.shouldRender()) {
9881
9865
  return this;
9882
9866
  }
9883
- const mediaControl = this.core.getPlugin('media_control');
9884
- this.$el.html(AudioSelector.template({ tracks: this.tracks, title: this.getTitle() }));
9885
- this.$('.audio-arrow').append(audioArrow);
9886
- mediaControl.putElement('audiotracks', this.el);
9867
+ this.core.getPlugin('media_control');
9868
+ this.$el.html(AudioTracks.template({
9869
+ tracks: this.tracks,
9870
+ title: this.getTitle(),
9871
+ icon: audioArrow,
9872
+ }));
9887
9873
  this.updateText();
9888
9874
  this.highlightCurrentTrack();
9889
9875
  return this;
9890
9876
  }
9891
- fillTracks(tracks) {
9892
- this.tracks = tracks;
9893
- this.render();
9894
- }
9895
- findTrackBy(id) {
9896
- return this.tracks.find((track) => track.id === id);
9897
- }
9898
9877
  onTrackSelect(event) {
9899
9878
  const id = event.target?.dataset?.audiotracksSelect;
9900
9879
  if (id) {
9901
9880
  this.selectAudioTrack(id);
9902
9881
  }
9903
- this.toggleContextMenu();
9882
+ this.hideMenu();
9904
9883
  event.stopPropagation();
9905
9884
  return false;
9906
9885
  }
9907
9886
  selectAudioTrack(id) {
9908
9887
  this.startTrackSwitch();
9909
- this.core.activePlayback.switchAudioTrack(id);
9888
+ this.core.activeContainer.switchAudioTrack(id);
9910
9889
  this.updateText();
9911
9890
  }
9912
- onShowLevelSelectMenu() {
9913
- this.toggleContextMenu();
9914
- }
9915
- hideSelectTrackMenu() {
9916
- this.$('ul').hide();
9891
+ hideMenu() {
9892
+ this.$el.find('#audiotracks-select').addClass('hidden');
9917
9893
  }
9918
9894
  toggleContextMenu() {
9919
- this.$('ul').toggle();
9895
+ this.$el.find('#audiotracks-select').toggleClass('hidden');
9920
9896
  }
9921
9897
  buttonElement() {
9922
9898
  return this.$('button');
@@ -9925,11 +9901,14 @@ class AudioSelector extends UICorePlugin {
9925
9901
  return this.$('button .audio-text');
9926
9902
  }
9927
9903
  trackElement(id) {
9928
- return this.$('ul a' +
9929
- (id !== undefined ? '[data-audiotracks-select="' + id + '"]' : '')).parent();
9904
+ return this.$('#audiotracks-select a' +
9905
+ (id !== undefined ? `[data-audiotracks-select="${id}"]` : '')).parent();
9930
9906
  }
9931
9907
  getTitle() {
9932
- return this.currentTrack?.label || '';
9908
+ if (!this.currentTrack) {
9909
+ return '';
9910
+ }
9911
+ return this.currentTrack.label || this.currentTrack.language;
9933
9912
  }
9934
9913
  startTrackSwitch() {
9935
9914
  this.buttonElement().addClass('changing');
@@ -9952,6 +9931,14 @@ class AudioSelector extends UICorePlugin {
9952
9931
  }
9953
9932
  }
9954
9933
 
9934
+ /**
9935
+ * @public
9936
+ * @param msg
9937
+ * @param data
9938
+ */
9939
+ function trace(msg, data = {}) {
9940
+ }
9941
+
9955
9942
  const volumeOffIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M5.50025 8.00025C4.67125 8.00025 4.00025 8.67225 4.00025 9.50025V14.5003C4.00025 15.3283 4.67125 16.0003 5.50025 16.0003H7.24824C7.65024 16.0003 8.03627 16.1613 8.31727 16.4483L12.5443 20.7413C12.7083 20.9073 12.9262 20.9963 13.1492 20.9963C13.2572 20.9963 13.3672 20.9763 13.4722 20.9333C13.7932 20.8013 14.0003 20.4923 14.0003 20.1462V16.3283C14.0003 16.1963 13.9473 16.0683 13.8543 15.9753L6.02528 8.14625C5.93228 8.05325 5.80425 8.00025 5.67225 8.00025H5.50025ZM14.0003 3.85426C14.0003 3.50826 13.7932 3.19927 13.4722 3.06727C13.1502 2.93627 12.7873 3.01226 12.5443 3.25926L9.33827 6.51527C9.14627 6.71127 9.14626 7.02625 9.34126 7.22025L13.5733 11.4522C13.7313 11.6102 14.0003 11.4982 14.0003 11.2752V3.85426ZM20.8543 20.8543C20.7563 20.9513 20.6283 21.0003 20.5003 21.0003C20.3723 21.0003 20.2442 20.9513 20.1462 20.8543L3.14625 3.85426C2.95125 3.65826 2.95125 3.34225 3.14625 3.14625C3.34225 2.95125 3.65826 2.95125 3.85426 3.14625L20.8543 20.1462C21.0493 20.3422 21.0493 20.6583 20.8543 20.8543Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
9956
9943
 
9957
9944
  const pluginHtml$6 = "<div class=\"big-mute-icon-wrapper\" data-big-mute>\n <div class=\"big-mute-icon gcore-skin-border-color\" data-big-mute-icon></div>\n</div>\n";
@@ -13358,7 +13345,7 @@ class ClipsPlugin extends UICorePlugin {
13358
13345
 
13359
13346
  const templateHtml$1 = "<ul class=\"context-menu-list\">\n <% if(options) { %>\n <% for (var i = 0; i < options.length; i++) { %>\n <li class=\"context-menu-list-item <%= options[i].class %>\"\n data-<%= options[i].name %>><%= options[i].label %></li>\n <% } %>\n <% } %>\n</ul>\n";
13360
13347
 
13361
- var version$1 = "2.22.3";
13348
+ var version$1 = "2.22.5";
13362
13349
 
13363
13350
  var packages = {
13364
13351
  "node_modules/@clappr/core": {
@@ -13940,387 +13927,115 @@ class GoogleAnalytics extends ContainerPlugin {
13940
13927
  }
13941
13928
  }
13942
13929
 
13943
- const buttonHtml$2 = "<button class='gplayer-lite-btn gcore-skin-text-color gear-option'>\n <span class=\"gear-option_hd-icon<%= isHd ? '' : ' hidden' %>\"><%= hdIcon %></span>\n <span><%= i18n.t('quality') %></span>\n <span class=\"gear-option_arrow-right-icon\"><%= arrowRightIcon %></span>\n <span class='gear-option_value'><%= currentText %></span>\n</button>\n";
13944
-
13945
- const listHtml$1 = "<button class=\"gplayer-lite-btn go-back gcore-skin-text-color\" id=\"level-selector-back-button\">\n <span class=\"arrow-left-icon\"><%= arrowLeftIcon %></span>\n <%= i18n.t('quality') %>\n</button>\n<ul class=\"gear-sub-menu\" id=\"level-selector-menu\">\n <% if (!removeAuto) { %>\n <li>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"-1\" id=\"level_selector_auto\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= i18n.t('auto') %>\n </a>\n </li>\n <% } %>\n <% for (const item of levels.slice().reverse()) { %>\n <li class=\"<%= maxLevel >= 0 && item.level > maxLevel ? 'disabled ' : ''%><%=item.level === current ? 'current ' : ''%>\">\n <a href=\"#\"\n class=\"gear-sub-menu_btn gcore-skin-text-color<%= item.level === current ? ' gcore-skin-active' : '' %>\"\n data-id=\"<%= item.level %>\"\n id=\"level_selector_<%= item.width > item.height ? item.height : item.width %>\"\n >\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= labels[item.level] %>\n </a>\n </li>\n <% } %>\n</ul>\n";
13946
-
13947
- const hdIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14.9562 8.22232H13.9961V15.1873H14.9562C15.8914 15.1873 16.766 14.8253 17.4195 14.1676C18.0786 13.5037 18.4415 12.6281 18.4415 11.7026C18.4415 9.7837 16.8781 8.22253 14.9561 8.22253L14.9562 8.22232Z\"\n fill=\"#C9C9C9\"/>\n <path\n d=\"M22.0801 4H1.91994C0.859222 4 0 4.86406 0 5.91994V17.4878C0 18.5437 0.859222 19.4078 1.91994 19.4078H22.0801C23.1408 19.4078 24 18.5437 24 17.4878V5.91994C24 4.86406 23.1408 4 22.0801 4ZM10.3975 15.3473C10.3975 15.6124 10.1827 15.8272 9.91754 15.8272C9.65216 15.8272 9.43761 15.6122 9.43761 15.3473V12.0239H5.55956V15.3473C5.55956 15.6124 5.34481 15.8272 5.07963 15.8272C4.81425 15.8272 4.5997 15.6122 4.5997 15.3473L4.59949 7.74042C4.59949 7.47524 4.81425 7.26049 5.07943 7.26049C5.34481 7.26049 5.55936 7.47544 5.55936 7.74042V11.0636H9.43741V7.74042C9.43741 7.47524 9.65216 7.26049 9.91734 7.26049C10.1827 7.26049 10.3973 7.47544 10.3973 7.74042L10.3975 15.3473ZM18.1005 14.8438C17.2652 15.6844 16.1486 16.1472 14.9561 16.1472H13.5161C13.2507 16.1472 13.0361 15.9323 13.0361 15.6673V7.74263C13.0361 7.47745 13.2509 7.26269 13.5161 7.26269H14.9561C17.4072 7.26269 19.4013 9.25438 19.4013 11.7027C19.4013 12.8835 18.9392 13.9991 18.1005 14.844V14.8438Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
13948
-
13949
- const arrowRightIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.70725 20.7073C8.51225 20.9023 8.25625 21.0002 8.00025 21.0002C7.74425 21.0002 7.48825 20.9023 7.29325 20.7073C6.90225 20.3162 6.90225 19.6842 7.29325 19.2932L14.5863 12.0002L7.29325 4.70725C6.90225 4.31625 6.90225 3.68425 7.29325 3.29325C7.68425 2.90225 8.31625 2.90225 8.70725 3.29325L16.7073 11.2933C17.0983 11.6842 17.0983 12.3162 16.7073 12.7072L8.70725 20.7073Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
13950
-
13951
- const arrowLeftIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M16.7073 19.2932C17.0983 19.6842 17.0983 20.3162 16.7073 20.7073C16.5123 20.9023 16.2563 21.0002 16.0003 21.0002C15.7443 21.0002 15.4882 20.9023 15.2933 20.7073L7.29325 12.7072C6.90225 12.3162 6.90225 11.6842 7.29325 11.2933L15.2933 3.29325C15.6842 2.90225 16.3163 2.90225 16.7073 3.29325C17.0983 3.68425 17.0983 4.31625 16.7073 4.70725L9.41425 12.0002L16.7073 19.2932Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
13930
+ function calculateSize(original) {
13931
+ const transformed = {
13932
+ media: {
13933
+ width: 0,
13934
+ height: 0
13935
+ },
13936
+ letterboxing: {
13937
+ horizontal: 0,
13938
+ vertical: 0
13939
+ }
13940
+ };
13941
+ // Freeze viewport height and scale video to fit vertically
13942
+ transformed.media.width = (original.media.width * original.dom.height / original.media.height);
13943
+ transformed.media.height = (original.media.height * transformed.media.width / original.media.width);
13944
+ // If it didnt't fit, freeze viewport width and scale video to fit horizontally
13945
+ if (transformed.media.width > original.dom.width) {
13946
+ transformed.media.height = (original.media.height * original.dom.width / original.media.width);
13947
+ transformed.media.width = (original.media.width * transformed.media.height / original.media.height);
13948
+ }
13949
+ // Calculate paddings for vertical or horizontal letterboxing
13950
+ if (transformed.media.width < original.dom.width) {
13951
+ transformed.letterboxing.horizontal = Math.floor((original.dom.width - transformed.media.width) / 2);
13952
+ }
13953
+ else {
13954
+ if (transformed.media.height < original.dom.height) {
13955
+ transformed.letterboxing.vertical = Math.floor((original.dom.height - transformed.media.height) / 2);
13956
+ }
13957
+ }
13958
+ transformed.media.width = Math.floor(transformed.media.width);
13959
+ transformed.media.height = Math.floor(transformed.media.height);
13960
+ return transformed;
13961
+ }
13952
13962
 
13953
- const checkIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M20.5793 4.19296C20.1216 3.86696 19.4777 3.96396 19.1424 4.40896L9.37295 17.3809L4.81634 12.107C4.45222 11.683 3.80218 11.6289 3.36709 11.9839C2.932 12.3389 2.87543 12.97 3.2416 13.393L8.64165 19.643C8.83708 19.869 9.12506 20 9.42849 20C9.4398 20 9.45114 20 9.46246 19.999C9.77926 19.989 10.0724 19.838 10.2586 19.59L20.8015 5.58996C21.1368 5.14496 21.0371 4.51896 20.5793 4.19296Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
13963
+ const logoHTML = "<div class=\"clappr-logo control-need-disable\">\n <img class=\"clappr-logo-img\"/>\n</div>\n";
13954
13964
 
13955
- const T$a = 'plugins.level_selector';
13956
- const VERSION$4 = '2.19.4';
13957
13965
  /**
13958
- * `PLUGIN` that provides a UI to select the desired quality level of the playback.
13966
+ * `PLUGIN` that adds custom logo to the player.
13959
13967
  * @beta
13960
- *
13961
- * @remarks
13962
- * Depends on:
13963
- *
13964
- * - {@link MediaControl}
13965
- *
13966
- * - {@link BottomGear}
13967
- *
13968
- * The plugin is rendered as an item in the gear menu, which, when clicked, shows a list of quality levels to choose from.
13969
- *
13970
- * Configuration options - {@link LevelSelectorPluginSettings}
13971
- *
13972
- * @example
13973
- * ```ts
13974
- * new Player({
13975
- * levelSelector: {
13976
- * restrictResolution: 360,
13977
- * labels: { 360: 'SD', 720: 'HD' },
13978
- * },
13979
- * })
13980
- * ```
13981
13968
  */
13982
- class LevelSelector extends UICorePlugin {
13983
- levels = [];
13984
- levelLabels = [];
13985
- removeAuto = false;
13986
- isHd = false;
13987
- currentText = '';
13988
- selectedLevelId = -1;
13989
- static buttonTemplate = tmpl(buttonHtml$2);
13990
- static listTemplate = tmpl(listHtml$1);
13991
- /**
13992
- * @internal
13993
- */
13969
+ class Logo extends UIContainerPlugin {
13970
+ hasStartedPlaying = false;
13971
+ $logoContainer = null;
13994
13972
  get name() {
13995
- return 'level_selector';
13973
+ return 'logo';
13996
13974
  }
13997
- /**
13998
- * @internal
13999
- */
14000
13975
  get supportedVersion() {
14001
13976
  return { min: CLAPPR_VERSION };
14002
13977
  }
14003
- /**
14004
- * @internal
14005
- */
14006
- static get version() {
14007
- return VERSION$4;
13978
+ get template() {
13979
+ return tmpl(logoHTML);
14008
13980
  }
14009
- /**
14010
- * @internal
14011
- */
14012
13981
  get attributes() {
14013
13982
  return {
14014
- class: 'level-selector',
14015
- 'data-level-selector': '',
13983
+ 'class': 'player-logo',
13984
+ 'data-logo': ''
14016
13985
  };
14017
13986
  }
14018
- get events() {
14019
- return {
14020
- 'click .gear-sub-menu_btn': 'onSelect',
14021
- 'click .go-back': 'goBack',
14022
- };
13987
+ get shouldRender() {
13988
+ return !!this.options.logo && !!this.options.logo.path;
14023
13989
  }
14024
- /**
14025
- * @internal
14026
- */
14027
13990
  bindEvents() {
14028
- this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady);
14029
- this.listenTo(this.core, Events.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChange);
13991
+ window.addEventListener('resize', this.setPosition);
13992
+ this.listenTo(this.container, Events.CONTAINER_RESIZE, this.setPosition);
13993
+ this.listenTo(this.container, Events.CONTAINER_STOP, this.onStop);
13994
+ this.listenTo(this.container, Events.CONTAINER_PLAY, this.onPlay);
13995
+ this.listenTo(this.container, Events.CONTAINER_LOADEDMETADATA, this.setPosition);
14030
13996
  }
14031
- onCoreReady() {
14032
- const gear = this.core.getPlugin('bottom_gear');
14033
- assert(gear, 'bottom_gear plugin is required');
14034
- this.currentText = this.core.i18n.t('auto');
14035
- this.listenTo(gear, GearEvents.RENDERED, this.onGearRendered);
13997
+ stopListening() {
13998
+ window.removeEventListener('resize', this.setPosition);
13999
+ // @ts-ignore
14000
+ return super.stopListening();
14036
14001
  }
14037
- onGearRendered() {
14038
- this.render();
14002
+ onPlay() {
14003
+ this.hasStartedPlaying = true;
14004
+ this.setPosition();
14039
14005
  }
14040
- onActiveContainerChange() {
14041
- this.removeAuto = false;
14042
- this.isHd = false;
14043
- const activePlayback = this.core.activePlayback;
14044
- this.listenTo(activePlayback, Events.PLAYBACK_LEVELS_AVAILABLE, this.onLevelsAvailable);
14045
- this.listenTo(activePlayback, Events.PLAYBACK_LEVEL_SWITCH_START, this.onLevelSwitchStart);
14046
- this.listenTo(activePlayback, Events.PLAYBACK_LEVEL_SWITCH_END, this.onLevelSwitchEnd);
14047
- this.listenTo(activePlayback, Events.PLAYBACK_BITRATE, this.onBitrate);
14048
- this.listenTo(activePlayback, Events.PLAYBACK_STOP, this.onStop);
14049
- this.listenTo(activePlayback, Events.PLAYBACK_HIGHDEFINITIONUPDATE, (isHd) => {
14050
- this.isHd = isHd;
14051
- this.updateHd();
14052
- });
14053
- if (activePlayback.levels?.length > 0) {
14054
- this.onLevelsAvailable(activePlayback.levels);
14055
- }
14006
+ onStop() {
14007
+ this.hasStartedPlaying = false;
14008
+ this.update();
14056
14009
  }
14057
- updateHd() {
14058
- if (this.isHd) {
14059
- this.$el.find('.gear-option_hd-icon').removeClass('hidden');
14010
+ update() {
14011
+ if (!this.shouldRender) {
14012
+ return;
14013
+ }
14014
+ if (!this.hasStartedPlaying) {
14015
+ this.$el.hide();
14060
14016
  }
14061
14017
  else {
14062
- this.$el.find('.gear-option_hd-icon').addClass('hidden');
14018
+ this.$el.show();
14063
14019
  }
14064
14020
  }
14065
- onStop() {
14066
- this.listenToOnce(this.core.activePlayback, Events.PLAYBACK_PLAY, () => {
14067
- if (this.core.activePlayback.getPlaybackType() === 'live') {
14068
- if (this.selectedLevelId !== -1) {
14069
- this.core.activePlayback.currentLevel = this.selectedLevelId;
14070
- }
14071
- }
14072
- });
14073
- }
14074
- shouldRender() {
14075
- const activePlayback = this.core.activePlayback;
14076
- if (!activePlayback) {
14077
- return false;
14078
- }
14079
- const supportsCurrentLevel = 'currentLevel' in activePlayback;
14080
- if (!supportsCurrentLevel) {
14081
- return false;
14021
+ constructor(container) {
14022
+ super(container);
14023
+ this.setPosition = this.setPosition.bind(this);
14024
+ this.hasStartedPlaying = false;
14025
+ if (!this.options.logo) {
14026
+ this.disable();
14027
+ return;
14082
14028
  }
14083
- // Only care if we have at least 2 to choose from
14084
- return !!(this.levels && this.levels.length > 1);
14029
+ this.render();
14085
14030
  }
14086
- /**
14087
- * @internal
14088
- */
14089
14031
  render() {
14090
- if (!this.shouldRender()) {
14032
+ if (!this.shouldRender) {
14091
14033
  return this;
14092
14034
  }
14093
- this.renderDropdown();
14094
- this.updateButton();
14095
- return this;
14096
- }
14097
- renderDropdown() {
14098
- this.$el.html(LevelSelector.listTemplate({
14099
- arrowLeftIcon,
14100
- checkIcon,
14101
- current: this.selectedLevelId,
14102
- labels: this.levelLabels,
14103
- levels: this.levels,
14104
- maxLevel: this.maxLevel,
14105
- removeAuto: this.removeAuto,
14106
- i18n: this.core.i18n,
14107
- }));
14108
- }
14109
- updateButton() {
14110
- this.core.getPlugin('bottom_gear')
14111
- ?.addItem('quality', this.$el)
14112
- .html(LevelSelector.buttonTemplate({
14113
- arrowRightIcon,
14114
- currentText: this.currentText,
14115
- isHd: this.isHd,
14116
- hdIcon,
14117
- i18n: this.core.i18n,
14118
- }));
14119
- }
14120
- get maxLevel() {
14121
- const maxRes = this.core.options.levelSelector?.restrictResolution;
14122
- return maxRes
14123
- ? this.levels.find((level) => (level.height > level.width ? level.width : level.height) ===
14124
- maxRes)?.level ?? -1
14125
- : -1;
14126
- }
14127
- onLevelsAvailable(levels) {
14128
- const maxResolution = this.core.options.levelSelector?.restrictResolution;
14129
- this.levels = levels;
14130
- this.makeLevelsLabels();
14131
- if (maxResolution) {
14132
- this.removeAuto = true;
14133
- const initialLevel = levels
14134
- .filter((level) => (level.width > level.height ? level.height : level.width) <=
14135
- maxResolution)
14136
- .pop();
14137
- this.setLevel(initialLevel?.level ?? 0);
14138
- }
14139
- this.render();
14140
- }
14141
- makeLevelsLabels() {
14142
- const labels = this.core.options.levelSelector?.labels ?? {};
14143
- this.levelLabels = [];
14144
- for (const level of this.levels) {
14145
- const ll = level.width > level.height ? level.height : level.width;
14146
- const label = labels[ll] || `${ll}p`;
14147
- this.levelLabels.push(label);
14148
- }
14149
- }
14150
- onSelect(event) {
14151
- const selectedLevel = parseInt(event.currentTarget?.dataset?.id ?? '-1', 10);
14152
- this.setLevel(selectedLevel);
14153
- event.stopPropagation();
14154
- event.preventDefault();
14155
- return false;
14156
- }
14157
- goBack() {
14158
- this.core.getPlugin('bottom_gear').refresh();
14159
- }
14160
- setLevel(index) {
14161
- this.selectedLevelId = index;
14162
- this.core.activePlayback.currentLevel = this.selectedLevelId;
14163
- this.highlightCurrentLevel();
14164
- }
14165
- allLevelElements() {
14166
- return this.$('#level-selector-menu li');
14167
- }
14168
- levelElement(id = -1) {
14169
- return this.$(`#level-selector-menu a[data-id="${id}"]`).parent();
14170
- }
14171
- onLevelSwitchStart() {
14172
- this.levelElement(this.selectedLevelId).addClass('changing');
14173
- }
14174
- onLevelSwitchEnd() {
14175
- this.levelElement(this.selectedLevelId).removeClass('changing');
14176
- }
14177
- updateText(level) {
14178
- this.currentText = this.getLevelLabel(level);
14179
- this.updateButton();
14180
- }
14181
- getLevelLabel(id) {
14182
- if (id < 0) {
14183
- return this.core.i18n.t('auto');
14184
- }
14185
- const index = this.levels.findIndex((l) => l.level === id);
14186
- if (index < 0) {
14187
- return this.core.i18n.t('auto');
14188
- }
14189
- return this.levelLabels[index] ?? formatLevelLabel(this.levels[index]);
14190
- }
14191
- onBitrate(info) {
14192
- this.highlightCurrentLevel();
14193
- }
14194
- highlightCurrentLevel() {
14195
- trace(`${T$a} highlightCurrentLevel`, {
14196
- selectedLevelId: this.selectedLevelId,
14197
- });
14198
- this.allLevelElements()
14199
- .removeClass('current')
14200
- .find('a')
14201
- .removeClass('gcore-skin-active');
14202
- const currentLevelElement = this.levelElement(this.selectedLevelId);
14203
- currentLevelElement
14204
- .addClass('current')
14205
- .find('a')
14206
- .addClass('gcore-skin-active');
14207
- this.updateText(this.selectedLevelId);
14208
- }
14209
- }
14210
- function formatLevelLabel(level) {
14211
- const h = level.width > level.height ? level.height : level.width;
14212
- return `${h}p`;
14213
- }
14214
-
14215
- function calculateSize(original) {
14216
- const transformed = {
14217
- media: {
14218
- width: 0,
14219
- height: 0
14220
- },
14221
- letterboxing: {
14222
- horizontal: 0,
14223
- vertical: 0
14224
- }
14225
- };
14226
- // Freeze viewport height and scale video to fit vertically
14227
- transformed.media.width = (original.media.width * original.dom.height / original.media.height);
14228
- transformed.media.height = (original.media.height * transformed.media.width / original.media.width);
14229
- // If it didnt't fit, freeze viewport width and scale video to fit horizontally
14230
- if (transformed.media.width > original.dom.width) {
14231
- transformed.media.height = (original.media.height * original.dom.width / original.media.width);
14232
- transformed.media.width = (original.media.width * transformed.media.height / original.media.height);
14233
- }
14234
- // Calculate paddings for vertical or horizontal letterboxing
14235
- if (transformed.media.width < original.dom.width) {
14236
- transformed.letterboxing.horizontal = Math.floor((original.dom.width - transformed.media.width) / 2);
14237
- }
14238
- else {
14239
- if (transformed.media.height < original.dom.height) {
14240
- transformed.letterboxing.vertical = Math.floor((original.dom.height - transformed.media.height) / 2);
14241
- }
14242
- }
14243
- transformed.media.width = Math.floor(transformed.media.width);
14244
- transformed.media.height = Math.floor(transformed.media.height);
14245
- return transformed;
14246
- }
14247
-
14248
- const logoHTML = "<div class=\"clappr-logo control-need-disable\">\n <img class=\"clappr-logo-img\"/>\n</div>\n";
14249
-
14250
- /**
14251
- * `PLUGIN` that adds custom logo to the player.
14252
- * @beta
14253
- */
14254
- class Logo extends UIContainerPlugin {
14255
- hasStartedPlaying = false;
14256
- $logoContainer = null;
14257
- get name() {
14258
- return 'logo';
14259
- }
14260
- get supportedVersion() {
14261
- return { min: CLAPPR_VERSION };
14262
- }
14263
- get template() {
14264
- return tmpl(logoHTML);
14265
- }
14266
- get attributes() {
14267
- return {
14268
- 'class': 'player-logo',
14269
- 'data-logo': ''
14270
- };
14271
- }
14272
- get shouldRender() {
14273
- return !!this.options.logo && !!this.options.logo.path;
14274
- }
14275
- bindEvents() {
14276
- window.addEventListener('resize', this.setPosition);
14277
- this.listenTo(this.container, Events.CONTAINER_RESIZE, this.setPosition);
14278
- this.listenTo(this.container, Events.CONTAINER_STOP, this.onStop);
14279
- this.listenTo(this.container, Events.CONTAINER_PLAY, this.onPlay);
14280
- this.listenTo(this.container, Events.CONTAINER_LOADEDMETADATA, this.setPosition);
14281
- }
14282
- stopListening() {
14283
- window.removeEventListener('resize', this.setPosition);
14284
- // @ts-ignore
14285
- return super.stopListening();
14286
- }
14287
- onPlay() {
14288
- this.hasStartedPlaying = true;
14289
- this.setPosition();
14290
- }
14291
- onStop() {
14292
- this.hasStartedPlaying = false;
14293
- this.update();
14294
- }
14295
- update() {
14296
- if (!this.shouldRender) {
14297
- return;
14298
- }
14299
- if (!this.hasStartedPlaying) {
14300
- this.$el.hide();
14301
- }
14302
- else {
14303
- this.$el.show();
14304
- }
14305
- }
14306
- constructor(container) {
14307
- super(container);
14308
- this.setPosition = this.setPosition.bind(this);
14309
- this.hasStartedPlaying = false;
14310
- if (!this.options.logo) {
14311
- this.disable();
14312
- return;
14313
- }
14314
- this.render();
14315
- }
14316
- render() {
14317
- if (!this.shouldRender) {
14318
- return this;
14319
- }
14320
- this.$el.html(this.template());
14321
- this.setLogoImgAttrs();
14322
- this.container.$el.append(this.$el.get(0));
14323
- this.update();
14035
+ this.$el.html(this.template());
14036
+ this.setLogoImgAttrs();
14037
+ this.container.$el.append(this.$el.get(0));
14038
+ this.update();
14324
14039
  return this;
14325
14040
  }
14326
14041
  setLogoImgAttrs() {
@@ -14647,7 +14362,7 @@ const DEFAULT_SETTINGS = {
14647
14362
  default: [],
14648
14363
  seekEnabled: true,
14649
14364
  };
14650
- const T$9 = 'plugins.media_control';
14365
+ const T$a = 'plugins.media_control';
14651
14366
  const LEFT_ORDER = [
14652
14367
  'playpause',
14653
14368
  'playstop',
@@ -15735,7 +15450,7 @@ class MediaControl extends UICorePlugin {
15735
15450
  return isFinite(this.core.activePlayback.getDuration());
15736
15451
  }
15737
15452
  getElementLocation(name) {
15738
- trace(`${T$9} getElementLocation`, {
15453
+ trace(`${T$a} getElementLocation`, {
15739
15454
  right: this.settings.right,
15740
15455
  left: this.settings.left,
15741
15456
  default: this.settings.default,
@@ -15781,8 +15496,8 @@ const streamsMomentoIcon = "<svg id=\"Слой_1\" data-name=\"Слой 1\" xmln
15781
15496
 
15782
15497
  const streamsWhiteNightsIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"50\" height=\"50\" viewBox=\"0 0 50 50\">\n <defs>\n <clipPath id=\"clip-Icon\">\n <rect width=\"50\" height=\"50\"/>\n </clipPath>\n </defs>\n <g id=\"Icon\" clip-path=\"url(#clip-Icon)\">\n <g id=\"icon2\" transform=\"translate(-0.041 0)\">\n <path id=\"Контур_77\" data-name=\"Контур 77\" d=\"M6.493,13v8.266h6.275V19.74H8.31V17.714h4.006V16.3H8.31V14.53h4.365V13Zm7.5,0v8.266h1.7V15.732h.023l3.438,5.534h1.818V13h-1.7v5.545h-.023L15.8,13Z\" fill=\"#fff\"/>\n <path id=\"Контур_76\" data-name=\"Контур 76\" d=\"M29.949,29.1V26.774H31.94a1.4,1.4,0,0,1,.938.272,1.1,1.1,0,0,1,.313.874,1.155,1.155,0,0,1-.313.9,1.375,1.375,0,0,1-.938.278ZM28.132,25.36v8.266h1.817V30.4h1.818a1.353,1.353,0,0,1,.984.3,1.637,1.637,0,0,1,.394.949c.046.333.079.681.1,1.042a3.2,3.2,0,0,0,.185.938h1.819a1.218,1.218,0,0,1-.191-.423,3.611,3.611,0,0,1-.093-.527c-.019-.185-.033-.367-.041-.544s-.016-.332-.023-.463a5.052,5.052,0,0,0-.087-.625,2.109,2.109,0,0,0-.2-.573,1.586,1.586,0,0,0-.359-.451,1.414,1.414,0,0,0-.556-.284v-.023a1.926,1.926,0,0,0,1-.81,2.494,2.494,0,0,0,.307-1.262,2.308,2.308,0,0,0-.165-.88,2.128,2.128,0,0,0-.486-.724,2.3,2.3,0,0,0-.764-.492,2.67,2.67,0,0,0-1-.179ZM43.506,30.5V25.36H41.689V30.5a2.065,2.065,0,0,1-.37,1.36,1.7,1.7,0,0,1-1.343.434,2.086,2.086,0,0,1-.886-.156,1.283,1.283,0,0,1-.758-.978,3.748,3.748,0,0,1-.058-.66V25.36H36.456V30.5a3.16,3.16,0,0,0,.92,2.5,3.807,3.807,0,0,0,2.6.81,3.82,3.82,0,0,0,2.593-.816,3.132,3.132,0,0,0,.937-2.492Z\" fill=\"#fff\"/>\n <path id=\"Контур_80\" data-name=\"Контур 80\" d=\"M22.646,31.2H4.689a4.505,4.505,0,0,1-4.5-4.5V8.5A4.505,4.505,0,0,1,4.689,4h18.2a4.505,4.505,0,0,1,4.5,4.5v8.445l-.893.1a3.184,3.184,0,0,0-2.846,3.177V30.5l-.465.7ZM4.689,6a2.5,2.5,0,0,0-2.5,2.5V26.7a2.5,2.5,0,0,0,2.5,2.5H21.65V20.22a5.18,5.18,0,0,1,3.739-4.992V8.5a2.5,2.5,0,0,0-2.5-2.5Z\" fill=\"#fff\"/>\n <path id=\"Контур_81\" data-name=\"Контур 81\" d=\"M30.127,47.884a1,1,0,0,1-1-1V43.267H26.846a5.206,5.206,0,0,1-5.2-5.2V20.222a5.206,5.206,0,0,1,5.2-5.2H44.692a5.206,5.206,0,0,1,5.2,5.2V38.068a5.206,5.206,0,0,1-5.2,5.2H35.058l-4.216,4.316A1,1,0,0,1,30.127,47.884ZM26.846,17.022a3.2,3.2,0,0,0-3.2,3.2V38.067a3.2,3.2,0,0,0,3.2,3.2h3.281a1,1,0,0,1,1,1v2.162l2.8-2.86a1,1,0,0,1,.715-.3H44.692a3.2,3.2,0,0,0,3.2-3.2V20.222a3.2,3.2,0,0,0-3.2-3.2Z\" fill=\"#fff\"/>\n </g>\n </g>\n</svg>\n";
15783
15498
 
15784
- const VERSION$3 = '0.0.1';
15785
- const T$8 = 'plugins.multicamera';
15499
+ const VERSION$4 = '0.0.1';
15500
+ const T$9 = 'plugins.multicamera';
15786
15501
  /**
15787
15502
  * `PLUGIN` that adds support for loading multiple streams and switching between them using the media control UI.
15788
15503
  * @beta
@@ -15800,7 +15515,7 @@ class MultiCamera extends UICorePlugin {
15800
15515
  return { min: CLAPPR_VERSION };
15801
15516
  }
15802
15517
  static get version() {
15803
- return VERSION$3;
15518
+ return VERSION$4;
15804
15519
  }
15805
15520
  get template() {
15806
15521
  return tmpl(pluginHtml$3);
@@ -16054,7 +15769,7 @@ class MultiCamera extends UICorePlugin {
16054
15769
  // TODO figure out what this does
16055
15770
  playbackOptions.recycleVideo = Browser.isMobile;
16056
15771
  this.currentCamera = this.findElementById(id) ?? null;
16057
- trace(`${T$8} changeById`, { currentCamera: this.currentCamera, multicamera: this.multicamera });
15772
+ trace(`${T$9} changeById`, { currentCamera: this.currentCamera, multicamera: this.multicamera });
16058
15773
  if (!this.currentCamera) {
16059
15774
  return;
16060
15775
  }
@@ -16070,7 +15785,7 @@ class MultiCamera extends UICorePlugin {
16070
15785
  // TODO remove?
16071
15786
  // for html5 playback:
16072
15787
  this.options.dvrEnabled = this.currentCamera.dvr;
16073
- trace(`${T$8} changeById`, { currentCamera: this.currentCamera });
15788
+ trace(`${T$9} changeById`, { currentCamera: this.currentCamera });
16074
15789
  // TODO
16075
15790
  this.core.configure({
16076
15791
  playback: playbackOptions,
@@ -16125,10 +15840,10 @@ class MultiCamera extends UICorePlugin {
16125
15840
 
16126
15841
  const pipIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M21.05 3.00001C21.302 3.00001 21.5435 3.10003 21.7217 3.27833C21.9 3.45646 22 3.69802 22 3.95003V10.6H20.1V4.90003H4.90001V18.2H10.6V20.1H3.95001C3.69802 20.1 3.45647 20 3.27832 19.8217C3.10002 19.6436 3 19.402 3 19.15V3.95001C3 3.69802 3.10002 3.45647 3.27832 3.27832C3.45644 3.10002 3.69801 3 3.95001 3L21.05 3.00001ZM21.05 12.5C21.302 12.5 21.5435 12.6 21.7217 12.7783C21.9 12.9565 22 13.198 22 13.45V19.15C22 19.402 21.9 19.6436 21.7217 19.8217C21.5436 20 21.302 20.1 21.05 20.1H13.45C13.198 20.1 12.9564 20 12.7783 19.8217C12.6 19.6436 12.5 19.402 12.5 19.15V13.45C12.5 13.198 12.6 12.9565 12.7783 12.7783C12.9564 12.6 13.198 12.5 13.45 12.5H21.05ZM7.47178 6.12823L9.60928 8.26572L11.5501 6.32492V11.5499H6.32509L8.26589 9.60911L6.12839 7.47161L7.47178 6.12823Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
16127
15842
 
16128
- const buttonHtml$1 = "<button class=\"gplayer-lite-btn gcore-skin-button-color\">\n <%= pipIcon %>\n</button>\n";
15843
+ const buttonHtml$2 = "<button class=\"gplayer-lite-btn gcore-skin-button-color\">\n <%= pipIcon %>\n</button>\n";
16129
15844
 
16130
- const VERSION$2 = '0.0.1';
16131
- const T$7 = `plugins.pip`;
15845
+ const VERSION$3 = '0.0.1';
15846
+ const T$8 = `plugins.pip`;
16132
15847
  /**
16133
15848
  * `PLUGIN` that enables picture in picture mode.
16134
15849
  * @beta
@@ -16156,9 +15871,9 @@ class PictureInPicture extends UICorePlugin {
16156
15871
  * @internal
16157
15872
  */
16158
15873
  static get version() {
16159
- return VERSION$2;
15874
+ return VERSION$3;
16160
15875
  }
16161
- static buttonTemplate = tmpl(buttonHtml$1);
15876
+ static buttonTemplate = tmpl(buttonHtml$2);
16162
15877
  /**
16163
15878
  * @internal
16164
15879
  */
@@ -16211,7 +15926,7 @@ class PictureInPicture extends UICorePlugin {
16211
15926
  }
16212
15927
  }
16213
15928
  requestPictureInPicture() {
16214
- trace(`${T$7} requestPictureInPicture`, {
15929
+ trace(`${T$8} requestPictureInPicture`, {
16215
15930
  videoElement: !!this.videoElement,
16216
15931
  });
16217
15932
  this.videoElement.requestPictureInPicture();
@@ -16221,12 +15936,18 @@ class PictureInPicture extends UICorePlugin {
16221
15936
  }
16222
15937
  }
16223
15938
 
16224
- const buttonHtml = "<button class='gplayer-lite-btn gcore-skin-text-color gear-option' id=\"playback-rate-button\">\n <span class=\"gear-option_speed-icon\"><%= speedIcon %></span>\n <span class=\"gear-option_label\"><%= i18n.t('playback_rate') %></span>\n <span class=\"gear-option_arrow-right-icon\"><%= arrowRightIcon %></span>\n <span class='gear-option_value'><%= title %></span>\n</button>\n";
15939
+ const buttonHtml$1 = "<button class='gplayer-lite-btn gcore-skin-text-color gear-option' id=\"playback-rate-button\">\n <span class=\"gear-option_speed-icon\"><%= speedIcon %></span>\n <span class=\"gear-option_label\"><%= i18n.t('playback_rate') %></span>\n <span class=\"gear-option_arrow-right-icon\"><%= arrowRightIcon %></span>\n <span class='gear-option_value'><%= title %></span>\n</button>\n";
16225
15940
 
16226
- const listHtml = "<button class=\"gplayer-lite-btn go-back gcore-skin-text-color\" id=\"playback-rate-back-button\">\n <span class=\"arrow-left-icon\"><%= arrowLeftIcon %></span>\n <%= i18n.t('playback_rate') %>\n</button>\n<ul class=\"gear-sub-menu\" id=\"playback-rate-menu\">\n <% for (const item of playbackRates) { %>\n <li<%= item.value === current ? ' class=\"current\"' : '' %>>\n <a href=\"#\" class=\"gear-sub-menu_btn gcore-skin-text-color<%= item.value === current ? ' gcore-skin-active' : '' %>\" data-rate=\"<%= item.value %>\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= item.label %>\n </a>\n </li>\n <% } %>\n</ul>";
15941
+ const listHtml$1 = "<button class=\"gplayer-lite-btn go-back gcore-skin-text-color\" id=\"playback-rate-back-button\">\n <span class=\"arrow-left-icon\"><%= arrowLeftIcon %></span>\n <%= i18n.t('playback_rate') %>\n</button>\n<ul class=\"gear-sub-menu\" id=\"playback-rate-menu\">\n <% for (const item of playbackRates) { %>\n <li<%= item.value === current ? ' class=\"current\"' : '' %>>\n <a href=\"#\" class=\"gear-sub-menu_btn gcore-skin-text-color<%= item.value === current ? ' gcore-skin-active' : '' %>\" data-rate=\"<%= item.value %>\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= item.label %>\n </a>\n </li>\n <% } %>\n</ul>";
16227
15942
 
16228
15943
  const speedIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11.9854 23.9999C11.4272 23.9999 10.9571 23.5293 10.9571 22.9704C10.9571 22.4115 11.4272 21.9409 11.9854 21.9409C17.4492 21.9409 21.9143 17.4704 21.9143 11.9999C21.9143 6.52948 17.4492 2.05899 11.9854 2.05899C11.4272 2.05899 10.9571 1.58836 10.9571 1.02949C10.9571 0.470625 11.4272 0 11.9854 0C18.5949 0 24 5.38224 24 12.0291C24 18.6766 18.5949 24 11.9854 24V23.9999ZM10.2227 17.853L17.4785 13.4413C18.0072 13.1178 18.301 12.5885 18.301 11.9707C18.301 11.353 17.9779 10.8237 17.4785 10.5002L10.2227 6.08852C9.69405 5.76499 9.01826 5.76499 8.4896 6.05919C7.96094 6.35338 7.60828 6.94157 7.60828 7.5591V16.3824C7.60828 17.0002 7.93142 17.5883 8.4896 17.8824C8.75393 18.0294 9.04779 18.1177 9.34139 18.1177C9.63523 18.1177 9.95838 18.0294 10.2227 17.853V17.853ZM15.9216 11.9707L9.66457 15.7647V8.17661L15.9216 11.9707ZM8.22516 22.3529C8.4602 21.8236 8.25447 21.2058 7.7258 20.9705C7.19714 20.7353 6.69755 20.4413 6.2277 20.0882C5.75764 19.7646 5.11137 19.8822 4.78824 20.3235C4.46509 20.7941 4.58251 21.4412 5.02327 21.7647C5.58146 22.1764 6.19819 22.5293 6.81519 22.8235C6.96211 22.8824 7.10903 22.9117 7.25574 22.9117C7.66699 22.941 8.04893 22.7057 8.22513 22.3528L8.22516 22.3529ZM3.58381 19.0882C4.05387 18.7647 4.17127 18.1177 3.84814 17.647C3.52502 17.1764 3.23115 16.6765 2.99635 16.1471C2.76132 15.6178 2.14456 15.4118 1.6157 15.6472C1.08704 15.8825 0.881306 16.5 1.11634 17.0295C1.41018 17.6472 1.7626 18.2648 2.14459 18.8236C2.35032 19.1178 2.67325 19.2646 2.99638 19.2646C3.20191 19.2942 3.40763 19.2353 3.58384 19.0882L3.58381 19.0882ZM1.14563 13.9707C1.70382 13.9118 2.14435 13.4118 2.08576 12.853C2.05645 12.5588 2.05645 12.2648 2.05645 11.9706C2.05645 11.6764 2.05645 11.4117 2.08576 11.1178C2.14456 10.5589 1.70381 10.059 1.14563 10.0001C0.587439 9.94122 0.0881057 10.3825 0.0293019 10.9414C1.96979e-07 11.2942 0 11.6178 0 11.9709C0 12.3237 0.0293018 12.6768 0.0588091 13.0297C0.117618 13.5589 0.558169 13.9709 1.08706 13.9709C1.08686 13.9707 1.11636 13.9707 1.14567 13.9707L1.14563 13.9707ZM2.96687 7.79432C3.2019 7.26502 3.49553 6.76482 3.81866 6.2944C4.1418 5.82377 4.02439 5.17672 3.55432 4.8532C3.08427 4.52967 2.438 4.64722 2.11486 5.11786C1.73292 5.67672 1.38047 6.2942 1.08661 6.91193C0.851579 7.44123 1.08661 8.05897 1.58597 8.29426C1.73289 8.35314 1.87981 8.38247 2.02652 8.38247C2.40888 8.41181 2.7906 8.1767 2.96686 7.7943L2.96687 7.79432ZM6.22757 3.85328C6.69762 3.52974 7.19696 3.23554 7.69635 2.97089C8.22501 2.73558 8.43074 2.11807 8.19571 1.58857C7.96068 1.05927 7.34392 0.85329 6.81505 1.08861C6.19806 1.3828 5.58128 1.73565 5.02314 2.14741C4.55308 2.47094 4.43568 3.11797 4.78811 3.5886C4.99384 3.8828 5.31676 4.02969 5.6399 4.02969C5.84583 4.05902 6.05135 4.00014 6.22757 3.85325V3.85328Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
16229
15944
 
15945
+ const arrowRightIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.70725 20.7073C8.51225 20.9023 8.25625 21.0002 8.00025 21.0002C7.74425 21.0002 7.48825 20.9023 7.29325 20.7073C6.90225 20.3162 6.90225 19.6842 7.29325 19.2932L14.5863 12.0002L7.29325 4.70725C6.90225 4.31625 6.90225 3.68425 7.29325 3.29325C7.68425 2.90225 8.31625 2.90225 8.70725 3.29325L16.7073 11.2933C17.0983 11.6842 17.0983 12.3162 16.7073 12.7072L8.70725 20.7073Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
15946
+
15947
+ const arrowLeftIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M16.7073 19.2932C17.0983 19.6842 17.0983 20.3162 16.7073 20.7073C16.5123 20.9023 16.2563 21.0002 16.0003 21.0002C15.7443 21.0002 15.4882 20.9023 15.2933 20.7073L7.29325 12.7072C6.90225 12.3162 6.90225 11.6842 7.29325 11.2933L15.2933 3.29325C15.6842 2.90225 16.3163 2.90225 16.7073 3.29325C17.0983 3.68425 17.0983 4.31625 16.7073 4.70725L9.41425 12.0002L16.7073 19.2932Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
15948
+
15949
+ const checkIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M20.5793 4.19296C20.1216 3.86696 19.4777 3.96396 19.1424 4.40896L9.37295 17.3809L4.81634 12.107C4.45222 11.683 3.80218 11.6289 3.36709 11.9839C2.932 12.3389 2.87543 12.97 3.2416 13.393L8.64165 19.643C8.83708 19.869 9.12506 20 9.42849 20C9.4398 20 9.45114 20 9.46246 19.999C9.77926 19.989 10.0724 19.838 10.2586 19.59L20.8015 5.58996C21.1368 5.14496 21.0371 4.51896 20.5793 4.19296Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
15950
+
16230
15951
  var PlaybackEvents;
16231
15952
  (function (PlaybackEvents) {
16232
15953
  /**
@@ -16247,7 +15968,7 @@ const DEFAULT_PLAYBACK_RATES = [
16247
15968
  { value: 2.0, label: '2x' },
16248
15969
  ];
16249
15970
  const DEFAULT_PLAYBACK_RATE = 1;
16250
- const T$6 = 'plugins.playback_rate';
15971
+ const T$7 = 'plugins.playback_rate';
16251
15972
  /**
16252
15973
  * `PLUGIN` that allows changing the playback speed of the video.
16253
15974
  * @beta
@@ -16296,8 +16017,8 @@ class PlaybackRate extends UICorePlugin {
16296
16017
  get supportedVersion() {
16297
16018
  return { min: CLAPPR_VERSION };
16298
16019
  }
16299
- static buttonTemplate = tmpl(buttonHtml);
16300
- static listTemplate = tmpl(listHtml);
16020
+ static buttonTemplate = tmpl(buttonHtml$1);
16021
+ static listTemplate = tmpl(listHtml$1);
16301
16022
  constructor(core) {
16302
16023
  super(core);
16303
16024
  this.playbackRates =
@@ -16375,7 +16096,7 @@ class PlaybackRate extends UICorePlugin {
16375
16096
  this.core.activePlayback?.setPlaybackRate(this.selectedRate);
16376
16097
  }
16377
16098
  else {
16378
- trace(`${T$6} onPlaybackRateChange not steering to the selected rate, it is seemingly a catchup algorithm working`, {
16099
+ trace(`${T$7} onPlaybackRateChange not steering to the selected rate, it is seemingly a catchup algorithm working`, {
16379
16100
  selectedRate: this.selectedRate,
16380
16101
  });
16381
16102
  }
@@ -16394,7 +16115,7 @@ class PlaybackRate extends UICorePlugin {
16394
16115
  * @internal
16395
16116
  */
16396
16117
  render() {
16397
- trace(`${T$6} render`, {
16118
+ trace(`${T$7} render`, {
16398
16119
  shouldRender: this.shouldRender(),
16399
16120
  });
16400
16121
  if (!this.shouldRender()) {
@@ -16478,7 +16199,7 @@ const posterHTML = "<div class=\"play-wrapper\" data-poster></div>\n";
16478
16199
  //Copyright 2014 Globo.com Player authors. All rights reserved.
16479
16200
  // Use of this source code is governed by a BSD-style
16480
16201
  // license that can be found in the LICENSE file.
16481
- const T$5 = 'plugins.poster';
16202
+ const T$6 = 'plugins.poster';
16482
16203
  /**
16483
16204
  * `PLUGIN` that displays a poster image in the background and a big play button on top when playback is stopped
16484
16205
  * @beta
@@ -16589,7 +16310,7 @@ class Poster extends UIContainerPlugin {
16589
16310
  super.disable();
16590
16311
  }
16591
16312
  onError(error) {
16592
- trace(`${T$5} onError`, {
16313
+ trace(`${T$6} onError`, {
16593
16314
  enabled: this.enabled,
16594
16315
  });
16595
16316
  this.hasFatalError = error.level === PlayerError.Levels.FATAL;
@@ -16610,7 +16331,7 @@ class Poster extends UIContainerPlugin {
16610
16331
  this.update();
16611
16332
  }
16612
16333
  onStop() {
16613
- trace(`${T$5} onStop`, {
16334
+ trace(`${T$6} onStop`, {
16614
16335
  enabled: this.enabled,
16615
16336
  });
16616
16337
  this.hasStartedPlaying = false;
@@ -16618,7 +16339,7 @@ class Poster extends UIContainerPlugin {
16618
16339
  this.update();
16619
16340
  }
16620
16341
  updatePlayButton(show) {
16621
- trace(`${T$5} updatePlayButton`, {
16342
+ trace(`${T$6} updatePlayButton`, {
16622
16343
  chromeless: this.options.chromeless,
16623
16344
  allowUserInteraction: this.options.allowUserInteraction,
16624
16345
  });
@@ -16646,7 +16367,7 @@ class Poster extends UIContainerPlugin {
16646
16367
  this.$el.removeClass('clickable');
16647
16368
  }
16648
16369
  clicked() {
16649
- trace(`${T$5} clicked`, {
16370
+ trace(`${T$6} clicked`, {
16650
16371
  hasStartedPlaying: this.hasStartedPlaying,
16651
16372
  chromeless: this.options.chromeless,
16652
16373
  allowUserInteraction: this.options.allowUserInteraction,
@@ -16667,7 +16388,7 @@ class Poster extends UIContainerPlugin {
16667
16388
  return !this.container.playback.isAudioOnly;
16668
16389
  }
16669
16390
  update() {
16670
- trace(`${T$5} update`, {
16391
+ trace(`${T$6} update`, {
16671
16392
  shouldRender: this.shouldRender,
16672
16393
  });
16673
16394
  if (!this.shouldRender) {
@@ -16680,7 +16401,7 @@ class Poster extends UIContainerPlugin {
16680
16401
  this.updatePoster();
16681
16402
  }
16682
16403
  updatePoster() {
16683
- trace(`${T$5} updatePoster`, {
16404
+ trace(`${T$6} updatePoster`, {
16684
16405
  hasStartedPlaying: this.hasStartedPlaying,
16685
16406
  });
16686
16407
  if (!this.hasStartedPlaying) {
@@ -16695,7 +16416,7 @@ class Poster extends UIContainerPlugin {
16695
16416
  this.$el.show();
16696
16417
  }
16697
16418
  hidePoster() {
16698
- trace(`${T$5} hidePoster`, {
16419
+ trace(`${T$6} hidePoster`, {
16699
16420
  shouldHideOnPlay: this.shouldHideOnPlay(),
16700
16421
  });
16701
16422
  if (!this.options.disableMediaControl) {
@@ -16745,6 +16466,275 @@ class Poster extends UIContainerPlugin {
16745
16466
  }
16746
16467
  }
16747
16468
 
16469
+ const buttonHtml = "<button class='gplayer-lite-btn gcore-skin-text-color gear-option' aria-haspopup=\"menu\">\n <span class=\"gear-option_hd-icon<%= isHd ? '' : ' hidden' %>\"><%= hdIcon %></span>\n <span><%= i18n.t('quality') %></span>\n <span class=\"gear-option_arrow-right-icon\"><%= arrowRightIcon %></span>\n <span class='gear-option_value'><%= currentText %></span>\n</button>\n";
16470
+
16471
+ const listHtml = "<button class=\"gplayer-lite-btn go-back gcore-skin-text-color\" id=\"level-selector-back-button\">\n <span class=\"arrow-left-icon\"><%= arrowLeftIcon %></span>\n <%= i18n.t('quality') %>\n</button>\n<ul class=\"gear-sub-menu quality-levels\" id=\"level-selector-menu\" role=\"menu\">\n <% if (!removeAuto) { %>\n <li>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"-1\" id=\"level_selector_auto\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= i18n.t('auto') %>\n </a>\n </li>\n <% } %>\n <% for (const item of levels.slice().reverse()) {\n var disabled = maxLevel >= 0 && item.level > maxLevel\n var checked = item.level === current\n %>\n <li class=\"<%= disabled ? ' disabled' : ''%><%=checked ? ' current' : ''%>\">\n <a href=\"#\"\n class=\"gear-sub-menu_btn gcore-skin-text-color<%= checked ? ' gcore-skin-active' : '' %>\"\n data-id=\"<%= item.level %>\"\n data-disabled=\"<%= disabled %>\"\n data-checked=\"<%= checked %>\"\n role=\"menuitemradio\"\n id=\"level_selector_<%= item.width > item.height ? item.height : item.width %>\"\n >\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= labels[item.level] %>\n </a>\n </li>\n <% } %>\n</ul>\n";
16472
+
16473
+ const hdIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14.9562 8.22232H13.9961V15.1873H14.9562C15.8914 15.1873 16.766 14.8253 17.4195 14.1676C18.0786 13.5037 18.4415 12.6281 18.4415 11.7026C18.4415 9.7837 16.8781 8.22253 14.9561 8.22253L14.9562 8.22232Z\"\n fill=\"#C9C9C9\"/>\n <path\n d=\"M22.0801 4H1.91994C0.859222 4 0 4.86406 0 5.91994V17.4878C0 18.5437 0.859222 19.4078 1.91994 19.4078H22.0801C23.1408 19.4078 24 18.5437 24 17.4878V5.91994C24 4.86406 23.1408 4 22.0801 4ZM10.3975 15.3473C10.3975 15.6124 10.1827 15.8272 9.91754 15.8272C9.65216 15.8272 9.43761 15.6122 9.43761 15.3473V12.0239H5.55956V15.3473C5.55956 15.6124 5.34481 15.8272 5.07963 15.8272C4.81425 15.8272 4.5997 15.6122 4.5997 15.3473L4.59949 7.74042C4.59949 7.47524 4.81425 7.26049 5.07943 7.26049C5.34481 7.26049 5.55936 7.47544 5.55936 7.74042V11.0636H9.43741V7.74042C9.43741 7.47524 9.65216 7.26049 9.91734 7.26049C10.1827 7.26049 10.3973 7.47544 10.3973 7.74042L10.3975 15.3473ZM18.1005 14.8438C17.2652 15.6844 16.1486 16.1472 14.9561 16.1472H13.5161C13.2507 16.1472 13.0361 15.9323 13.0361 15.6673V7.74263C13.0361 7.47745 13.2509 7.26269 13.5161 7.26269H14.9561C17.4072 7.26269 19.4013 9.25438 19.4013 11.7027C19.4013 12.8835 18.9392 13.9991 18.1005 14.844V14.8438Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
16474
+
16475
+ const T$5 = 'plugins.quality_levels';
16476
+ const VERSION$2 = 'v2.22.5';
16477
+ /**
16478
+ * `PLUGIN` that provides a UI to select the desired quality level of the playback.
16479
+ * @beta
16480
+ *
16481
+ * @remarks
16482
+ * Depends on:
16483
+ *
16484
+ * - {@link MediaControl}
16485
+ *
16486
+ * - {@link BottomGear}
16487
+ *
16488
+ * The plugin is rendered as an item in the gear menu, which, when clicked, shows a list of quality levels to choose from.
16489
+ *
16490
+ * Configuration options - {@link QualityLevelsPluginSettings}
16491
+ *
16492
+ * @example
16493
+ * ```ts
16494
+ * new Player({
16495
+ * qualityLevels: {
16496
+ * restrictResolution: 360,
16497
+ * labels: { 360: 'SD', 720: 'HD' },
16498
+ * },
16499
+ * })
16500
+ * ```
16501
+ */
16502
+ class QualityLevels extends UICorePlugin {
16503
+ levels = [];
16504
+ levelLabels = [];
16505
+ removeAuto = false;
16506
+ isHd = false;
16507
+ currentText = '';
16508
+ selectedLevelId = -1;
16509
+ static buttonTemplate = tmpl(buttonHtml);
16510
+ static listTemplate = tmpl(listHtml);
16511
+ /**
16512
+ * @internal
16513
+ */
16514
+ get name() {
16515
+ return 'level_selector';
16516
+ }
16517
+ /**
16518
+ * @internal
16519
+ */
16520
+ get supportedVersion() {
16521
+ return { min: CLAPPR_VERSION };
16522
+ }
16523
+ /**
16524
+ * @internal
16525
+ */
16526
+ static get version() {
16527
+ return VERSION$2;
16528
+ }
16529
+ /**
16530
+ * @internal
16531
+ */
16532
+ get attributes() {
16533
+ return {
16534
+ class: 'level-selector',
16535
+ 'data-level-selector': '',
16536
+ };
16537
+ }
16538
+ get events() {
16539
+ return {
16540
+ 'click .gear-sub-menu_btn': 'onSelect',
16541
+ 'click .go-back': 'goBack',
16542
+ };
16543
+ }
16544
+ /**
16545
+ * @internal
16546
+ */
16547
+ bindEvents() {
16548
+ this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady);
16549
+ this.listenTo(this.core, Events.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChange);
16550
+ }
16551
+ onCoreReady() {
16552
+ const gear = this.core.getPlugin('bottom_gear');
16553
+ assert(gear, 'bottom_gear plugin is required');
16554
+ this.currentText = this.core.i18n.t('auto');
16555
+ this.listenTo(gear, GearEvents.RENDERED, this.onGearRendered);
16556
+ }
16557
+ onGearRendered() {
16558
+ this.render();
16559
+ }
16560
+ onActiveContainerChange() {
16561
+ this.removeAuto = false;
16562
+ this.isHd = false;
16563
+ const activePlayback = this.core.activePlayback;
16564
+ this.listenTo(activePlayback, Events.PLAYBACK_LEVELS_AVAILABLE, this.onLevelsAvailable);
16565
+ this.listenTo(activePlayback, Events.PLAYBACK_LEVEL_SWITCH_START, this.onLevelSwitchStart);
16566
+ this.listenTo(activePlayback, Events.PLAYBACK_LEVEL_SWITCH_END, this.onLevelSwitchEnd);
16567
+ this.listenTo(activePlayback, Events.PLAYBACK_BITRATE, this.onBitrate);
16568
+ this.listenTo(activePlayback, Events.PLAYBACK_STOP, this.onStop);
16569
+ this.listenTo(activePlayback, Events.PLAYBACK_HIGHDEFINITIONUPDATE, (isHd) => {
16570
+ this.isHd = isHd;
16571
+ this.updateHd();
16572
+ });
16573
+ if (activePlayback.levels?.length > 0) {
16574
+ this.onLevelsAvailable(activePlayback.levels);
16575
+ }
16576
+ }
16577
+ updateHd() {
16578
+ if (this.isHd) {
16579
+ this.$el.find('.gear-option_hd-icon').removeClass('hidden');
16580
+ }
16581
+ else {
16582
+ this.$el.find('.gear-option_hd-icon').addClass('hidden');
16583
+ }
16584
+ }
16585
+ onStop() {
16586
+ this.listenToOnce(this.core.activePlayback, Events.PLAYBACK_PLAY, () => {
16587
+ if (this.core.activePlayback.getPlaybackType() === 'live') {
16588
+ if (this.selectedLevelId !== -1) {
16589
+ this.core.activePlayback.currentLevel = this.selectedLevelId;
16590
+ }
16591
+ }
16592
+ });
16593
+ }
16594
+ shouldRender() {
16595
+ const activePlayback = this.core.activePlayback;
16596
+ if (!activePlayback) {
16597
+ return false;
16598
+ }
16599
+ const supportsCurrentLevel = 'currentLevel' in activePlayback;
16600
+ if (!supportsCurrentLevel) {
16601
+ return false;
16602
+ }
16603
+ // Only care if we have at least 2 to choose from
16604
+ return !!(this.levels && this.levels.length > 1);
16605
+ }
16606
+ /**
16607
+ * @internal
16608
+ */
16609
+ render() {
16610
+ if (!this.shouldRender()) {
16611
+ return this;
16612
+ }
16613
+ this.renderDropdown();
16614
+ this.updateButton();
16615
+ return this;
16616
+ }
16617
+ renderDropdown() {
16618
+ this.$el.html(QualityLevels.listTemplate({
16619
+ arrowLeftIcon,
16620
+ checkIcon,
16621
+ current: this.selectedLevelId,
16622
+ labels: this.levelLabels,
16623
+ levels: this.levels,
16624
+ maxLevel: this.maxLevel,
16625
+ removeAuto: this.removeAuto,
16626
+ i18n: this.core.i18n,
16627
+ }));
16628
+ }
16629
+ updateButton() {
16630
+ this.core.getPlugin('bottom_gear')
16631
+ ?.addItem('quality', this.$el)
16632
+ .html(QualityLevels.buttonTemplate({
16633
+ arrowRightIcon,
16634
+ currentText: this.currentText,
16635
+ isHd: this.isHd,
16636
+ hdIcon,
16637
+ i18n: this.core.i18n,
16638
+ }));
16639
+ }
16640
+ get pluginOptions() {
16641
+ return (this.core.options.qualityLevels || this.core.options.levelSelector || {});
16642
+ }
16643
+ get maxLevel() {
16644
+ const maxRes = this.pluginOptions.restrictResolution;
16645
+ return maxRes
16646
+ ? this.levels.find((level) => (level.height > level.width ? level.width : level.height) ===
16647
+ maxRes)?.level ?? -1
16648
+ : -1;
16649
+ }
16650
+ onLevelsAvailable(levels) {
16651
+ const maxResolution = this.pluginOptions.restrictResolution;
16652
+ this.levels = levels;
16653
+ this.makeLevelsLabels();
16654
+ if (maxResolution) {
16655
+ this.removeAuto = true;
16656
+ const initialLevel = levels
16657
+ .filter((level) => (level.width > level.height ? level.height : level.width) <=
16658
+ maxResolution)
16659
+ .pop();
16660
+ this.setLevel(initialLevel?.level ?? 0);
16661
+ }
16662
+ this.render();
16663
+ }
16664
+ makeLevelsLabels() {
16665
+ const labels = this.pluginOptions.labels ?? {};
16666
+ this.levelLabels = [];
16667
+ for (const level of this.levels) {
16668
+ const ll = level.width > level.height ? level.height : level.width;
16669
+ const label = labels[ll] || `${ll}p`;
16670
+ this.levelLabels.push(label);
16671
+ }
16672
+ }
16673
+ onSelect(event) {
16674
+ const selectedLevel = parseInt(event.currentTarget?.dataset?.id ?? '-1', 10);
16675
+ this.setLevel(selectedLevel);
16676
+ event.stopPropagation();
16677
+ event.preventDefault();
16678
+ return false;
16679
+ }
16680
+ goBack() {
16681
+ this.core.getPlugin('bottom_gear').refresh();
16682
+ }
16683
+ setLevel(index) {
16684
+ this.selectedLevelId = index;
16685
+ this.core.activePlayback.currentLevel = this.selectedLevelId;
16686
+ this.highlightCurrentLevel();
16687
+ }
16688
+ allLevelElements() {
16689
+ return this.$('#level-selector-menu li');
16690
+ }
16691
+ levelElement(id = -1) {
16692
+ return this.$(`#level-selector-menu a[data-id="${id}"]`).parent();
16693
+ }
16694
+ onLevelSwitchStart() {
16695
+ this.levelElement(this.selectedLevelId).addClass('changing');
16696
+ }
16697
+ onLevelSwitchEnd() {
16698
+ this.levelElement(this.selectedLevelId).removeClass('changing');
16699
+ }
16700
+ updateText(level) {
16701
+ this.currentText = this.getLevelLabel(level);
16702
+ this.updateButton();
16703
+ }
16704
+ getLevelLabel(id) {
16705
+ if (id < 0) {
16706
+ return this.core.i18n.t('auto');
16707
+ }
16708
+ const index = this.levels.findIndex((l) => l.level === id);
16709
+ if (index < 0) {
16710
+ return this.core.i18n.t('auto');
16711
+ }
16712
+ return this.levelLabels[index] ?? formatLevelLabel(this.levels[index]);
16713
+ }
16714
+ onBitrate(info) {
16715
+ this.highlightCurrentLevel();
16716
+ }
16717
+ highlightCurrentLevel() {
16718
+ trace(`${T$5} highlightCurrentLevel`, {
16719
+ selectedLevelId: this.selectedLevelId,
16720
+ });
16721
+ this.allLevelElements()
16722
+ .removeClass('current')
16723
+ .find('a')
16724
+ .removeClass('gcore-skin-active');
16725
+ const currentLevelElement = this.levelElement(this.selectedLevelId);
16726
+ currentLevelElement
16727
+ .addClass('current')
16728
+ .find('a')
16729
+ .addClass('gcore-skin-active');
16730
+ this.updateText(this.selectedLevelId);
16731
+ }
16732
+ }
16733
+ function formatLevelLabel(level) {
16734
+ const h = level.width > level.height ? level.height : level.width;
16735
+ return `${h}p`;
16736
+ }
16737
+
16748
16738
  const seekTimeHTML = "<span data-seek-time></span>\n<span data-duration></span>\n";
16749
16739
 
16750
16740
  // Copyright 2014 Globo.com Player authors. All rights reserved.
@@ -18704,4 +18694,4 @@ class VolumeFade extends UICorePlugin {
18704
18694
  }
18705
18695
  }
18706
18696
 
18707
- export { AudioSelector, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ClosedCaptions, ContextMenu, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, LevelSelector, Logo, MediaControl, MultiCamera, PictureInPicture, PlaybackRate, Poster, SeekTime, Share, SkipTime, SourceController, SpinnerThreeBounce as Spinner, SpinnerEvents, SpinnerThreeBounce, ClosedCaptions as Subtitles, Telemetry, TelemetryEvent, Thumbnails, VolumeFade, VolumeFadeEvents };
18697
+ export { AudioTracks as AudioSelector, AudioTracks, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ClosedCaptions, ContextMenu, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, QualityLevels as LevelSelector, Logo, MediaControl, MultiCamera, PictureInPicture, PlaybackRate, Poster, QualityLevels, SeekTime, Share, SkipTime, SourceController, SpinnerThreeBounce as Spinner, SpinnerEvents, SpinnerThreeBounce, ClosedCaptions as Subtitles, Telemetry, TelemetryEvent, Thumbnails, VolumeFade, VolumeFadeEvents };