@gcorevideo/player 2.20.7 → 2.20.9

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 (218) hide show
  1. package/dist/core.js +54 -25
  2. package/dist/index.css +1184 -1184
  3. package/dist/index.js +298 -267
  4. package/dist/player.d.ts +178 -126
  5. package/dist/plugins/index.css +841 -841
  6. package/dist/plugins/index.js +192 -192
  7. package/docs/api/player.bottomgear.md +14 -0
  8. package/docs/api/player.bottomgear.refresh.md +20 -0
  9. package/docs/api/player.clapprnerdstats.md +1 -1
  10. package/docs/api/player.clapprstats.exportmetrics.md +1 -1
  11. package/docs/api/player.clapprstats.md +1 -15
  12. package/docs/api/player.clapprstats.setupdatemetrics.md +2 -0
  13. package/docs/api/player.clipsplugin.md +1 -1
  14. package/docs/api/player.clipspluginsettings.md +5 -2
  15. package/docs/api/player.clipspluginsettings.text.md +3 -0
  16. package/docs/api/{player.errorscreen.bindevents.md → player.containerpluginconstructor.md} +7 -6
  17. package/docs/api/{player.errorscreen.render.md → player.corepluginconstructor.md} +7 -6
  18. package/docs/api/player.errordesc.md +28 -0
  19. package/docs/api/player.errorscreen.md +1 -220
  20. package/docs/api/{player.errorscreen.hide.md → player.errorscreenpluginsettings.md} +7 -7
  21. package/docs/api/player.levelselector.md +3 -9
  22. package/docs/api/player.levelselectorpluginsettings.labels.md +24 -0
  23. package/docs/api/player.levelselectorpluginsettings.md +79 -0
  24. package/docs/api/player.levelselectorpluginsettings.restrictresolution.md +16 -0
  25. package/docs/api/player.md +93 -16
  26. package/docs/api/{player.errorscreen.container.md → player.mediacontrol.currentseekpos.md} +3 -3
  27. package/docs/api/player.mediacontrol.disable.md +1 -1
  28. package/docs/api/player.mediacontrol.md +23 -2
  29. package/docs/api/{player.gearevents.md → player.mediacontrolevents.md} +4 -4
  30. package/docs/api/player.multicamera.md +1 -29
  31. package/docs/api/player.playbackerror.md +19 -0
  32. package/docs/api/{player.errorscreen.supportedversion.md → player.playbackerror.ui.md} +7 -4
  33. package/docs/api/player.playbackerrorcode.md +3 -3
  34. package/docs/api/{player.errorscreen.show.md → player.playbackrate._constructor_.md} +7 -11
  35. package/docs/api/player.playbackrate.md +35 -2
  36. package/docs/api/player.player.registerplugin.md +2 -2
  37. package/docs/api/player.player.unregisterplugin.md +2 -2
  38. package/docs/api/player.playerpluginconstructor.md +17 -0
  39. package/docs/api/player.share.attributes.md +3 -0
  40. package/docs/api/player.share.bindevents.md +3 -0
  41. package/docs/api/player.share.canshowshare.md +3 -0
  42. package/docs/api/player.share.events.md +3 -0
  43. package/docs/api/player.share.hideshare.md +3 -0
  44. package/docs/api/player.share.initializeicons.md +3 -0
  45. package/docs/api/player.share.md +40 -1
  46. package/docs/api/player.share.name.md +3 -0
  47. package/docs/api/player.share.onshareembedclick.md +3 -0
  48. package/docs/api/player.share.onsharefb.md +3 -0
  49. package/docs/api/player.share.onsharehide.md +3 -0
  50. package/docs/api/player.share.onsharelinkclick.md +3 -0
  51. package/docs/api/player.share.onshareshow.md +3 -0
  52. package/docs/api/player.share.onsharetw.md +3 -0
  53. package/docs/api/player.share.render.md +3 -0
  54. package/docs/api/player.share.showshare.md +3 -0
  55. package/docs/api/player.share.supportedversion.md +3 -0
  56. package/docs/api/player.share.template.md +3 -0
  57. package/docs/api/player.share.unbindevents.md +3 -0
  58. package/docs/api/player.skiptime.attributes.md +3 -0
  59. package/docs/api/player.skiptime.bindevents.md +3 -0
  60. package/docs/api/player.skiptime.container.md +3 -0
  61. package/docs/api/player.skiptime.events.md +3 -0
  62. package/docs/api/player.skiptime.handlerewindclicks.md +3 -0
  63. package/docs/api/player.skiptime.md +30 -1
  64. package/docs/api/player.skiptime.name.md +3 -0
  65. package/docs/api/player.skiptime.render.md +3 -0
  66. package/docs/api/player.skiptime.setback.md +3 -0
  67. package/docs/api/player.skiptime.setforward.md +3 -0
  68. package/docs/api/player.skiptime.setmidclick.md +3 -0
  69. package/docs/api/player.skiptime.supportedversion.md +3 -0
  70. package/docs/api/player.skiptime.template.md +3 -0
  71. package/docs/api/player.skiptime.togglefullscreen.md +3 -0
  72. package/docs/api/player.spinnerevents.md +4 -1
  73. package/docs/api/player.spinnerthreebounce.hide.md +1 -1
  74. package/docs/api/player.spinnerthreebounce.md +7 -5
  75. package/docs/api/player.spinnerthreebounce.show.md +40 -2
  76. package/docs/api/player.telemetry.md +1 -1
  77. package/docs/api/player.telemetrypluginsettings.md +1 -1
  78. package/docs/api/{player.errorscreen.unbindevents.md → player.telemetrysendfn.md} +6 -6
  79. package/lib/Player.d.ts +13 -4
  80. package/lib/Player.d.ts.map +1 -1
  81. package/lib/Player.js +17 -12
  82. package/lib/index.core.d.ts +0 -1
  83. package/lib/index.core.d.ts.map +1 -1
  84. package/lib/index.core.js +0 -1
  85. package/lib/index.plugins.d.ts +0 -1
  86. package/lib/index.plugins.d.ts.map +1 -1
  87. package/lib/index.plugins.js +0 -1
  88. package/lib/playback/BasePlayback.d.ts +5 -0
  89. package/lib/playback/BasePlayback.d.ts.map +1 -1
  90. package/lib/playback/BasePlayback.js +8 -0
  91. package/lib/playback/HTML5Video.d.ts +4 -0
  92. package/lib/playback/HTML5Video.d.ts.map +1 -0
  93. package/lib/playback/HTML5Video.js +3 -0
  94. package/lib/playback/dash-playback/DashPlayback.d.ts +1 -0
  95. package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
  96. package/lib/playback/dash-playback/DashPlayback.js +6 -2
  97. package/lib/playback/hls-playback/HlsPlayback.d.ts.map +1 -1
  98. package/lib/playback/hls-playback/HlsPlayback.js +1 -1
  99. package/lib/playback/index.d.ts.map +1 -1
  100. package/lib/playback/index.js +2 -0
  101. package/lib/playback/types.d.ts +9 -0
  102. package/lib/playback/types.d.ts.map +1 -0
  103. package/lib/playback/types.js +9 -0
  104. package/lib/plugins/bottom-gear/BottomGear.d.ts +7 -12
  105. package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
  106. package/lib/plugins/bottom-gear/BottomGear.js +5 -14
  107. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +1 -1
  108. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +3 -3
  109. package/lib/plugins/clappr-nerd-stats/speedtest/Speedtest.d.ts.map +1 -1
  110. package/lib/plugins/clappr-nerd-stats/speedtest/Speedtest.js +8 -8
  111. package/lib/plugins/clappr-stats/ClapprStats.d.ts +4 -5
  112. package/lib/plugins/clappr-stats/ClapprStats.d.ts.map +1 -1
  113. package/lib/plugins/clappr-stats/ClapprStats.js +4 -3
  114. package/lib/plugins/clips/Clips.d.ts +3 -2
  115. package/lib/plugins/clips/Clips.d.ts.map +1 -1
  116. package/lib/plugins/clips/Clips.js +1 -1
  117. package/lib/plugins/context-menu/ContextMenu.d.ts.map +1 -1
  118. package/lib/plugins/dvr-controls/DvrControls.d.ts +4 -3
  119. package/lib/plugins/dvr-controls/DvrControls.d.ts.map +1 -1
  120. package/lib/plugins/dvr-controls/DvrControls.js +30 -18
  121. package/lib/plugins/error-screen/ErrorScreen.d.ts +12 -1
  122. package/lib/plugins/error-screen/ErrorScreen.d.ts.map +1 -1
  123. package/lib/plugins/error-screen/ErrorScreen.js +1 -1
  124. package/lib/plugins/index.d.ts +0 -1
  125. package/lib/plugins/index.d.ts.map +1 -1
  126. package/lib/plugins/index.js +0 -1
  127. package/lib/plugins/kibo/index.d.ts +0 -3
  128. package/lib/plugins/kibo/index.d.ts.map +1 -1
  129. package/lib/plugins/kibo/index.js +0 -3
  130. package/lib/plugins/level-selector/LevelSelector.d.ts +8 -4
  131. package/lib/plugins/level-selector/LevelSelector.d.ts.map +1 -1
  132. package/lib/plugins/level-selector/LevelSelector.js +16 -7
  133. package/lib/plugins/media-control/MediaControl.d.ts +5 -4
  134. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  135. package/lib/plugins/media-control/MediaControl.js +8 -6
  136. package/lib/plugins/multi-camera/MultiCamera.d.ts +3 -11
  137. package/lib/plugins/multi-camera/MultiCamera.d.ts.map +1 -1
  138. package/lib/plugins/multi-camera/MultiCamera.js +1 -1
  139. package/lib/plugins/playback-rate/PlaybackRate.d.ts +11 -10
  140. package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
  141. package/lib/plugins/playback-rate/PlaybackRate.js +83 -91
  142. package/lib/plugins/poster/Poster.js +2 -2
  143. package/lib/plugins/share/Share.d.ts +2 -1
  144. package/lib/plugins/share/Share.d.ts.map +1 -1
  145. package/lib/plugins/share/Share.js +2 -1
  146. package/lib/plugins/skip-time/SkipTime.d.ts +2 -1
  147. package/lib/plugins/skip-time/SkipTime.d.ts.map +1 -1
  148. package/lib/plugins/skip-time/SkipTime.js +2 -1
  149. package/lib/plugins/source-controller/SourceController.js +3 -3
  150. package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts +6 -3
  151. package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts.map +1 -1
  152. package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.js +6 -3
  153. package/lib/plugins/telemetry/Telemetry.d.ts +2 -3
  154. package/lib/plugins/telemetry/Telemetry.d.ts.map +1 -1
  155. package/lib/plugins/telemetry/Telemetry.js +1 -1
  156. package/lib/plugins/vast-ads/VastAds.d.ts.map +1 -1
  157. package/lib/plugins/vast-ads/VastAds.js +3 -3
  158. package/lib/plugins/vast-ads/roll.d.ts +1 -1
  159. package/lib/plugins/vast-ads/roll.d.ts.map +1 -1
  160. package/lib/plugins/vast-ads/rollmanager.d.ts +1 -1
  161. package/lib/plugins/vast-ads/rollmanager.d.ts.map +1 -1
  162. package/lib/plugins/vast-ads/rollmanager.js +2 -2
  163. package/lib/types.d.ts +21 -5
  164. package/lib/types.d.ts.map +1 -1
  165. package/lib/utils/types.d.ts +0 -6
  166. package/lib/utils/types.d.ts.map +1 -1
  167. package/package.json +1 -1
  168. package/src/Player.ts +18 -16
  169. package/src/index.core.ts +0 -1
  170. package/src/index.plugins.ts +0 -1
  171. package/src/playback/BasePlayback.ts +12 -4
  172. package/src/playback/HTML5Video.ts +3 -0
  173. package/src/playback/dash-playback/DashPlayback.ts +15 -11
  174. package/src/playback/hls-playback/HlsPlayback.ts +7 -11
  175. package/src/playback/index.ts +2 -1
  176. package/src/playback/types.ts +9 -0
  177. package/src/plugins/audio-selector/AudioSelector.ts +1 -1
  178. package/src/plugins/big-mute-button/BigMuteButton.ts +1 -1
  179. package/src/plugins/bottom-gear/BottomGear.ts +7 -16
  180. package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +5 -5
  181. package/src/plugins/clappr-nerd-stats/speedtest/Speedtest.ts +184 -187
  182. package/src/plugins/clappr-stats/ClapprStats.ts +5 -4
  183. package/src/plugins/clips/Clips.ts +4 -3
  184. package/src/plugins/context-menu/ContextMenu.ts +0 -2
  185. package/src/plugins/dvr-controls/DvrControls.ts +90 -56
  186. package/src/plugins/error-screen/ErrorScreen.ts +12 -1
  187. package/src/plugins/favicon/Favicon.ts +1 -1
  188. package/src/plugins/index.ts +0 -1
  189. package/src/plugins/kibo/index.ts +0 -3
  190. package/src/plugins/level-selector/LevelSelector.ts +24 -10
  191. package/src/plugins/logo/Logo.ts +1 -1
  192. package/src/plugins/media-control/MediaControl.ts +13 -10
  193. package/src/plugins/multi-camera/MultiCamera.ts +4 -4
  194. package/src/plugins/playback-rate/PlaybackRate.ts +90 -106
  195. package/src/plugins/poster/Poster.ts +3 -3
  196. package/src/plugins/seek-time/SeekTime.ts +1 -1
  197. package/src/plugins/share/Share.ts +2 -1
  198. package/src/plugins/skip-time/SkipTime.ts +2 -1
  199. package/src/plugins/source-controller/SourceController.ts +3 -3
  200. package/src/plugins/source-controller/__tests__/SourceController.test.ts +2 -2
  201. package/src/plugins/spinner-three-bounce/SpinnerThreeBounce.ts +6 -3
  202. package/src/plugins/subtitles/Subtitles.ts +1 -1
  203. package/src/plugins/telemetry/Telemetry.ts +2 -2
  204. package/src/plugins/thumbnails/Thumbnails.ts +1 -1
  205. package/src/plugins/vast-ads/VastAds.ts +5 -4
  206. package/src/plugins/vast-ads/roll.ts +2 -1
  207. package/src/plugins/vast-ads/rollmanager.ts +3 -3
  208. package/src/types.ts +24 -5
  209. package/src/utils/types.ts +0 -8
  210. package/temp/player.api.json +540 -576
  211. package/tsconfig.tsbuildinfo +1 -1
  212. package/assets/playback-rate/playback-rate-selector.ejs +0 -9
  213. package/docs/api/player.clapprstats.onbitrate.md +0 -52
  214. package/docs/api/player.errorscreen.attributes.md +0 -17
  215. package/docs/api/player.errorscreen.name.md +0 -14
  216. package/docs/api/player.errorscreen.template.md +0 -14
  217. package/docs/api/player.multicamera.getcameraslist.md +0 -18
  218. package/docs/api/player.multicamera.getcurrentcamera.md +0 -18
package/dist/index.js CHANGED
@@ -7761,7 +7761,7 @@ var UNKNOWN_ERROR = {
7761
7761
  };
7762
7762
 
7763
7763
  // TODO: rename this Playback to HTML5Playback (breaking change, only after 0.3.0)
7764
- var HTML5Video = /*#__PURE__*/function (_Playback) {
7764
+ var HTML5Video$1 = /*#__PURE__*/function (_Playback) {
7765
7765
  function HTML5Video() {
7766
7766
  var _this;
7767
7767
  _classCallCheck(this, HTML5Video);
@@ -8553,7 +8553,7 @@ var HTML5Video = /*#__PURE__*/function (_Playback) {
8553
8553
  }
8554
8554
  }]);
8555
8555
  }(Playback);
8556
- HTML5Video._mimeTypesForUrl = function () {
8556
+ HTML5Video$1._mimeTypesForUrl = function () {
8557
8557
  var resourceUrl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
8558
8558
  var mimeTypesByExtension = arguments.length > 1 ? arguments[1] : undefined;
8559
8559
  var mimeType = arguments.length > 2 ? arguments[2] : undefined;
@@ -8561,15 +8561,15 @@ HTML5Video._mimeTypesForUrl = function () {
8561
8561
  var mimeTypes = mimeType || extension && mimeTypesByExtension[extension.toLowerCase()] || [];
8562
8562
  return mimeTypes.constructor === Array ? mimeTypes : [mimeTypes];
8563
8563
  };
8564
- HTML5Video._canPlay = function (type, mimeTypesByExtension, resourceUrl, mimeType) {
8565
- var mimeTypes = HTML5Video._mimeTypesForUrl(resourceUrl, mimeTypesByExtension, mimeType);
8564
+ HTML5Video$1._canPlay = function (type, mimeTypesByExtension, resourceUrl, mimeType) {
8565
+ var mimeTypes = HTML5Video$1._mimeTypesForUrl(resourceUrl, mimeTypesByExtension, mimeType);
8566
8566
  var media = document.createElement(type);
8567
8567
  return !!mimeTypes.filter(function (mediaType) {
8568
8568
  return !!media.canPlayType(mediaType).replace(/no/, '');
8569
8569
  })[0];
8570
8570
  };
8571
- HTML5Video.canPlay = function (resourceUrl, mimeType) {
8572
- return HTML5Video._canPlay('audio', AUDIO_MIMETYPES, resourceUrl, mimeType) || HTML5Video._canPlay('video', MIMETYPES, resourceUrl, mimeType);
8571
+ HTML5Video$1.canPlay = function (resourceUrl, mimeType) {
8572
+ return HTML5Video$1._canPlay('audio', AUDIO_MIMETYPES, resourceUrl, mimeType) || HTML5Video$1._canPlay('video', MIMETYPES, resourceUrl, mimeType);
8573
8573
  };
8574
8574
 
8575
8575
  // TODO: remove this playback and change HTML5Video to HTML5Playback (breaking change, only after 0.3.0)
@@ -8614,7 +8614,7 @@ var HTML5Audio = /*#__PURE__*/function (_HTML5Video) {
8614
8614
  return Playback.AOD;
8615
8615
  }
8616
8616
  }]);
8617
- }(HTML5Video);
8617
+ }(HTML5Video$1);
8618
8618
  HTML5Audio.canPlay = function (resourceUrl, mimeType) {
8619
8619
  var mimetypes = {
8620
8620
  'wav': ['audio/wav'],
@@ -8622,7 +8622,7 @@ HTML5Audio.canPlay = function (resourceUrl, mimeType) {
8622
8622
  'aac': ['audio/mp4;codecs="mp4a.40.5"'],
8623
8623
  'oga': ['audio/ogg']
8624
8624
  };
8625
- return HTML5Video._canPlay('audio', mimetypes, resourceUrl, mimeType);
8625
+ return HTML5Video$1._canPlay('audio', mimetypes, resourceUrl, mimeType);
8626
8626
  };
8627
8627
 
8628
8628
  var css_248z$1 = "[data-html-img] {\n max-width: 100%;\n max-height: 100%; }\n";
@@ -9024,7 +9024,7 @@ Loader.registerPlugin(SourcesPlugin);
9024
9024
  Loader.registerPlayback(NoOp);
9025
9025
  Loader.registerPlayback(HTMLImg);
9026
9026
  Loader.registerPlayback(HTML5Audio);
9027
- Loader.registerPlayback(HTML5Video);
9027
+ Loader.registerPlayback(HTML5Video$1);
9028
9028
 
9029
9029
  const global$1 = (typeof global !== "undefined" ? global :
9030
9030
  typeof self !== "undefined" ? self :
@@ -12628,7 +12628,7 @@ var PlaybackErrorCode;
12628
12628
  * @internal
12629
12629
  * TODO use custom HTML5Video playback with this layer applied
12630
12630
  */
12631
- class BasePlayback extends HTML5Video {
12631
+ class BasePlayback extends HTML5Video$1 {
12632
12632
  createError(errorData, options) {
12633
12633
  const i18n = this.i18n ||
12634
12634
  // @ts-ignore
@@ -12649,18 +12649,35 @@ class BasePlayback extends HTML5Video {
12649
12649
  }
12650
12650
  return super.createError(errorData, options);
12651
12651
  }
12652
+ /**
12653
+ * Sets the playback rate.
12654
+ * @param rate - The playback rate to set.
12655
+ */
12656
+ setPlaybackRate(rate) {
12657
+ this.el.playbackRate = rate;
12658
+ }
12652
12659
  _onPlaying() {
12653
12660
  super._onPlaying();
12654
12661
  this.trigger(Events$1.PLAYBACK_MEDIACONTROL_ENABLE);
12655
12662
  }
12656
12663
  }
12657
12664
 
12665
+ var PlaybackEvents;
12666
+ (function (PlaybackEvents) {
12667
+ /**
12668
+ * Emitted when the playback rate changes.
12669
+ * Payload:
12670
+ * - playbackRate number
12671
+ */
12672
+ PlaybackEvents["PLAYBACK_RATE_CHANGED"] = "playback:rate-changed";
12673
+ })(PlaybackEvents || (PlaybackEvents = {}));
12674
+
12658
12675
  // Copyright 2014 Globo.com Player authors. All rights reserved.
12659
12676
  // Use of this source code is governed by a BSD-style
12660
12677
  // license that can be found in the LICENSE file.
12661
12678
  const AUTO$2 = -1;
12662
12679
  const { now: now$2 } = Utils;
12663
- const T$g = 'playback.dash';
12680
+ const T$i = 'playback.dash';
12664
12681
  // @ts-expect-error
12665
12682
  class DashPlayback extends BasePlayback {
12666
12683
  _levels = null;
@@ -12838,8 +12855,8 @@ class DashPlayback extends BasePlayback {
12838
12855
  }
12839
12856
  }
12840
12857
  });
12841
- this._dash.on(DASHJS.MediaPlayer.events.PLAYBACK_RATE_CHANGED, () => {
12842
- this.trigger('dash:playback-rate-changed');
12858
+ this._dash.on(DASHJS.MediaPlayer.events.PLAYBACK_RATE_CHANGED, (e) => {
12859
+ this.trigger(PlaybackEvents.PLAYBACK_RATE_CHANGED, e.playbackRate);
12843
12860
  });
12844
12861
  }
12845
12862
  render() {
@@ -12930,10 +12947,10 @@ class DashPlayback extends BasePlayback {
12930
12947
  }
12931
12948
  _onPlaybackError = (event) => {
12932
12949
  // TODO
12933
- trace(`${T$g} _onPlaybackError`, { event });
12950
+ trace(`${T$i} _onPlaybackError`, { event });
12934
12951
  };
12935
12952
  _onDASHJSSError = (event) => {
12936
- trace(`${T$g} _onDASHJSSError`, { event });
12953
+ trace(`${T$i} _onDASHJSSError`, { event });
12937
12954
  this._stopTimeUpdateTimer();
12938
12955
  // Note that the other error types are deprecated
12939
12956
  const e = event.error;
@@ -12968,7 +12985,7 @@ class DashPlayback extends BasePlayback {
12968
12985
  }
12969
12986
  };
12970
12987
  triggerError(error) {
12971
- trace(`${T$g} triggerError`, { error });
12988
+ trace(`${T$i} triggerError`, { error });
12972
12989
  // this triggers Events.ERROR to be handled by the UI
12973
12990
  this.trigger(Events$1.PLAYBACK_ERROR, this.createError(error, {
12974
12991
  useCodePrefix: false,
@@ -13007,7 +13024,7 @@ class DashPlayback extends BasePlayback {
13007
13024
  }
13008
13025
  get dvrEnabled() {
13009
13026
  if (!this._dash) {
13010
- trace(`${T$g} dvrEnable no dash player instance`);
13027
+ trace(`${T$i} dvrEnable no dash player instance`);
13011
13028
  return false;
13012
13029
  }
13013
13030
  return (this._dash?.getDVRWindowSize() >= this._minDvrSize &&
@@ -13029,7 +13046,7 @@ class DashPlayback extends BasePlayback {
13029
13046
  this.trigger(Events$1.PLAYBACK_PROGRESS, progress, {});
13030
13047
  }
13031
13048
  play() {
13032
- trace(`${T$g} play`, { dash: !!this._dash });
13049
+ trace(`${T$i} play`, { dash: !!this._dash });
13033
13050
  if (!this._dash) {
13034
13051
  this._setup();
13035
13052
  }
@@ -13105,6 +13122,9 @@ class DashPlayback extends BasePlayback {
13105
13122
  assert.ok(ret, 'Invalid quality level');
13106
13123
  return ret;
13107
13124
  }
13125
+ setPlaybackRate(rate) {
13126
+ this._dash?.setPlaybackRate(rate);
13127
+ }
13108
13128
  }
13109
13129
  DashPlayback.canPlay = function (resource, mimeType) {
13110
13130
  if (!isDashSource(resource, mimeType)) {
@@ -41776,7 +41796,7 @@ const AUTO$1 = -1;
41776
41796
  const DEFAULT_RECOVER_ATTEMPTS = 16;
41777
41797
  Events$1.register('PLAYBACK_FRAGMENT_CHANGED');
41778
41798
  Events$1.register('PLAYBACK_FRAGMENT_PARSING_METADATA');
41779
- const T$f = 'playback.hls';
41799
+ const T$h = 'playback.hls';
41780
41800
  // @ts-expect-error
41781
41801
  class HlsPlayback extends BasePlayback {
41782
41802
  _ccIsSetup = false;
@@ -42006,7 +42026,7 @@ class HlsPlayback extends BasePlayback {
42006
42026
  maxBufferLength: 2,
42007
42027
  maxMaxBufferLength: 4,
42008
42028
  }, this.options.playback.hlsjsConfig);
42009
- trace(`${T$f} _createHLSInstance`, { config });
42029
+ trace(`${T$h} _createHLSInstance`, { config });
42010
42030
  this._hls = new Hls(config);
42011
42031
  }
42012
42032
  _attachHLSMedia() {
@@ -42095,7 +42115,7 @@ class HlsPlayback extends BasePlayback {
42095
42115
  }
42096
42116
  else {
42097
42117
  Log.error('hlsjs: failed to recover', { evt, data });
42098
- trace(`${T$f} _recover failed to recover`, {
42118
+ trace(`${T$h} _recover failed to recover`, {
42099
42119
  type: data.type,
42100
42120
  details: data.details,
42101
42121
  });
@@ -42181,7 +42201,7 @@ class HlsPlayback extends BasePlayback {
42181
42201
  this.trigger(Events$1.PLAYBACK_SETTINGSUPDATE);
42182
42202
  }
42183
42203
  _onHLSJSError(evt, data) {
42184
- trace(`${T$f} _onHLSJSError`, {
42204
+ trace(`${T$h} _onHLSJSError`, {
42185
42205
  fatal: data.fatal,
42186
42206
  type: data.type,
42187
42207
  details: data.details,
@@ -42229,7 +42249,7 @@ class HlsPlayback extends BasePlayback {
42229
42249
  evt,
42230
42250
  data,
42231
42251
  });
42232
- trace(`${T$f} _onHLSJSError trying to recover from network error`, {
42252
+ trace(`${T$h} _onHLSJSError trying to recover from network error`, {
42233
42253
  details: data.details,
42234
42254
  });
42235
42255
  error.level = PlayerError.Levels.WARN;
@@ -42242,7 +42262,7 @@ class HlsPlayback extends BasePlayback {
42242
42262
  evt,
42243
42263
  data,
42244
42264
  });
42245
- trace(`${T$f} _onHLSJSError trying to recover from media error`, {
42265
+ trace(`${T$h} _onHLSJSError trying to recover from media error`, {
42246
42266
  details: data.details,
42247
42267
  });
42248
42268
  error.level = PlayerError.Levels.WARN;
@@ -42272,7 +42292,7 @@ class HlsPlayback extends BasePlayback {
42272
42292
  return;
42273
42293
  }
42274
42294
  Log.warn('hlsjs: non-fatal error occurred', { evt, data });
42275
- trace(`${T$f} _onHLSJSError non-fatal error occurred`, {
42295
+ trace(`${T$h} _onHLSJSError non-fatal error occurred`, {
42276
42296
  type: data.type,
42277
42297
  details: data.details,
42278
42298
  });
@@ -42596,13 +42616,17 @@ HlsPlayback.canPlay = function (resource, mimeType) {
42596
42616
  return Hls.isSupported();
42597
42617
  };
42598
42618
 
42619
+ class HTML5Video extends BasePlayback {
42620
+ }
42621
+
42599
42622
  // TODO consider allowing the variation of the order of playback modules
42600
42623
  function registerPlaybacks() {
42624
+ Loader.registerPlayback(HTML5Video); // TODO check it overrides the default HTML5Video
42601
42625
  Loader.registerPlayback(HlsPlayback);
42602
42626
  Loader.registerPlayback(DashPlayback);
42603
42627
  }
42604
42628
 
42605
- const T$e = 'GPlayer';
42629
+ const T$g = 'GPlayer';
42606
42630
  const DEFAULT_OPTIONS = {
42607
42631
  autoPlay: false,
42608
42632
  debug: 'none',
@@ -42697,7 +42721,7 @@ class Player {
42697
42721
  }
42698
42722
  const coreOpts = this.buildCoreOptions(playerElement);
42699
42723
  const { core, container } = Player.getRegisteredPlugins();
42700
- trace(`${T$e} init`, {
42724
+ trace(`${T$g} init`, {
42701
42725
  registeredPlaybacks: Loader.registeredPlaybacks.map((p) => p.name),
42702
42726
  });
42703
42727
  coreOpts.plugins = {
@@ -42711,7 +42735,7 @@ class Player {
42711
42735
  * Destroys the player, releasing all resources and unmounting its UI from the DOM.
42712
42736
  */
42713
42737
  destroy() {
42714
- trace(`${T$e} destroy`, {
42738
+ trace(`${T$g} destroy`, {
42715
42739
  player: !!this.player,
42716
42740
  });
42717
42741
  if (this.player) {
@@ -42870,6 +42894,23 @@ class Player {
42870
42894
  }
42871
42895
  Loader.registerPlugin(plugin);
42872
42896
  }
42897
+ /**
42898
+ * Unregisters a plugin registered earlier with {@link Player.registerPlugin}.
42899
+ * @remarks
42900
+ * It can be also used to unregister a built-in default plugin.
42901
+ *
42902
+ * Currently, the plugins that are always registered are:
42903
+ *
42904
+ * - {@link https://github.com/clappr/clappr-core/blob/3126c3a38a6eee9d5aba3918b194e6380fa1178c/src/plugins/strings/strings.js | 'strings'}, which supports internationalization of the player UI
42905
+ *
42906
+ * - {@link https://github.com/clappr/clappr-core/blob/3126c3a38a6eee9d5aba3918b194e6380fa1178c/src/plugins/sources/sources.js | 'sources'}, which lets to specify multiple media sources and selects the first suitable playback module
42907
+ *
42908
+ * @param name - name of the plugin
42909
+ */
42910
+ static unregisterPlugin(name) {
42911
+ Player.corePlugins = Player.corePlugins.filter((p) => p.prototype.name !== name);
42912
+ Loader.unregisterPlugin(name);
42913
+ }
42873
42914
  static getRegisteredPlugins() {
42874
42915
  for (const plugin of Player.corePlugins) {
42875
42916
  Loader.registerPlugin(plugin);
@@ -42877,23 +42918,11 @@ class Player {
42877
42918
  return Loader.registeredPlugins;
42878
42919
  }
42879
42920
  static corePlugins = [];
42880
- /**
42881
- * Unregisters a plugin registered earlier with {@link Player.registerPlugin}.
42882
- * @param plugin - a plugin class
42883
- */
42884
- static unregisterPlugin(plugin) {
42885
- assert.ok(plugin.type === 'core' || plugin.type === 'container', 'Invalid plugin type');
42886
- if (plugin.type === 'core') {
42887
- Player.corePlugins = Player.corePlugins.filter((p) => p !== plugin);
42888
- return;
42889
- }
42890
- Loader.unregisterPlugin(plugin);
42891
- }
42892
42921
  setConfig(config) {
42893
42922
  this.config = $.extend(true, this.config, config);
42894
42923
  }
42895
42924
  initPlayer(coreOptions) {
42896
- trace(`${T$e} initPlayer`, {
42925
+ trace(`${T$g} initPlayer`, {
42897
42926
  autoPlay: coreOptions.autoPlay,
42898
42927
  sources: coreOptions.sources,
42899
42928
  // TODO selected options
@@ -42918,7 +42947,7 @@ class Player {
42918
42947
  }
42919
42948
  }
42920
42949
  triggerAutoPlay() {
42921
- trace(`${T$e} triggerAutoPlay`);
42950
+ trace(`${T$g} triggerAutoPlay`);
42922
42951
  setTimeout(() => {
42923
42952
  this.player?.play({
42924
42953
  autoPlay: true,
@@ -42936,7 +42965,7 @@ class Player {
42936
42965
  // TODO test
42937
42966
  events = {
42938
42967
  onReady: () => {
42939
- trace(`${T$e} onReady`, {
42968
+ trace(`${T$g} onReady`, {
42940
42969
  ready: this.ready,
42941
42970
  });
42942
42971
  if (this.ready) {
@@ -42970,7 +42999,7 @@ class Player {
42970
42999
  buildCoreOptions(rootNode) {
42971
43000
  const sources = this.buildMediaSourcesList();
42972
43001
  const source = sources[0];
42973
- trace(`${T$e} buildCoreOptions`, {
43002
+ trace(`${T$g} buildCoreOptions`, {
42974
43003
  source,
42975
43004
  sources,
42976
43005
  });
@@ -43031,7 +43060,7 @@ class Player {
43031
43060
  assert.ok(this.player, 'Player is not initialized');
43032
43061
  const core = this.player.core;
43033
43062
  core.on(Events$1.CORE_SCREEN_ORIENTATION_CHANGED, ({ orientation }) => {
43034
- trace(`${T$e} on CORE_SCREEN_ORIENTATION_CHANGED`, {
43063
+ trace(`${T$g} on CORE_SCREEN_ORIENTATION_CHANGED`, {
43035
43064
  orientation,
43036
43065
  rootNode: {
43037
43066
  width: this.rootNode?.clientWidth,
@@ -43046,14 +43075,14 @@ class Player {
43046
43075
  }
43047
43076
  }, null);
43048
43077
  core.on(Events$1.CORE_RESIZE, ({ width, height }) => {
43049
- trace(`${T$e} on CORE_RESIZE`, {
43078
+ trace(`${T$g} on CORE_RESIZE`, {
43050
43079
  width,
43051
43080
  height,
43052
43081
  });
43053
43082
  this.safeTriggerEvent(PlayerEvent.Resize, { width, height });
43054
43083
  }, null);
43055
43084
  core.on(Events$1.CORE_FULLSCREEN, (isFullscreen) => {
43056
- trace(`${T$e} CORE_FULLSCREEN`, {
43085
+ trace(`${T$g} CORE_FULLSCREEN`, {
43057
43086
  isFullscreen,
43058
43087
  });
43059
43088
  this.safeTriggerEvent(PlayerEvent.Fullscreen, isFullscreen);
@@ -43061,7 +43090,7 @@ class Player {
43061
43090
  }
43062
43091
  }
43063
43092
 
43064
- var version$1 = "2.20.7";
43093
+ var version$1 = "2.20.9";
43065
43094
 
43066
43095
  var packages = {
43067
43096
  "node_modules/@clappr/core": {
@@ -43085,7 +43114,7 @@ function version() {
43085
43114
  };
43086
43115
  }
43087
43116
 
43088
- const pluginHtml$8 = "<button data-track-selector-button class='gcore-skin-button-color'>\n <span class='audio-text'><%= title %></span> <span class=\"audio-arrow\"></span>\n</button>\n<ul class='gcore-skin-bg-color'>\n <% for (var i = 0; i < tracks.length; i++) { %>\n <li>\n <a href=\"#\" class='gcore-skin-text-color' data-track-selector-select=\"<%= tracks[i].id %>\">\n <%= tracks[i].label || tracks[i].name %>\n </a>\n </li>\n <% }; %>\n</ul>\n";
43117
+ const pluginHtml$7 = "<button data-track-selector-button class='gcore-skin-button-color'>\n <span class='audio-text'><%= title %></span> <span class=\"audio-arrow\"></span>\n</button>\n<ul class='gcore-skin-bg-color'>\n <% for (var i = 0; i < tracks.length; i++) { %>\n <li>\n <a href=\"#\" class='gcore-skin-text-color' data-track-selector-select=\"<%= tracks[i].id %>\">\n <%= tracks[i].label || tracks[i].name %>\n </a>\n </li>\n <% }; %>\n</ul>\n";
43089
43118
 
43090
43119
  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";
43091
43120
 
@@ -43119,7 +43148,7 @@ class AudioSelector extends UICorePlugin {
43119
43148
  static get version() {
43120
43149
  return VERSION$6;
43121
43150
  }
43122
- static template = tmpl(pluginHtml$8);
43151
+ static template = tmpl(pluginHtml$7);
43123
43152
  /**
43124
43153
  * @internal
43125
43154
  */
@@ -43392,9 +43421,9 @@ class AudioSelector extends UICorePlugin {
43392
43421
 
43393
43422
  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";
43394
43423
 
43395
- const pluginHtml$7 = "<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";
43424
+ 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";
43396
43425
 
43397
- const T$d = 'plugins.big_mute_button';
43426
+ const T$f = 'plugins.big_mute_button';
43398
43427
  // TODO rewrite as a container plugin
43399
43428
  /**
43400
43429
  * Displays a big mute button over the video when it's muted.
@@ -43418,7 +43447,7 @@ class BigMuteButton extends UICorePlugin {
43418
43447
  get supportedVersion() {
43419
43448
  return { min: CLAPPR_VERSION };
43420
43449
  }
43421
- static template = tmpl(pluginHtml$7);
43450
+ static template = tmpl(pluginHtml$6);
43422
43451
  /**
43423
43452
  * @internal
43424
43453
  */
@@ -43436,7 +43465,7 @@ class BigMuteButton extends UICorePlugin {
43436
43465
  this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
43437
43466
  this.listenTo(this.core, 'core:advertisement:start', this.onStartAd);
43438
43467
  this.listenTo(this.core, 'core:advertisement:finish', this.onFinishAd);
43439
- trace(`${T$d} bindEvents`, {
43468
+ trace(`${T$f} bindEvents`, {
43440
43469
  mediacontrol: !!this.core.mediaControl,
43441
43470
  });
43442
43471
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.mediaControlRendered);
@@ -43461,12 +43490,12 @@ class BigMuteButton extends UICorePlugin {
43461
43490
  }
43462
43491
  mediaControlRendered() {
43463
43492
  const container = this.core.activeContainer;
43464
- trace(`${T$d} mediaControlRendered`, {
43493
+ trace(`${T$f} mediaControlRendered`, {
43465
43494
  container: !!container,
43466
43495
  });
43467
43496
  if (container) {
43468
43497
  this.listenTo(container.playback, Events$1.PLAYBACK_PLAY, () => {
43469
- trace(`${T$d} PLAYBACK_PLAY`);
43498
+ trace(`${T$f} PLAYBACK_PLAY`);
43470
43499
  this.render();
43471
43500
  });
43472
43501
  }
@@ -43490,7 +43519,7 @@ class BigMuteButton extends UICorePlugin {
43490
43519
  }
43491
43520
  const { autoPlay, wasMuted } = this.options;
43492
43521
  const volume = container.volume;
43493
- trace(`${T$d} shouldRender`, {
43522
+ trace(`${T$f} shouldRender`, {
43494
43523
  autoPlay,
43495
43524
  wasMuted,
43496
43525
  volume,
@@ -43502,7 +43531,7 @@ class BigMuteButton extends UICorePlugin {
43502
43531
  */
43503
43532
  render() {
43504
43533
  if (this.shouldRender()) {
43505
- trace(`${T$d} render`, {
43534
+ trace(`${T$f} render`, {
43506
43535
  el: !!this.$el,
43507
43536
  });
43508
43537
  this.$el.html(BigMuteButton.template());
@@ -43541,7 +43570,7 @@ class BigMuteButton extends UICorePlugin {
43541
43570
  }
43542
43571
  }
43543
43572
 
43544
- const pluginHtml$6 = "<div class=\"media-control-gear\" data-<%= name %>>\n <button type=\"button\" class=\"button-gear gplayer-lite-btn gcore-skin-button-color\" data-gear-button=\"-1\">\n <span class=\"gear-icon\"><%= icon %></span>\n </button>\n <div class=\"gear-wrapper gcore-skin-bg-color\">\n <ul class=\"gear-options-list\">\n <% items.forEach(function (gear) { %>\n <li data-<%= gear %>></li>\n <% }); %>\n </ul>\n </div>\n</div>\n";
43573
+ const pluginHtml$5 = "<div class=\"media-control-gear\" data-<%= name %>>\n <button type=\"button\" class=\"button-gear gplayer-lite-btn gcore-skin-button-color\" data-gear-button=\"-1\">\n <span class=\"gear-icon\"><%= icon %></span>\n </button>\n <div class=\"gear-wrapper gcore-skin-bg-color\">\n <ul class=\"gear-options-list\">\n <% items.forEach(function (gear) { %>\n <li data-<%= gear %>></li>\n <% }); %>\n </ul>\n </div>\n</div>\n";
43545
43574
 
43546
43575
  const gearIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_660_1503)\">\n <path\n d=\"M19.14 12.94C19.18 12.64 19.2 12.33 19.2 12C19.2 11.68 19.18 11.36 19.13 11.06L21.16 9.47999C21.34 9.33999 21.39 9.06999 21.28 8.86999L19.36 5.54999C19.24 5.32999 18.99 5.25999 18.77 5.32999L16.38 6.28999C15.88 5.90999 15.35 5.58999 14.76 5.34999L14.4 2.80999C14.36 2.56999 14.16 2.39999 13.92 2.39999H10.08C9.83999 2.39999 9.64999 2.56999 9.60999 2.80999L9.24999 5.34999C8.65999 5.58999 8.11999 5.91999 7.62999 6.28999L5.23999 5.32999C5.01999 5.24999 4.76999 5.32999 4.64999 5.54999L2.73999 8.86999C2.61999 9.07999 2.65999 9.33999 2.85999 9.47999L4.88999 11.06C4.83999 11.36 4.79999 11.69 4.79999 12C4.79999 12.31 4.81999 12.64 4.86999 12.94L2.83999 14.52C2.65999 14.66 2.60999 14.93 2.71999 15.13L4.63999 18.45C4.75999 18.67 5.00999 18.74 5.22999 18.67L7.61999 17.71C8.11999 18.09 8.64999 18.41 9.23999 18.65L9.59999 21.19C9.64999 21.43 9.83999 21.6 10.08 21.6H13.92C14.16 21.6 14.36 21.43 14.39 21.19L14.75 18.65C15.34 18.41 15.88 18.09 16.37 17.71L18.76 18.67C18.98 18.75 19.23 18.67 19.35 18.45L21.27 15.13C21.39 14.91 21.34 14.66 21.15 14.52L19.14 12.94ZM12 15.6C10.02 15.6 8.39999 13.98 8.39999 12C8.39999 10.02 10.02 8.39999 12 8.39999C13.98 8.39999 15.6 10.02 15.6 12C15.6 13.98 13.98 15.6 12 15.6Z\"\n fill=\"#C9C9C9\"/>\n </g>\n <defs>\n <clipPath id=\"clip0_660_1503\">\n <rect width=\"24\" height=\"24\" fill=\"white\"/>\n </clipPath>\n </defs>\n</svg>\n";
43547
43576
 
@@ -43550,9 +43579,6 @@ const gearHdIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\
43550
43579
  /* eslint-disable */
43551
43580
  // Kibo is released under the MIT License. Copyright (c) 2013 marquete.
43552
43581
  // see https://github.com/marquete/kibo
43553
- /**
43554
- * @internal
43555
- */
43556
43582
  class Kibo {
43557
43583
  element;
43558
43584
  lastKeyCode = -1;
@@ -43835,7 +43861,7 @@ var MediaControlEvents;
43835
43861
  */
43836
43862
  MediaControlEvents["MEDIACONTROL_GEAR_RENDERED"] = "mediacontrol:gear:rendered";
43837
43863
  })(MediaControlEvents || (MediaControlEvents = {}));
43838
- const T$c = 'plugins.media_control';
43864
+ const T$e = 'plugins.media_control';
43839
43865
  const LEFT_ORDER = [
43840
43866
  'playpause',
43841
43867
  'playstop',
@@ -43852,7 +43878,7 @@ function orderByOrderPattern(arr, order) {
43852
43878
  return [...ordered, ...rest];
43853
43879
  }
43854
43880
  /**
43855
- * The MediaControl provides a foundation for developing custom media controls UI.
43881
+ * PLUGIN that provides a foundation for developing custom media controls UI.
43856
43882
  * @beta
43857
43883
  * @remarks
43858
43884
  * The methods exposed are to be used by the other plugins that extend the media control UI.
@@ -43869,7 +43895,7 @@ class MediaControl extends UICorePlugin {
43869
43895
  buttonsColor = null;
43870
43896
  currentDurationValue = 0;
43871
43897
  currentPositionValue = 0;
43872
- currentSeekBarPercentage = null;
43898
+ currentSeekBarPercentage = 0;
43873
43899
  disabledClickableList = [];
43874
43900
  displayedDuration = null;
43875
43901
  displayedPosition = null;
@@ -43934,14 +43960,14 @@ class MediaControl extends UICorePlugin {
43934
43960
  }
43935
43961
  /**
43936
43962
  * @internal
43937
- * @deprecated
43963
+ * @deprecated Use core.activeContainer directly
43938
43964
  */
43939
43965
  get container() {
43940
43966
  return this.core.activeContainer;
43941
43967
  }
43942
43968
  /**
43943
43969
  * @internal
43944
- * @deprecated
43970
+ * @deprecated Use core.activePlayback directly
43945
43971
  */
43946
43972
  get playback() {
43947
43973
  return this.core.activePlayback;
@@ -43987,6 +44013,9 @@ class MediaControl extends UICorePlugin {
43987
44013
  'mouseleave .media-control-layer[data-controls]': 'resetUserKeepVisible',
43988
44014
  };
43989
44015
  }
44016
+ get currentSeekPos() {
44017
+ return this.currentSeekBarPercentage;
44018
+ }
43990
44019
  /**
43991
44020
  * Current volume [0..100]
43992
44021
  */
@@ -44083,7 +44112,7 @@ class MediaControl extends UICorePlugin {
44083
44112
  * Hides the media control UI
44084
44113
  */
44085
44114
  disable() {
44086
- trace(`${T$c} disable`);
44115
+ trace(`${T$e} disable`);
44087
44116
  this.userDisabled = true; // TODO distinguish between user and system (e.g., unplayable) disabled?
44088
44117
  this.hide();
44089
44118
  this.unbindKeyEvents();
@@ -44093,7 +44122,7 @@ class MediaControl extends UICorePlugin {
44093
44122
  * Reenables the plugin disabled earlier with the {@link MediaControl.disable} method
44094
44123
  */
44095
44124
  enable() {
44096
- trace(`${T$c} enable`);
44125
+ trace(`${T$e} enable`);
44097
44126
  if (this.options.chromeless) {
44098
44127
  return;
44099
44128
  }
@@ -44349,8 +44378,7 @@ class MediaControl extends UICorePlugin {
44349
44378
  this.changeTogglePlay();
44350
44379
  this.bindContainerEvents();
44351
44380
  this.settingsUpdate();
44352
- this.core.activeContainer &&
44353
- this.core.activeContainer.trigger(Events$1.CONTAINER_PLAYBACKDVRSTATECHANGED, this.core.activeContainer.isDvrInUse());
44381
+ this.core.activeContainer.trigger(Events$1.CONTAINER_PLAYBACKDVRSTATECHANGED, this.core.activeContainer.isDvrInUse());
44354
44382
  // TODO test
44355
44383
  if (this.core.activeContainer.mediaControlDisabled) {
44356
44384
  this.disable();
@@ -44916,18 +44944,7 @@ MediaControl.extend = function (properties) {
44916
44944
  };
44917
44945
 
44918
44946
  const VERSION$5 = '2.19.12';
44919
- const T$b = 'plugins.bottom_gear';
44920
- /**
44921
- * Custom events emitted by the plugin
44922
- * @beta
44923
- */
44924
- var GearEvents;
44925
- (function (GearEvents) {
44926
- /**
44927
- * Emitted when the gear menu is rendered
44928
- */
44929
- GearEvents["MEDIACONTROL_GEAR_RENDERED"] = "mediacontrol:gear:rendered";
44930
- })(GearEvents || (GearEvents = {}));
44947
+ const T$d = 'plugins.bottom_gear';
44931
44948
  /**
44932
44949
  * Adds the gear button that triggers extra options menu on the right side of the {@link MediaControl | media control} UI
44933
44950
  * @beta
@@ -44958,7 +44975,7 @@ class BottomGear extends UICorePlugin {
44958
44975
  static get version() {
44959
44976
  return VERSION$5;
44960
44977
  }
44961
- static template = tmpl(pluginHtml$6);
44978
+ static template = tmpl(pluginHtml$5);
44962
44979
  /**
44963
44980
  * @internal
44964
44981
  */
@@ -44983,7 +45000,6 @@ class BottomGear extends UICorePlugin {
44983
45000
  const mediaControl = this.core.getPlugin('media_control');
44984
45001
  assert(mediaControl, 'media_control plugin is required');
44985
45002
  this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChanged);
44986
- this.listenTo(this.core, 'gear:refresh', this.refresh); // TODO use direct plugin method call
44987
45003
  this.listenTo(mediaControl, Events$1.MEDIACONTROL_RENDERED, this.render);
44988
45004
  this.listenTo(mediaControl, Events$1.MEDIACONTROL_HIDE, this.hide); // TODO mediacontrol show as well
44989
45005
  }
@@ -45002,15 +45018,15 @@ class BottomGear extends UICorePlugin {
45002
45018
  this.$el.find('.gear-wrapper').html(content);
45003
45019
  }
45004
45020
  onActiveContainerChanged() {
45005
- trace(`${T$b} onActiveContainerChanged`);
45021
+ trace(`${T$d} onActiveContainerChanged`);
45006
45022
  this.bindContainerEvents();
45007
45023
  }
45008
45024
  bindContainerEvents() {
45009
- trace(`${T$b} bindContainerEvents`);
45025
+ trace(`${T$d} bindContainerEvents`);
45010
45026
  this.listenTo(this.core.activeContainer, Events$1.CONTAINER_HIGHDEFINITIONUPDATE, this.highDefinitionUpdate);
45011
45027
  }
45012
45028
  highDefinitionUpdate(isHd) {
45013
- trace(`${T$b} highDefinitionUpdate`, { isHd });
45029
+ trace(`${T$d} highDefinitionUpdate`, { isHd });
45014
45030
  this.isHd = isHd;
45015
45031
  this.$el.find('.gear-icon').html(isHd ? gearHdIcon : gearIcon);
45016
45032
  }
@@ -45029,11 +45045,14 @@ class BottomGear extends UICorePlugin {
45029
45045
  const icon = this.isHd ? gearHdIcon : gearIcon;
45030
45046
  this.$el.html(BottomGear.template({ icon, items }));
45031
45047
  mediaControl.getElement('gear')?.html(this.el);
45032
- this.core.trigger('gear:rendered'); // @deprecated
45033
- mediaControl.trigger(GearEvents.MEDIACONTROL_GEAR_RENDERED); // TODO drop
45034
45048
  mediaControl.trigger(MediaControlEvents.MEDIACONTROL_GEAR_RENDERED);
45035
45049
  return this;
45036
45050
  }
45051
+ /**
45052
+ * Re-renders the gear menu.
45053
+ * It fires the {@link MediaControlEvents.MEDIACONTROL_GEAR_RENDERED | MEDIACONTROL_GEAR_RENDERED} event,
45054
+ * which the plugins that attach to the gear menu can listen to to re-render themselves.
45055
+ */
45037
45056
  refresh() {
45038
45057
  this.render();
45039
45058
  this.$el.find('.gear-wrapper').show();
@@ -46691,7 +46710,7 @@ class Speedtest {
46691
46710
  this._state = 1;
46692
46711
  }
46693
46712
  if (this._state !== 1) {
46694
- throw 'You can\'t add a server after server selection';
46713
+ throw "You can't add a server after server selection";
46695
46714
  }
46696
46715
  this._settings.mpot = true;
46697
46716
  this._serverList.push(server);
@@ -46710,7 +46729,7 @@ class Speedtest {
46710
46729
  setSelectedServer(server) {
46711
46730
  this._checkServerDefinition(server);
46712
46731
  if (this._state === 3) {
46713
- throw 'You can\'t select a server while the test is running';
46732
+ throw "You can't select a server while the test is running";
46714
46733
  }
46715
46734
  this._selectedServer = server;
46716
46735
  this._state = 2;
@@ -46724,7 +46743,7 @@ class Speedtest {
46724
46743
  throw 'Server already selected';
46725
46744
  }
46726
46745
  if (this._state >= 3) {
46727
- throw 'You can\'t select a server while the test is running';
46746
+ throw "You can't select a server while the test is running";
46728
46747
  }
46729
46748
  }
46730
46749
  if (this._selectServerCalled) {
@@ -46734,7 +46753,7 @@ class Speedtest {
46734
46753
  this._selectServerCalled = true;
46735
46754
  }
46736
46755
  /*this function goes through a list of servers. For each server, the ping is measured, then the server with the function result is called with the best server, or null if all the servers were down.
46737
- */
46756
+ */
46738
46757
  const select = (serverList, result) => {
46739
46758
  //pings the specified URL, then calls the function result. Result will receive a parameter which is either the time it took to ping the URL, or -1 if something went wrong.
46740
46759
  const PING_TIMEOUT = 2000;
@@ -46836,7 +46855,7 @@ class Speedtest {
46836
46855
  }
46837
46856
  result(bestServer);
46838
46857
  };
46839
- serverList.forEach(server => {
46858
+ serverList.forEach((server) => {
46840
46859
  checkServer(server, done);
46841
46860
  });
46842
46861
  if (i === serverList.length) {
@@ -46929,12 +46948,12 @@ class Speedtest {
46929
46948
  if (typeof this._originalExtra !== 'undefined') {
46930
46949
  this._settings.telemetry_extra = JSON.stringify({
46931
46950
  server: this._selectedServer.name,
46932
- extra: this._originalExtra
46951
+ extra: this._originalExtra,
46933
46952
  });
46934
46953
  }
46935
46954
  else {
46936
46955
  this._settings.telemetry_extra = JSON.stringify({
46937
- server: this._selectedServer.name
46956
+ server: this._selectedServer.name,
46938
46957
  });
46939
46958
  }
46940
46959
  }
@@ -46944,7 +46963,7 @@ class Speedtest {
46944
46963
  }
46945
46964
  abort() {
46946
46965
  if (this._state < 3) {
46947
- throw new Error('You cannot abort a test that\'s not started yet');
46966
+ throw new Error("You cannot abort a test that's not started yet");
46948
46967
  }
46949
46968
  if (this._state < 4) {
46950
46969
  this.worker?.postMessage('abort');
@@ -47114,7 +47133,7 @@ function rankConnectionSpeed(dlSpeed) {
47114
47133
  return 0;
47115
47134
  }
47116
47135
 
47117
- const pluginHtml$5 = "<% general = metrics.general %>\n<% counters = metrics.counters %>\n<% timers = metrics.timers %>\n<% extra = metrics.extra %>\n<% custom = metrics.custom %>\n\n<div class=\"stats-box\">\n <div class=\"stats-box-top\">\n <a class=\"close-button gplayer-lite-btn\" data-close-button>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <g clip-path=\"url(#clip0_184_1489)\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M7.41376 6.00013L13.7068 -0.292872C14.0978 -0.683872 14.0978 -1.31587 13.7068 -1.70687C13.3158 -2.09787 12.6838 -2.09787 12.2928 -1.70687L5.99976 4.58613L-0.293238 -1.70687C-0.684238 -2.09787 -1.31624 -2.09787 -1.70724 -1.70687C-2.09824 -1.31587 -2.09824 -0.683872 -1.70724 -0.292872L4.58576 6.00013L-1.70724 12.2931C-2.09824 12.6841 -2.09824 13.3161 -1.70724 13.7071C-1.51224 13.9021 -1.25624 14.0001 -1.00024 14.0001C-0.744238 14.0001 -0.488238 13.9021 -0.293238 13.7071L5.99976 7.41413L12.2928 13.7071C12.4878 13.9021 12.7438 14.0001 12.9998 14.0001C13.2558 14.0001 13.5118 13.9021 13.7068 13.7071C14.0978 13.3161 14.0978 12.6841 13.7068 12.2931L7.41376 6.00013Z\"\n fill=\"white\"/>\n </g>\n <defs>\n <clipPath id=\"clip0_184_1489\">\n <rect width=\"12\" height=\"12\" fill=\"white\"/>\n </clipPath>\n </defs>\n </svg>\n </a>\n </div>\n <div class=\"stats-box-main\">\n <ul>\n <li class=\"title\"><span>General</span></li>\n <li>\n Display resolution:\n <div><span><%= general.displayResolution %></span></div>\n </li>\n <li>\n Volume:\n <div><span><%= general.volume %></span></div>\n </li>\n <li>\n Connection speed:\n <div><span id=\"dlText\"><%= custom.connectionSpeed %></span> Mbps</div>\n </li>\n <li class=\"canvas-wrapper\">\n <canvas id=\"speedTestCanvas\" width=\"190\" height=\"20\"></canvas>\n </li>\n <li>\n Ping:\n <div><span id=\"pingText\"><%= custom.ping %></span> ms</div>\n </li>\n <li>\n Jitter:\n <div><span id=\"jitterText\"><%= custom.jitter %></span> ms</div>\n </li>\n </ul>\n\n <ul>\n <li class=\"title\"><span>Counters</span></li>\n <li>\n Plays:\n <div><span><%= counters.play %></span></div>\n </li>\n <li>\n Pauses:\n <div><span><%= counters.pause %></span></div>\n </li>\n <li>\n Errors:\n <div><span><%= counters.error %></span></div>\n </li>\n <li>\n Bufferings:\n <div><span><%= counters.buffering %></span></div>\n </li>\n <li>\n Decoded frames:\n <div><span><%= counters.decodedFrames %></span></div>\n </li>\n <li>\n Dropped frames:\n <div><span><%= counters.droppedFrames %></span></div>\n </li>\n <li>\n Frames per second:\n <div><span><%= counters.fps %></span></div>\n </li>\n <li>\n Bitrate changes:\n <div><span><%= counters.changeLevel %></span></div>\n </li>\n <li>\n Seeks:\n <div><span><%= counters.seek %></span></div>\n </li>\n <li>\n Fullscreen:\n <div><span><%= counters.fullscreen %></span></div>\n </li>\n <li>\n DVR seeks:\n <div><span><%= counters.dvrUsage %></span></div>\n </li>\n </ul>\n\n <ul>\n <li class=\"title\"><span>Timers</span></li>\n <li>\n Startup time:\n <div><span><%= timers.startup %></span></div>\n </li>\n <li>\n Watching time:\n <div><span><%= timers.watch %></span></div>\n </li>\n <li>\n Pause time:\n <div><span><%= timers.pause %></span></div>\n </li>\n <li>\n Buffering time:\n <div><span><%= timers.buffering %></span></div>\n </li>\n <li>\n Session time:\n <div><span><%= timers.session %></span></div>\n </li>\n <!-- <li>-->\n <!-- Latency:-->\n <!-- <div><span><%= timers.latency %></span></div>-->\n <!-- </li>-->\n </ul>\n\n <ul>\n <li class=\"title\"><span>Extra</span></li>\n <li>\n Playback:\n <div><span><%= extra.playbackName %></span></div>\n </li>\n <li>\n Playback type:\n <div><span><%= extra.playbackType %></span></div>\n </li>\n <li>\n Buffer size:\n <div><span><%= extra.buffersize %></span></div>\n </li>\n <li>\n Video duration:\n <div><span><%= extra.duration %></span></div>\n </li>\n <li>\n Current time:\n <div><span><%= extra.currentTime %></span></div>\n </li>\n <li>\n Bitrate weighted mean:\n <div><span><%= extra.bitrateWeightedMean %></span></div>\n </li>\n <li>\n Bitrate most used:\n <div><span><%= extra.bitrateMostUsed %></span></div>\n </li>\n <li>\n % Watched:\n <div><span><%= extra.watchedPercentage %></span></div>\n </li>\n <li>\n % Buffering:\n <div><span><%= extra.bufferingPercentage %></span></div>\n </li>\n </ul>\n </div>\n <div class=\"speedtest-summary\">\n <div class=\"speedtest-summary-header\">Your internet quality summary</div>\n <div class=\"speedtest-summary-block\">\n <div class=\"speedtest-summary-subblock\">\n <div class=\"speedtest-summary-subblock-content\">\n <div class=\"speedtest-quality\">\n <div class=\"speedtest-quality-header\">VOD: <%= custom.vodQuality %></div>\n <div class=\"speedtest-quality-content\" data-streaming-type=\"vod\">\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"speedtest-summary-subblock\">\n <div class=\"speedtest-summary-subblock-content\">\n <div class=\"speedtest-quality\">\n <div class=\"speedtest-quality-header\">Live: <%= custom.liveQuality %></div>\n <div class=\"speedtest-quality-content\" data-streaming-type=\"live\">\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"speedtest-footer\">\n <!-- <a class=\"speedtest-footer-about-link\" href=\"\" target=\"_blank\">I am not a nerd, what's this all about?</a>-->\n <button class=\"gplayer-lite-btn speedtest-btn speedtest-footer-refresh\" data-refresh-button type=\"button\">\n <svg width=\"12\" height=\"10\" viewBox=\"0 0 12 10\" fill=\"none\">\n <path\n d=\"M6.03968 0.124998C3.64268 0.124998 1.67268 1.9565 1.48068 4.2915H1.00018C0.925833 4.29146 0.853156 4.31353 0.791378 4.35489C0.729601 4.39625 0.681511 4.45503 0.653218 4.52378C0.624925 4.59253 0.617705 4.66814 0.632476 4.74101C0.647248 4.81387 0.683343 4.88069 0.736177 4.933L1.57618 5.766C1.64641 5.83561 1.74129 5.87467 1.84018 5.87467C1.93906 5.87467 2.03395 5.83561 2.10418 5.766L2.94418 4.933C2.99701 4.88069 3.03311 4.81387 3.04788 4.74101C3.06265 4.66814 3.05543 4.59253 3.02714 4.52378C2.99884 4.45503 2.95075 4.39625 2.88898 4.35489C2.8272 4.31353 2.75452 4.29146 2.68018 4.2915H2.23368C2.42368 2.376 4.05268 0.874998 6.03968 0.874998C6.6948 0.873639 7.33932 1.04039 7.91158 1.35931C8.48384 1.67822 8.9647 2.13863 9.30818 2.6965C9.33331 2.73978 9.36686 2.7776 9.40684 2.80771C9.44682 2.83783 9.49243 2.85963 9.54097 2.87184C9.58951 2.88405 9.64001 2.88643 9.68948 2.87881C9.73895 2.8712 9.7864 2.85377 9.82902 2.82753C9.87165 2.80129 9.90859 2.76679 9.93767 2.72605C9.96675 2.68531 9.98739 2.63916 9.99835 2.59032C10.0093 2.54148 10.0104 2.49095 10.0015 2.44168C9.99264 2.39242 9.974 2.34544 9.94668 2.3035C9.53615 1.63664 8.96146 1.08621 8.27752 0.704805C7.59359 0.323402 6.82277 0.123774 6.03968 0.124998ZM10.4207 4.2335C10.3505 4.16419 10.2558 4.12532 10.1572 4.12532C10.0585 4.12532 9.96386 4.16419 9.89368 4.2335L9.05018 5.0665C8.9972 5.11874 8.96096 5.18557 8.94608 5.25847C8.93119 5.33137 8.93833 5.40705 8.96658 5.47588C8.99483 5.54472 9.04292 5.60359 9.10473 5.64501C9.16654 5.68644 9.23927 5.70853 9.31368 5.7085H9.76318C9.57218 7.6235 7.93768 9.125 5.94118 9.125C5.28399 9.12683 4.63729 8.96035 4.06269 8.64141C3.48808 8.32247 3.00473 7.86169 2.65868 7.303C2.63281 7.26107 2.59893 7.22465 2.55899 7.19582C2.51904 7.16699 2.47381 7.14631 2.42587 7.13495C2.37793 7.1236 2.32823 7.1218 2.27959 7.12966C2.23096 7.13752 2.18435 7.15488 2.14243 7.18075C2.05776 7.233 1.99731 7.31674 1.97438 7.41355C1.95146 7.51037 1.96793 7.61233 2.02018 7.697C2.43345 8.36457 3.01076 8.91521 3.69713 9.29647C4.38349 9.67772 5.15604 9.87689 5.94118 9.875C8.34518 9.875 10.3237 8.045 10.5162 5.7085H11.0002C11.0746 5.70853 11.1473 5.68644 11.2091 5.64501C11.2709 5.60359 11.319 5.54472 11.3473 5.47588C11.3755 5.40705 11.3827 5.33137 11.3678 5.25847C11.3529 5.18557 11.3167 5.11874 11.2637 5.0665L10.4207 4.2335Z\"\n fill=\"white\"/>\n </svg>\n Refresh\n </button>\n </div>\n</div>\n";
47136
+ const pluginHtml$4 = "<% general = metrics.general %>\n<% counters = metrics.counters %>\n<% timers = metrics.timers %>\n<% extra = metrics.extra %>\n<% custom = metrics.custom %>\n\n<div class=\"stats-box\">\n <div class=\"stats-box-top\">\n <a class=\"close-button gplayer-lite-btn\" data-close-button>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <g clip-path=\"url(#clip0_184_1489)\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M7.41376 6.00013L13.7068 -0.292872C14.0978 -0.683872 14.0978 -1.31587 13.7068 -1.70687C13.3158 -2.09787 12.6838 -2.09787 12.2928 -1.70687L5.99976 4.58613L-0.293238 -1.70687C-0.684238 -2.09787 -1.31624 -2.09787 -1.70724 -1.70687C-2.09824 -1.31587 -2.09824 -0.683872 -1.70724 -0.292872L4.58576 6.00013L-1.70724 12.2931C-2.09824 12.6841 -2.09824 13.3161 -1.70724 13.7071C-1.51224 13.9021 -1.25624 14.0001 -1.00024 14.0001C-0.744238 14.0001 -0.488238 13.9021 -0.293238 13.7071L5.99976 7.41413L12.2928 13.7071C12.4878 13.9021 12.7438 14.0001 12.9998 14.0001C13.2558 14.0001 13.5118 13.9021 13.7068 13.7071C14.0978 13.3161 14.0978 12.6841 13.7068 12.2931L7.41376 6.00013Z\"\n fill=\"white\"/>\n </g>\n <defs>\n <clipPath id=\"clip0_184_1489\">\n <rect width=\"12\" height=\"12\" fill=\"white\"/>\n </clipPath>\n </defs>\n </svg>\n </a>\n </div>\n <div class=\"stats-box-main\">\n <ul>\n <li class=\"title\"><span>General</span></li>\n <li>\n Display resolution:\n <div><span><%= general.displayResolution %></span></div>\n </li>\n <li>\n Volume:\n <div><span><%= general.volume %></span></div>\n </li>\n <li>\n Connection speed:\n <div><span id=\"dlText\"><%= custom.connectionSpeed %></span> Mbps</div>\n </li>\n <li class=\"canvas-wrapper\">\n <canvas id=\"speedTestCanvas\" width=\"190\" height=\"20\"></canvas>\n </li>\n <li>\n Ping:\n <div><span id=\"pingText\"><%= custom.ping %></span> ms</div>\n </li>\n <li>\n Jitter:\n <div><span id=\"jitterText\"><%= custom.jitter %></span> ms</div>\n </li>\n </ul>\n\n <ul>\n <li class=\"title\"><span>Counters</span></li>\n <li>\n Plays:\n <div><span><%= counters.play %></span></div>\n </li>\n <li>\n Pauses:\n <div><span><%= counters.pause %></span></div>\n </li>\n <li>\n Errors:\n <div><span><%= counters.error %></span></div>\n </li>\n <li>\n Bufferings:\n <div><span><%= counters.buffering %></span></div>\n </li>\n <li>\n Decoded frames:\n <div><span><%= counters.decodedFrames %></span></div>\n </li>\n <li>\n Dropped frames:\n <div><span><%= counters.droppedFrames %></span></div>\n </li>\n <li>\n Frames per second:\n <div><span><%= counters.fps %></span></div>\n </li>\n <li>\n Bitrate changes:\n <div><span><%= counters.changeLevel %></span></div>\n </li>\n <li>\n Seeks:\n <div><span><%= counters.seek %></span></div>\n </li>\n <li>\n Fullscreen:\n <div><span><%= counters.fullscreen %></span></div>\n </li>\n <li>\n DVR seeks:\n <div><span><%= counters.dvrUsage %></span></div>\n </li>\n </ul>\n\n <ul>\n <li class=\"title\"><span>Timers</span></li>\n <li>\n Startup time:\n <div><span><%= timers.startup %></span></div>\n </li>\n <li>\n Watching time:\n <div><span><%= timers.watch %></span></div>\n </li>\n <li>\n Pause time:\n <div><span><%= timers.pause %></span></div>\n </li>\n <li>\n Buffering time:\n <div><span><%= timers.buffering %></span></div>\n </li>\n <li>\n Session time:\n <div><span><%= timers.session %></span></div>\n </li>\n <!-- <li>-->\n <!-- Latency:-->\n <!-- <div><span><%= timers.latency %></span></div>-->\n <!-- </li>-->\n </ul>\n\n <ul>\n <li class=\"title\"><span>Extra</span></li>\n <li>\n Playback:\n <div><span><%= extra.playbackName %></span></div>\n </li>\n <li>\n Playback type:\n <div><span><%= extra.playbackType %></span></div>\n </li>\n <li>\n Buffer size:\n <div><span><%= extra.buffersize %></span></div>\n </li>\n <li>\n Video duration:\n <div><span><%= extra.duration %></span></div>\n </li>\n <li>\n Current time:\n <div><span><%= extra.currentTime %></span></div>\n </li>\n <li>\n Bitrate weighted mean:\n <div><span><%= extra.bitrateWeightedMean %></span></div>\n </li>\n <li>\n Bitrate most used:\n <div><span><%= extra.bitrateMostUsed %></span></div>\n </li>\n <li>\n % Watched:\n <div><span><%= extra.watchedPercentage %></span></div>\n </li>\n <li>\n % Buffering:\n <div><span><%= extra.bufferingPercentage %></span></div>\n </li>\n </ul>\n </div>\n <div class=\"speedtest-summary\">\n <div class=\"speedtest-summary-header\">Your internet quality summary</div>\n <div class=\"speedtest-summary-block\">\n <div class=\"speedtest-summary-subblock\">\n <div class=\"speedtest-summary-subblock-content\">\n <div class=\"speedtest-quality\">\n <div class=\"speedtest-quality-header\">VOD: <%= custom.vodQuality %></div>\n <div class=\"speedtest-quality-content\" data-streaming-type=\"vod\">\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"speedtest-summary-subblock\">\n <div class=\"speedtest-summary-subblock-content\">\n <div class=\"speedtest-quality\">\n <div class=\"speedtest-quality-header\">Live: <%= custom.liveQuality %></div>\n <div class=\"speedtest-quality-content\" data-streaming-type=\"live\">\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n <div class=\"speedtest-quality-content-item\"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"speedtest-footer\">\n <!-- <a class=\"speedtest-footer-about-link\" href=\"\" target=\"_blank\">I am not a nerd, what's this all about?</a>-->\n <button class=\"gplayer-lite-btn speedtest-btn speedtest-footer-refresh\" data-refresh-button type=\"button\">\n <svg width=\"12\" height=\"10\" viewBox=\"0 0 12 10\" fill=\"none\">\n <path\n d=\"M6.03968 0.124998C3.64268 0.124998 1.67268 1.9565 1.48068 4.2915H1.00018C0.925833 4.29146 0.853156 4.31353 0.791378 4.35489C0.729601 4.39625 0.681511 4.45503 0.653218 4.52378C0.624925 4.59253 0.617705 4.66814 0.632476 4.74101C0.647248 4.81387 0.683343 4.88069 0.736177 4.933L1.57618 5.766C1.64641 5.83561 1.74129 5.87467 1.84018 5.87467C1.93906 5.87467 2.03395 5.83561 2.10418 5.766L2.94418 4.933C2.99701 4.88069 3.03311 4.81387 3.04788 4.74101C3.06265 4.66814 3.05543 4.59253 3.02714 4.52378C2.99884 4.45503 2.95075 4.39625 2.88898 4.35489C2.8272 4.31353 2.75452 4.29146 2.68018 4.2915H2.23368C2.42368 2.376 4.05268 0.874998 6.03968 0.874998C6.6948 0.873639 7.33932 1.04039 7.91158 1.35931C8.48384 1.67822 8.9647 2.13863 9.30818 2.6965C9.33331 2.73978 9.36686 2.7776 9.40684 2.80771C9.44682 2.83783 9.49243 2.85963 9.54097 2.87184C9.58951 2.88405 9.64001 2.88643 9.68948 2.87881C9.73895 2.8712 9.7864 2.85377 9.82902 2.82753C9.87165 2.80129 9.90859 2.76679 9.93767 2.72605C9.96675 2.68531 9.98739 2.63916 9.99835 2.59032C10.0093 2.54148 10.0104 2.49095 10.0015 2.44168C9.99264 2.39242 9.974 2.34544 9.94668 2.3035C9.53615 1.63664 8.96146 1.08621 8.27752 0.704805C7.59359 0.323402 6.82277 0.123774 6.03968 0.124998ZM10.4207 4.2335C10.3505 4.16419 10.2558 4.12532 10.1572 4.12532C10.0585 4.12532 9.96386 4.16419 9.89368 4.2335L9.05018 5.0665C8.9972 5.11874 8.96096 5.18557 8.94608 5.25847C8.93119 5.33137 8.93833 5.40705 8.96658 5.47588C8.99483 5.54472 9.04292 5.60359 9.10473 5.64501C9.16654 5.68644 9.23927 5.70853 9.31368 5.7085H9.76318C9.57218 7.6235 7.93768 9.125 5.94118 9.125C5.28399 9.12683 4.63729 8.96035 4.06269 8.64141C3.48808 8.32247 3.00473 7.86169 2.65868 7.303C2.63281 7.26107 2.59893 7.22465 2.55899 7.19582C2.51904 7.16699 2.47381 7.14631 2.42587 7.13495C2.37793 7.1236 2.32823 7.1218 2.27959 7.12966C2.23096 7.13752 2.18435 7.15488 2.14243 7.18075C2.05776 7.233 1.99731 7.31674 1.97438 7.41355C1.95146 7.51037 1.96793 7.61233 2.02018 7.697C2.43345 8.36457 3.01076 8.91521 3.69713 9.29647C4.38349 9.67772 5.15604 9.87689 5.94118 9.875C8.34518 9.875 10.3237 8.045 10.5162 5.7085H11.0002C11.0746 5.70853 11.1473 5.68644 11.2091 5.64501C11.2709 5.60359 11.319 5.54472 11.3473 5.47588C11.3755 5.40705 11.3827 5.33137 11.3678 5.25847C11.3529 5.18557 11.3167 5.11874 11.2637 5.0665L10.4207 4.2335Z\"\n fill=\"white\"/>\n </svg>\n Refresh\n </button>\n </div>\n</div>\n";
47118
47137
 
47119
47138
  const buttonHtml$3 = "<button class='nerd-button gplayer-lite-btn gcore-skin-text-color gear-option'>\n <span class=\"stats-icon\"></span>\n <span>Statistics</span>\n</button>\n";
47120
47139
 
@@ -47189,7 +47208,7 @@ const drawSummary = (customMetrics, vodContainer, liveContainer) => {
47189
47208
  };
47190
47209
  // const T = 'plugins.clappr_nerd_stats';
47191
47210
  /**
47192
- * Displays useful network-related statistics.
47211
+ * PLUGIN that displays useful network-related statistics.
47193
47212
  * @beta
47194
47213
  *
47195
47214
  * @remarks
@@ -47229,7 +47248,7 @@ class ClapprNerdStats extends UICorePlugin {
47229
47248
  get supportedVersion() {
47230
47249
  return { min: CLAPPR_VERSION };
47231
47250
  }
47232
- static template = tmpl(pluginHtml$5);
47251
+ static template = tmpl(pluginHtml$4);
47233
47252
  /**
47234
47253
  * @internal
47235
47254
  */
@@ -47283,7 +47302,7 @@ class ClapprNerdStats extends UICorePlugin {
47283
47302
  const mediaControl = this.core.getPlugin('media_control');
47284
47303
  assert(mediaControl, 'media_control plugin is required');
47285
47304
  this.listenToOnce(this.core, Events$1.CORE_READY, this.init);
47286
- this.listenTo(mediaControl, GearEvents.MEDIACONTROL_GEAR_RENDERED, this.addToBottomGear);
47305
+ this.listenTo(mediaControl, MediaControlEvents.MEDIACONTROL_GEAR_RENDERED, this.addToBottomGear);
47287
47306
  }
47288
47307
  init() {
47289
47308
  this.container = this.core.activeContainer;
@@ -47449,7 +47468,7 @@ function newMetrics() {
47449
47468
  // TODO: fix
47450
47469
  const updateMetrics = () => { };
47451
47470
  /**
47452
- * Collects useful statistics about playback performance.
47471
+ * PLIGIN that collects useful statistics about playback performance.
47453
47472
  * @beta
47454
47473
  * @remarks
47455
47474
  * This plugin does not render anything and is supposed to be extended or used together with other plugins that actually render something.
@@ -47512,9 +47531,10 @@ class ClapprStats extends ContainerPlugin {
47512
47531
  }
47513
47532
  /**
47514
47533
  * Registers a callback to receive the metrics.
47515
- * @param updateMetricsFn
47534
+ * @param updateMetricsFn - The callback to receive the metrics
47516
47535
  */
47517
47536
  setUpdateMetrics(updateMetricsFn) {
47537
+ // TODO use events instead
47518
47538
  this.updateFn = updateMetricsFn;
47519
47539
  }
47520
47540
  _defaultReport(metrics) {
@@ -47562,7 +47582,7 @@ class ClapprStats extends ContainerPlugin {
47562
47582
  }
47563
47583
  /**
47564
47584
  * Returns the collected metrics.
47565
- * @returns The collected metrics
47585
+ * @returns Currently collected metrics
47566
47586
  */
47567
47587
  exportMetrics() {
47568
47588
  return structuredClone(this.metrics);
@@ -47804,7 +47824,7 @@ class ClapprStats extends ContainerPlugin {
47804
47824
  //Copyright 2014 Globo.com Player authors. All rights reserved.
47805
47825
  // Use of this source code is governed by a BSD-style
47806
47826
  // license that can be found at https://github.com/clappr/clappr-plugins/blob/master/LICENSE.
47807
- const T$a = 'plugins.click_to_pause_custom';
47827
+ const T$c = 'plugins.click_to_pause_custom';
47808
47828
  /**
47809
47829
  * Adds a behavior of toggling the playback state on click over the container
47810
47830
  * @beta
@@ -47834,7 +47854,7 @@ class ClickToPause extends ContainerPlugin {
47834
47854
  click() {
47835
47855
  const isLivePlayback = this.container.getPlaybackType() === Playback.LIVE;
47836
47856
  const isDvrEnabled = this.container.isDvrEnabled();
47837
- trace(`${T$a} click`, {
47857
+ trace(`${T$c} click`, {
47838
47858
  isLivePlayback,
47839
47859
  isDvrEnabled,
47840
47860
  });
@@ -47852,7 +47872,7 @@ class ClickToPause extends ContainerPlugin {
47852
47872
  settingsUpdate() {
47853
47873
  const isLivePlayback = this.container.getPlaybackType() === Playback.LIVE;
47854
47874
  const pointerEnabled = !isLivePlayback || this.container.isDvrEnabled();
47855
- trace(`${T$a} settingsUpdate`, {
47875
+ trace(`${T$c} settingsUpdate`, {
47856
47876
  isLivePlayback,
47857
47877
  pointerEnabled,
47858
47878
  });
@@ -47881,7 +47901,7 @@ class ClickToPause extends ContainerPlugin {
47881
47901
  }
47882
47902
 
47883
47903
  /**
47884
- * Adds a behavior of showing a text over the seekbar to indicate the current clip.
47904
+ * PLUGIN that shows text over the seekbar to indicate the current clip.
47885
47905
  * @beta
47886
47906
  * @remarks
47887
47907
  * Depends on:
@@ -48148,8 +48168,10 @@ class ContextMenu extends UIContainerPlugin {
48148
48168
 
48149
48169
  const dvrHTML = "<div class=\"live-info\"><%= live %></div>\n<button type=\"button\" class=\"live-button\" aria-label=\"<%= backToLive %>\"><%= backToLive %></button>\n";
48150
48170
 
48171
+ const T$b = 'plugins.dvr_controls';
48151
48172
  /**
48152
- * Adds the DVR controls to the media control UI
48173
+ * PLUGIN that adds the DVR controls to the media control UI
48174
+ *
48153
48175
  * @beta
48154
48176
  *
48155
48177
  * @remarks
@@ -48157,7 +48179,7 @@ const dvrHTML = "<div class=\"live-info\"><%= live %></div>\n<button type=\"butt
48157
48179
  *
48158
48180
  * - {@link MediaControl}
48159
48181
  *
48160
- * The plugin renders the live stream indicator and the DVR seek bar, if DVR is enabled, in the media control UI.
48182
+ * The plugin renders live stream indicator and the DVR seek bar, if DVR is enabled, in the media control UI.
48161
48183
  */
48162
48184
  class DvrControls extends UICorePlugin {
48163
48185
  static template = tmpl(dvrHTML);
@@ -48178,7 +48200,7 @@ class DvrControls extends UICorePlugin {
48178
48200
  */
48179
48201
  get events() {
48180
48202
  return {
48181
- 'click .live-button': 'click'
48203
+ 'click .live-button': 'click',
48182
48204
  };
48183
48205
  }
48184
48206
  /**
@@ -48186,8 +48208,8 @@ class DvrControls extends UICorePlugin {
48186
48208
  */
48187
48209
  get attributes() {
48188
48210
  return {
48189
- 'class': 'dvr-controls',
48190
- 'data-dvr-controls': ''
48211
+ class: 'dvr-controls',
48212
+ 'data-dvr-controls': '',
48191
48213
  };
48192
48214
  }
48193
48215
  constructor(core) {
@@ -48206,23 +48228,25 @@ class DvrControls extends UICorePlugin {
48206
48228
  }
48207
48229
  bindContainerEvents() {
48208
48230
  this.listenToOnce(this.core.activeContainer, Events$1.CONTAINER_TIMEUPDATE, this.render);
48209
- this.listenTo(this.core.activeContainer, Events$1.CONTAINER_PLAYBACKDVRSTATECHANGED, this.dvrChanged);
48231
+ this.listenTo(this.core.activeContainer, Events$1.CONTAINER_PLAYBACKDVRSTATECHANGED, this.onDvrChanged);
48210
48232
  }
48211
- dvrChanged(dvrEnabled) {
48233
+ onDvrChanged(dvrEnabled) {
48234
+ trace(`${T$b} onDvrChanged`, {
48235
+ dvrEnabled,
48236
+ });
48212
48237
  if (this.core.getPlaybackType() !== Playback.LIVE) {
48213
48238
  return;
48214
48239
  }
48215
48240
  this.settingsUpdate();
48216
48241
  this.core.mediaControl.$el.addClass('live');
48217
48242
  if (dvrEnabled) {
48218
- this.core.mediaControl.$playbackRate.removeClass('playbackrate-enable');
48243
+ // TODO
48219
48244
  this.core.mediaControl.$el
48220
48245
  .addClass('dvr')
48221
48246
  .find('.media-control-indicator[data-position], .media-control-indicator[data-duration]')
48222
48247
  .hide();
48223
48248
  }
48224
48249
  else {
48225
- this.core.mediaControl.$playbackRate.addClass('playbackrate-enable');
48226
48250
  this.core.mediaControl.$el.removeClass('dvr');
48227
48251
  }
48228
48252
  }
@@ -48247,24 +48271,31 @@ class DvrControls extends UICorePlugin {
48247
48271
  this.bindEvents();
48248
48272
  }
48249
48273
  shouldRender() {
48250
- const useDvrControls = this.core.options.useDvrControls === undefined || !!this.core.options.useDvrControls;
48274
+ const useDvrControls = this.core.options.useDvrControls === undefined ||
48275
+ !!this.core.options.useDvrControls;
48251
48276
  return useDvrControls && this.core.getPlaybackType() === Playback.LIVE;
48252
48277
  }
48253
48278
  /**
48254
48279
  * @internal
48255
48280
  */
48256
48281
  render() {
48282
+ trace(`${T$b} render`, {
48283
+ dvrEnabled: this.core.activePlayback?.dvrEnabled,
48284
+ });
48285
+ if (!this.shouldRender()) {
48286
+ return this;
48287
+ }
48257
48288
  this.$el.html(DvrControls.template({
48258
48289
  live: this.core.i18n.t('live'),
48259
- backToLive: this.core.i18n.t('back_to_live')
48290
+ backToLive: this.core.i18n.t('back_to_live'),
48260
48291
  }));
48261
- if (this.shouldRender()) {
48262
- const mediaControl = this.core.getPlugin('media_control');
48263
- assert(mediaControl, 'media_control plugin is required');
48264
- // TODO don't tap into the $el directly
48265
- mediaControl.$el.addClass('live');
48266
- mediaControl.$('.media-control-left-panel[data-media-control]').append(this.$el);
48267
- }
48292
+ const mediaControl = this.core.getPlugin('media_control');
48293
+ assert(mediaControl, 'media_control plugin is required');
48294
+ // TODO don't tap into the $el directly
48295
+ mediaControl.$el.addClass('live');
48296
+ mediaControl
48297
+ .$('.media-control-left-panel[data-media-control]')
48298
+ .append(this.$el);
48268
48299
  return this;
48269
48300
  }
48270
48301
  }
@@ -48273,9 +48304,9 @@ const reloadIcon = "<svg fill=\"#FFFFFF\" height=\"24\" viewBox=\"0 0 24 24\" wi
48273
48304
 
48274
48305
  const templateHtml = "<div class=\"player-error-screen__content\" data-error-screen>\n <% if (icon) { %>\n <div class=\"player-error-screen__icon\" data-error-screen><%= icon %></div>\n <% } %>\n <div class=\"player-error-screen__title\" data-error-screen><%= title %></div>\n <% if (message) { %>\n <div class=\"player-error-screen__message\" data-error-screen><%= message %></div>\n <% } %>\n <% if (code) { %>\n <div class=\"player-error-screen__code\" data-error-screen>Error code: <%= code %></div>\n <% } %>\n <% if (reloadIcon) { %>\n <div class=\"player-error-screen__reload\" data-error-screen><%= reloadIcon %></div>\n <% } %>\n</div>\n";
48275
48306
 
48276
- const T$9 = 'plugins.error_screen';
48307
+ const T$a = 'plugins.error_screen';
48277
48308
  /**
48278
- * Displays an error nicely in the overlay on top of the player.
48309
+ * PLUGIN that displays errors nicely in the overlay on top of the player.
48279
48310
  * @beta
48280
48311
  */
48281
48312
  class ErrorScreen extends UICorePlugin {
@@ -48310,11 +48341,11 @@ class ErrorScreen extends UICorePlugin {
48310
48341
  this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChanged);
48311
48342
  }
48312
48343
  onPlay() {
48313
- trace(`${T$9} onPlay`);
48344
+ trace(`${T$a} onPlay`);
48314
48345
  this.unmount();
48315
48346
  }
48316
48347
  unmount() {
48317
- trace(`${T$9} unmount`);
48348
+ trace(`${T$a} unmount`);
48318
48349
  this.err = null;
48319
48350
  this.$el.remove();
48320
48351
  }
@@ -48336,7 +48367,7 @@ class ErrorScreen extends UICorePlugin {
48336
48367
  }, 0);
48337
48368
  }
48338
48369
  onActiveContainerChanged() {
48339
- trace(`${T$9} onActiveContainerChanged`, {
48370
+ trace(`${T$a} onActiveContainerChanged`, {
48340
48371
  reloading: this.core.options.reloading,
48341
48372
  });
48342
48373
  this.err = null;
@@ -48352,7 +48383,7 @@ class ErrorScreen extends UICorePlugin {
48352
48383
  }
48353
48384
  }
48354
48385
  onError(err) {
48355
- trace(`${T$9} onError`, { err });
48386
+ trace(`${T$a} onError`, { err });
48356
48387
  if (err.UI) {
48357
48388
  if (this.err) {
48358
48389
  this.unmount();
@@ -48620,10 +48651,10 @@ const arrowLeftIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fil
48620
48651
 
48621
48652
  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";
48622
48653
 
48623
- const T$8 = 'plugins.level_selector';
48654
+ const T$9 = 'plugins.level_selector';
48624
48655
  const VERSION$4 = '2.19.4';
48625
48656
  /**
48626
- * A {@link MediaControl | media control} plugin that provides a UI to control the quality level of the playback.
48657
+ * PLUGIN that provides a UI to select the desired quality level of the playback.
48627
48658
  * @beta
48628
48659
  *
48629
48660
  * @remarks
@@ -48633,9 +48664,7 @@ const VERSION$4 = '2.19.4';
48633
48664
  *
48634
48665
  * - {@link BottomGear}
48635
48666
  *
48636
- * The plugin is rendered as an item in the gear menu.
48637
- *
48638
- * When clicked, it shows a list of quality levels to choose from.
48667
+ * The plugin is rendered as an item in the gear menu, which, when clicked, shows a list of quality levels to choose from.
48639
48668
  *
48640
48669
  * Configuration options - {@link LevelSelectorPluginSettings}
48641
48670
  *
@@ -48697,9 +48726,18 @@ class LevelSelector extends UICorePlugin {
48697
48726
  * @internal
48698
48727
  */
48699
48728
  bindEvents() {
48729
+ this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
48730
+ this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, this.bindPlaybackEvents);
48731
+ }
48732
+ onCoreReady() {
48733
+ trace(`${T$9} onCoreReady`);
48700
48734
  const mediaControl = this.core.getPlugin('media_control');
48701
48735
  assert(mediaControl, 'media_control plugin is required');
48702
- this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, this.bindPlaybackEvents);
48736
+ this.listenTo(mediaControl, MediaControlEvents.MEDIACONTROL_GEAR_RENDERED, this.onGearRendered);
48737
+ }
48738
+ onGearRendered() {
48739
+ trace(`${T$9} onGearRendered`);
48740
+ this.deferRender();
48703
48741
  }
48704
48742
  bindPlaybackEvents() {
48705
48743
  this.removeAuto = false;
@@ -48719,9 +48757,9 @@ class LevelSelector extends UICorePlugin {
48719
48757
  }
48720
48758
  }
48721
48759
  onStop() {
48722
- trace(`${T$8} onStop`);
48760
+ trace(`${T$9} onStop`);
48723
48761
  this.listenToOnce(this.core.activePlayback, Events$1.PLAYBACK_PLAY, () => {
48724
- trace(`${T$8} on PLAYBACK_PLAY after stop`, {
48762
+ trace(`${T$9} on PLAYBACK_PLAY after stop`, {
48725
48763
  selectedLevelId: this.selectedLevelId,
48726
48764
  });
48727
48765
  if (this.core.activePlayback.getPlaybackType() === 'live') {
@@ -48764,7 +48802,7 @@ class LevelSelector extends UICorePlugin {
48764
48802
  this.$el.html(html);
48765
48803
  const gear = this.core.getPlugin('bottom_gear');
48766
48804
  if (!gear) {
48767
- trace(`${T$8} renderButton: bottom_gear plugin not found`);
48805
+ trace(`${T$9} renderButton: bottom_gear plugin not found`);
48768
48806
  }
48769
48807
  gear?.getElement('quality')?.html(this.el);
48770
48808
  }
@@ -48780,7 +48818,7 @@ class LevelSelector extends UICorePlugin {
48780
48818
  });
48781
48819
  this.$el.html(html);
48782
48820
  const gear = this.core.getPlugin('bottom_gear');
48783
- trace(`${T$8} renderDropdown: bottom_gear plugin not found`);
48821
+ trace(`${T$9} renderDropdown: bottom_gear plugin not found`);
48784
48822
  gear?.setContent(this.el);
48785
48823
  }
48786
48824
  get maxLevel() {
@@ -48821,13 +48859,14 @@ class LevelSelector extends UICorePlugin {
48821
48859
  return false;
48822
48860
  }
48823
48861
  goBack() {
48824
- trace(`${T$8} goBack`);
48862
+ trace(`${T$9} goBack`);
48825
48863
  this.isOpen = false;
48826
- this.core.trigger('gear:refresh');
48827
- this.deferRender();
48864
+ setTimeout(() => {
48865
+ this.core.getPlugin('bottom_gear').refresh();
48866
+ }, 0);
48828
48867
  }
48829
48868
  setLevel(index) {
48830
- trace(`${T$8} setIndexLevel`, { index });
48869
+ trace(`${T$9} setIndexLevel`, { index });
48831
48870
  this.selectedLevelId = index;
48832
48871
  if (!this.core.activePlayback) {
48833
48872
  return;
@@ -48845,7 +48884,7 @@ class LevelSelector extends UICorePlugin {
48845
48884
  this.deferRender();
48846
48885
  }
48847
48886
  onShowLevelSelectMenu() {
48848
- trace(`${T$8} onShowLevelSelectMenu`);
48887
+ trace(`${T$9} onShowLevelSelectMenu`);
48849
48888
  this.isOpen = true;
48850
48889
  this.renderDropdown();
48851
48890
  this.highlightCurrentLevel();
@@ -48881,11 +48920,11 @@ class LevelSelector extends UICorePlugin {
48881
48920
  return this.levelLabels[index] ?? formatLevelLabel(this.levels[index]);
48882
48921
  }
48883
48922
  updateCurrentLevel(info) {
48884
- trace(`${T$8} updateCurrentLevel`, { info });
48923
+ trace(`${T$9} updateCurrentLevel`, { info });
48885
48924
  this.highlightCurrentLevel();
48886
48925
  }
48887
48926
  highlightCurrentLevel() {
48888
- trace(`${T$8} highlightCurrentLevel`, {
48927
+ trace(`${T$9} highlightCurrentLevel`, {
48889
48928
  selectedLevelId: this.selectedLevelId,
48890
48929
  });
48891
48930
  this.allLevelElements().removeClass('current');
@@ -49126,7 +49165,7 @@ class Logo extends UIContainerPlugin {
49126
49165
  }
49127
49166
  }
49128
49167
 
49129
- const pluginHtml$4 = "<button data-multicamera-button class='gcore-skin-button-color'>\n <span class=\"multicamera-icon\"></span>\n</button>\n\n<ul class=\"gcore-skin-bg-color\">\n <% for (var i = 0; i < streams.length; i++) { %>\n <% if(!streams[i].live && multisources_mode === 'only_live') { %>\n <% continue; %>\n <% } %>\n <li>\n <div class=\"multicamera-item\" data-multicamera-selector-live=\"<%= streams[i].live %>\"\n data-multicamera-selector-select=\"<%= streams[i].id %>\">\n <div class=\"multicamera-screenshot\">\n <% if (streams[i].screenshot) { %>\n <img src=\"<%= streams[i].screenshot %>\" alt=\"<%= streams[i].title %>\"/>\n <% } %>\n </div>\n <div class=\"multicamera-text gcore-skin-text-color\">\n <% if (streams[i].title) { %>\n <div class=\"multicamera-title gcore-skin-text-color\"><%= streams[i].title %></div>\n <% } %>\n <% if (streams[i].description) { %>\n <div class=\"multicamera-description gcore-skin-text-color\"><%= streams[i].description %></div>\n <% } %>\n </div>\n </div>\n </li>\n <% } %>\n</ul>\n";
49168
+ const pluginHtml$3 = "<button data-multicamera-button class='gcore-skin-button-color'>\n <span class=\"multicamera-icon\"></span>\n</button>\n\n<ul class=\"gcore-skin-bg-color\">\n <% for (var i = 0; i < streams.length; i++) { %>\n <% if(!streams[i].live && multisources_mode === 'only_live') { %>\n <% continue; %>\n <% } %>\n <li>\n <div class=\"multicamera-item\" data-multicamera-selector-live=\"<%= streams[i].live %>\"\n data-multicamera-selector-select=\"<%= streams[i].id %>\">\n <div class=\"multicamera-screenshot\">\n <% if (streams[i].screenshot) { %>\n <img src=\"<%= streams[i].screenshot %>\" alt=\"<%= streams[i].title %>\"/>\n <% } %>\n </div>\n <div class=\"multicamera-text gcore-skin-text-color\">\n <% if (streams[i].title) { %>\n <div class=\"multicamera-title gcore-skin-text-color\"><%= streams[i].title %></div>\n <% } %>\n <% if (streams[i].description) { %>\n <div class=\"multicamera-description gcore-skin-text-color\"><%= streams[i].description %></div>\n <% } %>\n </div>\n </div>\n </li>\n <% } %>\n</ul>\n";
49130
49169
 
49131
49170
  const streamsIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"20\" viewBox=\"0 0 24 20\">\n <path fill=\"#FFF\" fill-rule=\"nonzero\" d=\"M24 1.5v13a1.5 1.5 0 0 1-1.5 1.5h-1a.5.5 0 0 1-.5-.5v-10A2.5 2.5 0 0 0 18.5 3h-14a.5.5 0 0 1-.5-.5v-1A1.5 1.5 0 0 1 5.5 0h17A1.5 1.5 0 0 1 24 1.5M12.724 12.447l-5 2.5a.505.505 0 0 1-.487-.021A.503.503 0 0 1 7 14.5v-5c0-.173.09-.334.237-.426a.505.505 0 0 1 .487-.021l5 2.5a.5.5 0 0 1 0 .894M18.5 4h-17C.673 4 0 4.673 0 5.5v13c0 .827.673 1.5 1.5 1.5h17c.827 0 1.5-.673 1.5-1.5v-13c0-.827-.673-1.5-1.5-1.5\"/>\n</svg>\n";
49132
49171
 
@@ -49135,9 +49174,9 @@ const streamsMomentoIcon = "<svg id=\"Слой_1\" data-name=\"Слой 1\" xmln
49135
49174
  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";
49136
49175
 
49137
49176
  const VERSION$3 = '0.0.1';
49138
- const T$7 = 'plugins.multicamera';
49177
+ const T$8 = 'plugins.multicamera';
49139
49178
  /**
49140
- * The plugin adds support for loading multiple streams and switching between them using the media control UI.
49179
+ * PLUGIN that adds support for loading multiple streams and switching between them using the media control UI.
49141
49180
  * @beta
49142
49181
  */
49143
49182
  class MultiCamera extends UICorePlugin {
@@ -49156,7 +49195,7 @@ class MultiCamera extends UICorePlugin {
49156
49195
  return VERSION$3;
49157
49196
  }
49158
49197
  get template() {
49159
- return tmpl(pluginHtml$4);
49198
+ return tmpl(pluginHtml$3);
49160
49199
  }
49161
49200
  get attributes() {
49162
49201
  return {
@@ -49281,7 +49320,7 @@ class MultiCamera extends UICorePlugin {
49281
49320
  }
49282
49321
  onCameraSelect(event) {
49283
49322
  const value = event.currentTarget.dataset.multicameraSelectorSelect;
49284
- trace(`${T$7} onCameraSelect`, { value });
49323
+ trace(`${T$8} onCameraSelect`, { value });
49285
49324
  if (value !== undefined) {
49286
49325
  this.changeById(parseInt(value, 10));
49287
49326
  }
@@ -49407,13 +49446,13 @@ class MultiCamera extends UICorePlugin {
49407
49446
  }
49408
49447
  }
49409
49448
  changeById(id) {
49410
- trace(`${T$7} changeById`, { id });
49449
+ trace(`${T$8} changeById`, { id });
49411
49450
  queueMicrotask(() => {
49412
49451
  const playbackOptions = this.core.options.playback || {};
49413
49452
  // TODO figure out what this does
49414
49453
  playbackOptions.recycleVideo = Browser.isMobile;
49415
49454
  this.currentCamera = this.findElementById(id) ?? null;
49416
- trace(`${T$7} changeById`, { id, currentCamera: this.currentCamera, multicamera: this.multicamera });
49455
+ trace(`${T$8} changeById`, { id, currentCamera: this.currentCamera, multicamera: this.multicamera });
49417
49456
  if (!this.currentCamera) {
49418
49457
  return;
49419
49458
  }
@@ -49430,7 +49469,7 @@ class MultiCamera extends UICorePlugin {
49430
49469
  // TODO remove?
49431
49470
  // for html5 playback:
49432
49471
  this.options.dvrEnabled = this.currentCamera.dvr;
49433
- trace(`${T$7} changeById`, { currentCamera: this.currentCamera });
49472
+ trace(`${T$8} changeById`, { currentCamera: this.currentCamera });
49434
49473
  // TODO
49435
49474
  this.core.configure({
49436
49475
  playback: playbackOptions,
@@ -49488,7 +49527,7 @@ const pipIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"no
49488
49527
  const buttonHtml$1 = "<button class=\"gplayer-lite-btn gcore-skin-button-color\">\n <span><%= pipIcon %></span>\n</button>\n";
49489
49528
 
49490
49529
  const VERSION$2 = '0.0.1';
49491
- const T$6 = `plugins.pip`;
49530
+ const T$7 = `plugins.pip`;
49492
49531
  /**
49493
49532
  * Enables picture in picture mode.
49494
49533
  * @beta
@@ -49536,7 +49575,7 @@ class PictureInPicture extends UICorePlugin {
49536
49575
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.render);
49537
49576
  }
49538
49577
  isPiPSupported() {
49539
- trace(`${T$6} isPiPSupported`, {
49578
+ trace(`${T$7} isPiPSupported`, {
49540
49579
  pictureInPictureEnabled: document.pictureInPictureEnabled,
49541
49580
  requestPictureInPicture: HTMLVideoElement.prototype.requestPictureInPicture,
49542
49581
  });
@@ -49558,7 +49597,7 @@ class PictureInPicture extends UICorePlugin {
49558
49597
  return this;
49559
49598
  }
49560
49599
  togglePictureInPicture() {
49561
- trace(`${T$6} togglePictureInPicture`);
49600
+ trace(`${T$7} togglePictureInPicture`);
49562
49601
  if (this.videoElement !== document.pictureInPictureElement) {
49563
49602
  this.requestPictureInPicture();
49564
49603
  }
@@ -49567,19 +49606,17 @@ class PictureInPicture extends UICorePlugin {
49567
49606
  }
49568
49607
  }
49569
49608
  requestPictureInPicture() {
49570
- trace(`${T$6} requestPictureInPicture`, {
49609
+ trace(`${T$7} requestPictureInPicture`, {
49571
49610
  videoElement: !!this.videoElement,
49572
49611
  });
49573
49612
  this.videoElement.requestPictureInPicture();
49574
49613
  }
49575
49614
  exitPictureInPicture() {
49576
- trace(`${T$6} exitPictureInPicture`);
49615
+ trace(`${T$7} exitPictureInPicture`);
49577
49616
  document.exitPictureInPicture();
49578
49617
  }
49579
49618
  }
49580
49619
 
49581
- const pluginHtml$3 = "<button class=\"gcore-skin-button-color\" data-playback-rate-button>\n <span><%= title %></span>\n</button>\n<ul>\n <% for (var i = 0; i < playbackRates.length; i++) { %>\n <li data-playback-rate-select=\"<%= playbackRates[i].value %>\"><a\n data-playback-rate-a=\"<%= playbackRates[i].value %>\" href=\"#\"><%= playbackRates[i].label %></a></li>\n <% }; %>\n</ul>\n";
49582
-
49583
49620
  const buttonHtml = "<button class='gplayer-lite-btn gcore-skin-text-color gear-option'>\n <span class=\"gear-option_speed-icon\"><%= speedIcon %></span>\n <span>Playback speed</span>\n <span class=\"gear-option_arrow-right-icon\"><%= arrowRightIcon %></span>\n <span class='gear-option_value'><%= title %></span>\n</button>\n";
49584
49621
 
49585
49622
  const listHtml = "<button class=\"gplayer-lite-btn go-back gcore-skin-text-color\">\n <span class=\"arrow-left-icon\"><%= arrowLeftIcon %></span>\n Playback speed\n</button>\n<ul class=\"gear-sub-menu\">\n <% for (var i = playbackRates.length - 1; i >= 0; i--) { %>\n <li>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-rate=\"<%= playbackRates[i].value %>\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= playbackRates[i].label %>\n </a>\n </li>\n <% } %>\n</ul>\n";
@@ -49596,10 +49633,9 @@ const DEFAULT_PLAYBACK_RATES = [
49596
49633
  { value: '2.0', label: '2x' }
49597
49634
  ];
49598
49635
  const DEFAULT_PLAYBACK_RATE = '1.0';
49599
- // TODO
49600
- const MEDIACONTROL_PLAYBACKRATE = 'playbackRate';
49636
+ const T$6 = 'plugins.playback_rate';
49601
49637
  /**
49602
- * Allows changing the playback speed of the video.
49638
+ * PLUGIN that allows changing the playback speed of the video.
49603
49639
  * @beta
49604
49640
  *
49605
49641
  * @remarks
@@ -49609,12 +49645,13 @@ const MEDIACONTROL_PLAYBACKRATE = 'playbackRate';
49609
49645
  *
49610
49646
  * - {@link BottomGear | bottom_gear}
49611
49647
  *
49612
- * It renders a button in the gear menu, which opens a dropdown with the available playback rates.
49648
+ * It renders a button in the gear menu, which opens a dropdown with the options to change the playback rate.
49613
49649
  */
49614
49650
  class PlaybackRate extends UICorePlugin {
49615
- currentPlayback = null;
49616
49651
  playbackRates = DEFAULT_PLAYBACK_RATES;
49652
+ // Saved when an ad starts to restore after it finishes
49617
49653
  prevSelectedRate;
49654
+ rendered = false;
49618
49655
  selectedRate = DEFAULT_PLAYBACK_RATE;
49619
49656
  /**
49620
49657
  * @internal
@@ -49628,9 +49665,13 @@ class PlaybackRate extends UICorePlugin {
49628
49665
  get supportedVersion() {
49629
49666
  return { min: CLAPPR_VERSION };
49630
49667
  }
49631
- static template = tmpl(pluginHtml$3);
49632
49668
  static buttonTemplate = tmpl(buttonHtml);
49633
49669
  static listTemplate = tmpl(listHtml);
49670
+ constructor(core) {
49671
+ super(core);
49672
+ this.playbackRates = core.options.playbackRate?.options || DEFAULT_PLAYBACK_RATES;
49673
+ this.selectedRate = core.options.playbackRate?.defaultValue || DEFAULT_PLAYBACK_RATE;
49674
+ }
49634
49675
  /**
49635
49676
  * @internal
49636
49677
  */
@@ -49654,27 +49695,36 @@ class PlaybackRate extends UICorePlugin {
49654
49695
  * @internal
49655
49696
  */
49656
49697
  bindEvents() {
49657
- this.listenTo(this.core, 'gear:rendered', this.render);
49658
- // TODO this.core.getPlugin('media_control'), bottom_gear
49659
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.reload);
49660
- this.listenTo(this.core.mediaControl, MEDIACONTROL_PLAYBACKRATE, this.updatePlaybackRate);
49661
- this.listenTo(this.core, 'core:advertisement:start', this.onStartAd);
49662
- this.listenTo(this.core, 'core:advertisement:finish', this.onFinishAd);
49663
- if (this.core.activeContainer) {
49664
- this.listenTo(this.core.activePlayback, Events$1.PLAYBACK_BUFFERFULL, this.updateLiveStatus);
49665
- }
49666
- if (this.currentPlayback) {
49667
- this.listenTo(this.currentPlayback, Events$1.PLAYBACK_STOP, this.onStop);
49668
- this.listenTo(this.currentPlayback, Events$1.PLAYBACK_PLAY, this.onPlay);
49669
- // TODO import dash playback events
49670
- this.listenTo(this.currentPlayback, 'dash:playback-rate-changed', this.onDashRateChange);
49671
- }
49698
+ this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
49699
+ this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChange);
49672
49700
  }
49673
- unBindEvents() {
49674
- this.stopListening(this.core, 'gear:rendered', this.render);
49675
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.reload);
49676
- this.stopListening(this.core, 'core:advertisement:start', this.onStartAd);
49677
- this.stopListening(this.core, 'core:advertisement:finish', this.onFinishAd);
49701
+ onCoreReady() {
49702
+ const mediaControl = this.core.getPlugin('media_control');
49703
+ assert(mediaControl, 'media_control plugin is required');
49704
+ const gear = this.core.getPlugin('bottom_gear');
49705
+ assert(gear, 'bottom_gear plugin is required');
49706
+ this.listenTo(mediaControl, MediaControlEvents.MEDIACONTROL_GEAR_RENDERED, this.onGearRendered);
49707
+ }
49708
+ onActiveContainerChange() {
49709
+ this.listenTo(this.core.activePlayback, Events$1.PLAYBACK_STOP, this.onStop);
49710
+ this.listenTo(this.core.activePlayback, Events$1.PLAYBACK_PLAY, this.onPlay);
49711
+ this.listenTo(this.core.activePlayback, PlaybackEvents.PLAYBACK_RATE_CHANGED, this.onPlaybackRateChange);
49712
+ this.listenTo(this.core.activeContainer, Events$1.CONTAINER_PLAYBACKDVRSTATECHANGED, this.onDvrStateChanged);
49713
+ }
49714
+ onGearRendered() {
49715
+ trace(`${T$6} onGearRendered`, {
49716
+ rendered: this.rendered,
49717
+ });
49718
+ this.rendered = false;
49719
+ this.render();
49720
+ }
49721
+ onDvrStateChanged(dvrEnabled) {
49722
+ trace(`${T$6} onDvrStateChanged`, {
49723
+ dvrEnabled,
49724
+ });
49725
+ if (dvrEnabled) {
49726
+ this.render();
49727
+ }
49678
49728
  }
49679
49729
  allRateElements() {
49680
49730
  return this.$('ul.gear-sub-menu li');
@@ -49682,68 +49732,53 @@ class PlaybackRate extends UICorePlugin {
49682
49732
  rateElement(rate = "1") {
49683
49733
  return this.$(`ul.gear-sub-menu a[data-rate="${rate}"]`).parent();
49684
49734
  }
49685
- onDashRateChange() {
49686
- // TODO consider removing
49687
- this.currentPlayback._dash?.setPlaybackRate(this.selectedRate);
49688
- }
49689
- updateLiveStatus() {
49690
- if (this.core.getPlaybackType() === Playback.LIVE) {
49691
- if (this.core.mediaControl.currentSeekBarPercentage <= 98.9) {
49692
- this.core.mediaControl.$playbackRate.removeClass('playbackrate-enable');
49693
- this.core.mediaControl.$el.addClass('dvr');
49694
- return;
49695
- }
49696
- this.updatePlaybackRate(DEFAULT_PLAYBACK_RATE);
49697
- this.core.mediaControl.$playbackRate.addClass('playbackrate-enable');
49698
- this.core.mediaControl.$el.removeClass('dvr');
49735
+ onPlaybackRateChange(playbackRate) {
49736
+ const selectedRate = parseInt(this.selectedRate, 10);
49737
+ if (playbackRate !== selectedRate) {
49738
+ trace(`${T$6} onPlaybackRateChange setting target rate`, {
49739
+ playbackRate,
49740
+ selectedRate,
49741
+ });
49742
+ this.core.activePlayback?.setPlaybackRate(selectedRate);
49699
49743
  }
49700
49744
  }
49701
- reload() {
49702
- this.unBindEvents();
49703
- this.bindEvents();
49704
- }
49705
49745
  shouldRender() {
49706
49746
  if (!this.core.activeContainer) {
49707
49747
  return false;
49708
49748
  }
49709
- this.currentPlayback = this.core.activePlayback;
49710
- return !(this.currentPlayback?.tagName !== 'video' && this.currentPlayback?.tagName !== 'audio');
49749
+ if (this.core.getPlaybackType() === Playback.LIVE && !this.core.activePlayback.dvrEnabled) {
49750
+ return false;
49751
+ }
49752
+ return 'setPlaybackRate' in this.core.activePlayback;
49711
49753
  }
49712
49754
  /**
49713
49755
  * @internal
49714
49756
  */
49715
49757
  render() {
49716
- const container = this.core.activeContainer;
49717
- if (this.core.getPlaybackType() === Playback.LIVE && !container.isDvrEnabled()) {
49758
+ trace(`${T$6} render`, {
49759
+ rendered: this.rendered,
49760
+ shouldRender: this.shouldRender(),
49761
+ });
49762
+ if (!this.shouldRender()) {
49718
49763
  return this;
49719
49764
  }
49720
- const cfg = this.core.options.playbackRateConfig || {};
49721
- if (!this.playbackRates) {
49722
- this.playbackRates = cfg.options || DEFAULT_PLAYBACK_RATES;
49723
- }
49724
- if (!this.selectedRate) {
49725
- this.selectedRate = cfg.defaultValue || DEFAULT_PLAYBACK_RATE;
49726
- }
49727
- if (this.shouldRender()) {
49728
- const button = PlaybackRate.buttonTemplate({
49729
- title: this.getTitle(),
49730
- speedIcon,
49731
- arrowRightIcon,
49732
- });
49733
- this.$el.html(button);
49734
- // if (this.core.getPlaybackType() === Playback.LIVE) {
49735
- // this.core.mediaControl.$playbackRate.addClass('playbackrate-enable');
49736
- // }
49737
- // this.core.mediaControl.$playbackRate.append(this.el);
49738
- this.core.mediaControl.$el?.find('.gear-options-list [data-rate]').html(this.el);
49739
- // this.updateText();
49765
+ if (this.rendered) {
49766
+ return this;
49740
49767
  }
49768
+ const button = PlaybackRate.buttonTemplate({
49769
+ title: this.getTitle(),
49770
+ speedIcon,
49771
+ arrowRightIcon,
49772
+ });
49773
+ this.$el.html(button);
49774
+ this.core.getPlugin('bottom_gear')?.getElement('rate')?.html(this.el);
49775
+ this.rendered = true;
49741
49776
  return this;
49742
49777
  }
49743
49778
  onStartAd() {
49744
49779
  this.prevSelectedRate = this.selectedRate;
49745
- this.setSelectedRate('1.0');
49746
- this.listenToOnce(this.currentPlayback, Events$1.PLAYBACK_PLAY, this.onFinishAd);
49780
+ this.resetPlaybackRate();
49781
+ this.listenToOnce(this.core.activePlayback, Events$1.PLAYBACK_PLAY, this.onFinishAd);
49747
49782
  }
49748
49783
  onFinishAd() {
49749
49784
  if (this.prevSelectedRate) {
@@ -49751,16 +49786,16 @@ class PlaybackRate extends UICorePlugin {
49751
49786
  }
49752
49787
  }
49753
49788
  onPlay() {
49754
- if (!this.core.mediaControl.$el.hasClass('dvr')) {
49755
- if (this.core.getPlaybackType() === Playback.LIVE) {
49756
- this.updatePlaybackRate(DEFAULT_PLAYBACK_RATE);
49757
- this.core.mediaControl.$playbackRate.addClass('playbackrate-enable');
49758
- }
49789
+ if (this.core.getPlaybackType() === Playback.LIVE && !this.core.activePlayback.dvrEnabled) {
49790
+ this.resetPlaybackRate();
49759
49791
  }
49760
49792
  else {
49761
49793
  this.setSelectedRate(this.selectedRate);
49762
49794
  }
49763
49795
  }
49796
+ resetPlaybackRate() {
49797
+ this.setSelectedRate(DEFAULT_PLAYBACK_RATE);
49798
+ }
49764
49799
  onStop() {
49765
49800
  }
49766
49801
  onRateSelect(event) {
@@ -49778,30 +49813,21 @@ class PlaybackRate extends UICorePlugin {
49778
49813
  arrowLeftIcon,
49779
49814
  checkIcon,
49780
49815
  }));
49781
- this.core.mediaControl.$el?.find('.gear-wrapper').html(this.el);
49816
+ this.core.getPlugin('bottom_gear')?.setContent(this.el);
49782
49817
  this.highlightCurrentRate();
49783
49818
  }
49784
49819
  goBack() {
49785
- this.core.trigger('gear:refresh');
49786
- }
49787
- updatePlaybackRate(rate) {
49788
- this.setSelectedRate(rate);
49820
+ setTimeout(() => {
49821
+ this.core.getPlugin('bottom_gear').refresh();
49822
+ }, 0);
49789
49823
  }
49790
49824
  setSelectedRate(rate) {
49791
49825
  // Set <video playbackRate="..."
49792
- this.core.$el.find('video,audio').get(0).playbackRate = rate;
49826
+ this.core.activePlayback?.setPlaybackRate(rate);
49793
49827
  this.selectedRate = rate;
49794
- // TODO
49795
- // Player.player.trigger('playbackRateChanged', rate);
49796
49828
  }
49797
49829
  getTitle() {
49798
- let title = this.selectedRate;
49799
- this.playbackRates.forEach((r) => {
49800
- if (r.value === this.selectedRate) {
49801
- title = r.label;
49802
- }
49803
- });
49804
- return title;
49830
+ return this.playbackRates.find((r) => r.value === this.selectedRate)?.label || this.selectedRate;
49805
49831
  }
49806
49832
  highlightCurrentRate() {
49807
49833
  this.allRateElements().removeClass('current');
@@ -49817,7 +49843,7 @@ const posterHTML = "<div class=\"play-wrapper\" data-poster></div>\n";
49817
49843
  //Copyright 2014 Globo.com Player authors. All rights reserved.
49818
49844
  // Use of this source code is governed by a BSD-style
49819
49845
  // license that can be found in the LICENSE file.
49820
- const T$5 = 'plugins.poster_custom';
49846
+ const T$5 = 'plugins.poster';
49821
49847
  /**
49822
49848
  * Displays a poster image in the background and a big play button on top when playback is stopped
49823
49849
  * @beta
@@ -49855,7 +49881,7 @@ class Poster extends UIContainerPlugin {
49855
49881
  * @internal
49856
49882
  */
49857
49883
  get name() {
49858
- return 'poster_custom';
49884
+ return 'poster';
49859
49885
  }
49860
49886
  /**
49861
49887
  * @internal
@@ -50256,7 +50282,8 @@ const fbIcon = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"32px\"
50256
50282
  const twIcon = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"32px\" height=\"32px\" viewBox=\"0 0 32 32\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <!-- Generator: Sketch 49 (51002) - http://www.bohemiancoding.com/sketch -->\n <title>twitter</title>\n <desc>Created with Sketch.</desc>\n <defs></defs>\n <g id=\"twitter\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <g fill-rule=\"nonzero\" id=\"Shape\">\n <path d=\"M32,30 C32,31.104 31.104,32 30,32 L2,32 C0.896,32 0,31.104 0,30 L0,2 C0,0.896 0.896,0 2,0 L30,0 C31.104,0 32,0.896 32,2 L32,30 Z\" fill=\"#55ACEE\"></path>\n <path class=\"icon-hover\" d=\"M25.987,9.894 C25.251,10.216 24.462,10.431 23.63,10.529 C24.48,10.031 25.13,9.24 25.436,8.298 C24.644,8.759 23.766,9.095 22.831,9.276 C22.083,8.491 21.017,8 19.838,8 C17.572,8 15.738,9.807 15.738,12.038 C15.738,12.352 15.774,12.663 15.842,12.96 C12.435,12.788 9.413,11.181 7.39,8.739 C7.038,9.336 6.834,10.029 6.834,10.771 C6.834,12.17 7.56,13.406 8.658,14.131 C7.987,14.109 7.354,13.928 6.802,13.625 C6.801,13.642 6.801,13.659 6.801,13.677 C6.801,15.632 8.215,17.266 10.091,17.637 C9.748,17.727 9.386,17.779 9.01,17.779 C8.746,17.779 8.49,17.755 8.24,17.707 C8.76,19.311 10.274,20.478 12.068,20.512 C10.67,21.594 8.9,22.24 6.979,22.24 C6.649,22.24 6.321,22.222 6,22.184 C7.814,23.329 9.971,23.997 12.287,23.997 C19.828,23.997 23.953,17.843 23.953,12.506 C23.953,12.333 23.948,12.156 23.941,11.985 C24.741,11.414 25.438,10.703 25.987,9.894 Z\" fill=\"#FFFFFF\"></path>\n </g>\n </g>\n</svg>";
50257
50283
 
50258
50284
  /**
50259
- * The plugin adds a share button to the media control UI.
50285
+ * PLUGIN that adds a share button to the media control UI.
50286
+ * @beta
50260
50287
  */
50261
50288
  class Share extends UICorePlugin {
50262
50289
  hide = false;
@@ -50376,7 +50403,8 @@ class Share extends UICorePlugin {
50376
50403
  const pluginHtml$1 = "<div class=\"skip-container\" data-skip-container>\n <div class=\"skip-item\" data-skip-left>\n </div>\n <div class=\"skip-item\" data-skip-mid>\n </div>\n <div class=\"skip-item\" data-skip-right>\n </div>\n</div>\n";
50377
50404
 
50378
50405
  /**
50379
- * The plugin adds skip controls to the media control UI.
50406
+ * PLUGIN that adds skip controls to the media control UI.
50407
+ * @beta
50380
50408
  */
50381
50409
  class SkipTime extends UICorePlugin {
50382
50410
  get name() {
@@ -50469,6 +50497,7 @@ const spinnerHTML = "<div data-bounce1></div>\n<div data-bounce2></div>\n<div da
50469
50497
  const T$4 = 'plugins.spinner';
50470
50498
  /**
50471
50499
  * Custom events emitted by the plugin
50500
+ * @beta
50472
50501
  */
50473
50502
  var SpinnerEvents;
50474
50503
  (function (SpinnerEvents) {
@@ -50479,10 +50508,12 @@ var SpinnerEvents;
50479
50508
  SpinnerEvents["SYNC"] = "plugins:spinner:sync";
50480
50509
  })(SpinnerEvents || (SpinnerEvents = {}));
50481
50510
  /**
50482
- * Shows a pending operation indicator when playback is buffering or in other appropriate cases
50511
+ * PLUGIN that shows a pending operation indicator when playback is buffering or in a similar state
50483
50512
  * @beta
50484
50513
  * @remarks
50485
- * The plugin emits
50514
+ * Events emitted- {@link SpinnerEvents}
50515
+ * Other plugins can use {@link SpinnerThreeBounce.show | show} and {@link SpinnerThreeBounce.hide | hide} methods to
50516
+ * implement custom pending/progress indication scenarios.
50486
50517
  */
50487
50518
  class SpinnerThreeBounce extends UIContainerPlugin {
50488
50519
  userShown = false;
@@ -50562,7 +50593,7 @@ class SpinnerThreeBounce extends UIContainerPlugin {
50562
50593
  /**
50563
50594
  * Shows the spinner.
50564
50595
  *
50565
- * When called, the spinner will not hide (due to its built-in logic) until {@link SpinnerThreeBounce#hide} is called
50596
+ * When called, the spinner will not hide (due to its built-in logic) until {@link SpinnerThreeBounce.hide} is called
50566
50597
  */
50567
50598
  show(delay = 300) {
50568
50599
  trace(`${T$4} show`);
@@ -50743,7 +50774,7 @@ class SourceController extends CorePlugin {
50743
50774
  }
50744
50775
  this.bindContainerEventListeners();
50745
50776
  if (this.active) {
50746
- this.core.activeContainer?.getPlugin('poster_custom')?.disable();
50777
+ this.core.activeContainer?.getPlugin('poster')?.disable();
50747
50778
  spinner?.show(0);
50748
50779
  }
50749
50780
  }
@@ -50764,7 +50795,7 @@ class SourceController extends CorePlugin {
50764
50795
  }
50765
50796
  switch (error.code) {
50766
50797
  case PlaybackErrorCode.MediaSourceUnavailable:
50767
- this.core.activeContainer?.getPlugin('poster_custom')?.disable();
50798
+ this.core.activeContainer?.getPlugin('poster')?.disable();
50768
50799
  this.retryPlayback();
50769
50800
  break;
50770
50801
  }
@@ -50776,7 +50807,7 @@ class SourceController extends CorePlugin {
50776
50807
  });
50777
50808
  if (this.active) {
50778
50809
  this.reset();
50779
- this.core.activeContainer?.getPlugin('poster_custom')?.enable();
50810
+ this.core.activeContainer?.getPlugin('poster')?.enable();
50780
50811
  this.core.activeContainer?.getPlugin('spinner')?.hide();
50781
50812
  }
50782
50813
  });
@@ -51220,7 +51251,7 @@ var TelemetryEvent;
51220
51251
  TelemetryEvent[TelemetryEvent["Stall"] = 4] = "Stall";
51221
51252
  })(TelemetryEvent || (TelemetryEvent = {}));
51222
51253
  /**
51223
- * Collects and reports the performance statistics.
51254
+ * PLUGIN that collects and reports the performance statistics.
51224
51255
  * @beta
51225
51256
  * @remarks
51226
51257
  * This plugin is experimental and its API is likely to change.
@@ -52044,4 +52075,4 @@ class VolumeFade extends UICorePlugin {
52044
52075
  }
52045
52076
  }
52046
52077
 
52047
- export { AudioSelector, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ContextMenu, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, Kibo, LevelSelector, LogTracer, Logger, Logo, MediaControl, MediaControlEvents, MultiCamera, PictureInPicture, PlaybackErrorCode, PlaybackRate, Player, PlayerEvent, Poster, SeekTime, SentryTracer, Share, SkipTime, SourceController, SpinnerEvents, SpinnerThreeBounce, Subtitles, Telemetry, TelemetryEvent, Thumbnails, VolumeFade, VolumeFadeEvents, reportError, setTracer, trace, version };
52078
+ export { AudioSelector, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ContextMenu, DvrControls, ErrorScreen, Favicon, GoogleAnalytics, LevelSelector, LogTracer, Logger, Logo, MediaControl, MediaControlEvents, MultiCamera, PictureInPicture, PlaybackErrorCode, PlaybackRate, Player, PlayerEvent, Poster, SeekTime, SentryTracer, Share, SkipTime, SourceController, SpinnerEvents, SpinnerThreeBounce, Subtitles, Telemetry, TelemetryEvent, Thumbnails, VolumeFade, VolumeFadeEvents, reportError, setTracer, trace, version };