rx-player 3.33.5-dev.2025040100 → 3.33.6

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.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # Changelog
2
2
 
3
- ## Current dev build: v3.33.5-dev.2025040100
3
+ ## v3.33.6 (2025-09-25)
4
+
5
+ ### Bug fixes
6
+
7
+ - Subtitles: Fix some subtitle missing on multiple period assets [#1726]
8
+ - DRM: renew the mediaKeySystemAccess on Edge and Firefox when using a Playready keySystem
9
+ to work-around frequent DRM issues. [#1728]
10
+ - DRM: On Firefox check extensively Playready DRMs support before using them to
11
+ work-around recent firefox issue with PlayReady integration [#1730]
12
+ - DRM: Fix persistent session loading when content has no key id [#1724]
13
+ - Directfile: set autoplay attribute on directfile contents, to work-around
14
+ safari-specific issues [#1729]
15
+ - Remove unnecessary duration logs when reaching the end of some VoD contents [1750]
16
+
17
+ ## v3.33.5 (2025-04-01)
4
18
 
5
19
  ### Bug fixes
6
20
 
@@ -28,7 +42,7 @@
28
42
  - Avoid error log when stopping a stream with a pending `BufferGarbageCollector` buffer
29
43
  removal [#1685]
30
44
 
31
- ## v3.33.4
45
+ ## v3.33.4 (2024-10-17)
32
46
 
33
47
  ### Bug fixes
34
48
 
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.33.5-dev.2025040100
1
+ 3.33.6
@@ -26,8 +26,14 @@
26
26
  * "com.microsoft.playready.recommendation.3000", generating a request with
27
27
  * `generateRequest` throws an error: "NotSupportedError: Failed to execute
28
28
  * 'generateRequest' on 'MediaKeySession': Failed to create MF PR CdmSession".
29
- * In this particular case, the work-around was to consider
30
- * recommendation.3000 as not supported and try another keySystem.
29
+ * In this particular case, the work-around was to consider recommendation.3000 as not supported
30
+ * and try another keySystem.
31
+ *
32
+ * - On Firefox v.137:
33
+ * Similar issue with requestMediaKeySystemAccess that resolves correctly with
34
+ * 'com.microsoft.playready.recommendation.3000' but fail at the `createMediaKeys``
35
+ * step with error `WMFCDMProxy: Init: WMFCDM init error`
36
+ *
31
37
  * @param keySystem - The key system in use.
32
38
  * @returns {boolean}
33
39
  */
@@ -13,7 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { isEdgeChromium } from "./browser_detection";
16
+ import { isEdgeChromium, isFirefox } from "./browser_detection";
17
17
  /**
18
18
  * This functions tells if the RxPlayer can trust the browser when it has
19
19
  * successfully granted the MediaKeySystemAccess with
@@ -27,13 +27,19 @@ import { isEdgeChromium } from "./browser_detection";
27
27
  * "com.microsoft.playready.recommendation.3000", generating a request with
28
28
  * `generateRequest` throws an error: "NotSupportedError: Failed to execute
29
29
  * 'generateRequest' on 'MediaKeySession': Failed to create MF PR CdmSession".
30
- * In this particular case, the work-around was to consider
31
- * recommendation.3000 as not supported and try another keySystem.
30
+ * In this particular case, the work-around was to consider recommendation.3000 as not supported
31
+ * and try another keySystem.
32
+ *
33
+ * - On Firefox v.137:
34
+ * Similar issue with requestMediaKeySystemAccess that resolves correctly with
35
+ * 'com.microsoft.playready.recommendation.3000' but fail at the `createMediaKeys``
36
+ * step with error `WMFCDMProxy: Init: WMFCDM init error`
37
+ *
32
38
  * @param keySystem - The key system in use.
33
39
  * @returns {boolean}
34
40
  */
35
41
  export function canRelyOnRequestMediaKeySystemAccess(keySystem) {
36
- if (isEdgeChromium && keySystem.indexOf("playready") !== -1) {
42
+ if ((isEdgeChromium || isFirefox) && keySystem.indexOf("playready") !== -1) {
37
43
  return false;
38
44
  }
39
45
  return true;
@@ -18,4 +18,4 @@
18
18
  * renewed on each content.
19
19
  * @returns {Boolean}
20
20
  */
21
- export default function shouldRenewMediaKeySystemAccess(): boolean;
21
+ export default function shouldRenewMediaKeySystemAccess(keySystem: string): boolean;
@@ -13,12 +13,12 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { isIE11 } from "./browser_detection";
16
+ import { isIE11, isEdgeChromium, isFirefox } from "./browser_detection";
17
17
  /**
18
18
  * Returns true if the current target require the MediaKeySystemAccess to be
19
19
  * renewed on each content.
20
20
  * @returns {Boolean}
21
21
  */
22
- export default function shouldRenewMediaKeySystemAccess() {
23
- return isIE11;
22
+ export default function shouldRenewMediaKeySystemAccess(keySystem) {
23
+ return keySystem.indexOf("playready") !== -1 && (isIE11 || isEdgeChromium || isFirefox);
24
24
  }
@@ -88,7 +88,7 @@ var Player = /** @class */ (function (_super) {
88
88
  // Workaround to support Firefox autoplay on FF 42.
89
89
  // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
90
90
  videoElement.preload = "auto";
91
- _this.version = /* PLAYER_VERSION */ "3.33.5-dev.2025040100";
91
+ _this.version = /* PLAYER_VERSION */ "3.33.6";
92
92
  _this.log = log;
93
93
  _this.state = "STOPPED";
94
94
  _this.videoElement = videoElement;
@@ -2520,5 +2520,5 @@ var Player = /** @class */ (function (_super) {
2520
2520
  Player._priv_currentlyUsedVideoElements = new WeakSet();
2521
2521
  return Player;
2522
2522
  }(EventEmitter));
2523
- Player.version = /* PLAYER_VERSION */ "3.33.5-dev.2025040100";
2523
+ Player.version = /* PLAYER_VERSION */ "3.33.6";
2524
2524
  export default Player;
@@ -334,7 +334,7 @@ export default function getMediaKeySystemAccess(mediaElement, keySystemsConfigs,
334
334
  keySystemConfiguration = keySystemConfigurations[configIdx];
335
335
  // Check if the current `MediaKeySystemAccess` created cannot be reused here
336
336
  if (currentState !== null &&
337
- !shouldRenewMediaKeySystemAccess() &&
337
+ !shouldRenewMediaKeySystemAccess(currentState.mediaKeySystemAccess.keySystem) &&
338
338
  // TODO: Do it with MediaKeySystemAccess.prototype.keySystem instead?
339
339
  keyType === currentState.mediaKeySystemAccess.keySystem &&
340
340
  eme.implementation === currentState.emeImplementation.implementation &&
@@ -220,7 +220,7 @@ var PersistentSessionsStore = /** @class */ (function () {
220
220
  if (entry.initDataType === initData.type) {
221
221
  switch (entry.version) {
222
222
  case 4:
223
- if (initData.keyIds !== undefined) {
223
+ if (Array.isArray(initData.keyIds) && initData.keyIds.length > 0) {
224
224
  var foundCompatible = initData.keyIds.every(function (keyId) {
225
225
  var keyIdB64 = bytesToBase64(keyId);
226
226
  for (var _i = 0, _a = entry.keyIds; _i < _a.length; _i++) {
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import type { IKeySystemOption } from "../../public_types";
17
17
  import type { IReadOnlySharedReference } from "../../utils/reference";
18
+ import type { CancellationSignal } from "../../utils/task_canceller";
18
19
  import type { PlaybackObserver } from "../api";
19
20
  import { ContentInitializer } from "./types";
20
21
  import type { IInitialTimeOptions } from "./utils/get_initial_time";
@@ -79,6 +80,15 @@ export default class DirectFileContentInitializer extends ContentInitializer {
79
80
  */
80
81
  private _seekAndPlay;
81
82
  }
83
+ /**
84
+ * Set autoplay value on the mediaElement.
85
+ *
86
+ * @param {HTMLElement} mediaElement - The media element whose `autoplay`
87
+ * attribute will be modified.
88
+ * @param {CancellationSignal} cancellationSignal - The signal that, when triggered,
89
+ * restores the `autoplay` attribute to its original value.
90
+ */
91
+ export declare function setAutoplay(mediaElement: HTMLMediaElement, autoplay: boolean, cancellationSignal: CancellationSignal): void;
82
92
  /** Options used by the `DirectFileContentInitializer` */
83
93
  export interface IDirectFileOptions {
84
94
  /** If `true` we will play right after the content is considered "loaded". */
@@ -91,6 +91,10 @@ var DirectFileContentInitializer = /** @class */ (function (_super) {
91
91
  */
92
92
  var decryptionRef = new SharedReference(null);
93
93
  decryptionRef.finish();
94
+ // Set the autoplay attribute on the mediaElement.
95
+ // On Apple devices, the native HLS player needs autoplay to be set
96
+ // in order to start buffering,which is required for our API's autoplay to work.
97
+ setAutoplay(mediaElement, this._settings.autoPlay, cancelSignal);
94
98
  var drmInitRef = initializeContentDecryption(mediaElement, keySystems, decryptionRef, {
95
99
  onError: function (err) { return _this._onFatalError(err); },
96
100
  onWarning: function (err) { return _this.trigger("warning", err); },
@@ -198,6 +202,31 @@ var DirectFileContentInitializer = /** @class */ (function (_super) {
198
202
  return DirectFileContentInitializer;
199
203
  }(ContentInitializer));
200
204
  export default DirectFileContentInitializer;
205
+ /**
206
+ * Set autoplay value on the mediaElement.
207
+ *
208
+ * @param {HTMLElement} mediaElement - The media element whose `autoplay`
209
+ * attribute will be modified.
210
+ * @param {CancellationSignal} cancellationSignal - The signal that, when triggered,
211
+ * restores the `autoplay` attribute to its original value.
212
+ */
213
+ export function setAutoplay(mediaElement, autoplay, cancellationSignal) {
214
+ if (!autoplay) {
215
+ // If autoplay option is set to false, don't touch to `autoplay`
216
+ // videoElement attribute.
217
+ return;
218
+ }
219
+ var autoplayPreviousValue = mediaElement.autoplay;
220
+ mediaElement.autoplay = autoplay;
221
+ cancellationSignal.register(function () {
222
+ /**
223
+ * Restore the `autoplay` attribute to its previous value.
224
+ * This ensures that the media element's state is the same as it was before
225
+ * calling `RxPlayer.loadVideo` in the application.
226
+ */
227
+ mediaElement.autoplay = autoplayPreviousValue;
228
+ });
229
+ }
201
230
  /**
202
231
  * calculate initial time as a position in seconds.
203
232
  * @param {HTMLMediaElement} mediaElement
@@ -126,7 +126,7 @@ function setMediaSourceDuration(mediaSource, duration, isRealEndKnown) {
126
126
  var sourceBuffer = mediaSource.sourceBuffers[i];
127
127
  var sbBufferedLen = sourceBuffer.buffered.length;
128
128
  if (sbBufferedLen > 0) {
129
- maxBufferedEnd = Math.max(sourceBuffer.buffered.end(sbBufferedLen - 1));
129
+ maxBufferedEnd = Math.max(maxBufferedEnd, sourceBuffer.buffered.end(sbBufferedLen - 1));
130
130
  }
131
131
  }
132
132
  if (newDuration === mediaSource.duration) {
@@ -195,7 +195,8 @@ var HTMLTextSegmentBuffer = /** @class */ (function (_super) {
195
195
  while (i >= 0 && cues[i].start >= appendWindowEnd) {
196
196
  i--;
197
197
  }
198
- cues.splice(i, cues.length);
198
+ // cues[i] is the last cue we want to keep, remove from i + 1
199
+ cues.splice(i + 1, cues.length);
199
200
  i = cues.length - 1;
200
201
  while (i >= 0 && cues[i].end > appendWindowEnd) {
201
202
  cues[i].end = appendWindowEnd;
@@ -186,7 +186,18 @@ export default function fetchRequest(options) {
186
186
  * @return {boolean}
187
187
  */
188
188
  export function fetchIsSupported() {
189
+ // Match [native code] and variants with different white space.
190
+ var nativeCodeRegex = /\[\s*native\s+code\s*\]/;
189
191
  return (typeof window.fetch === "function" &&
192
+ /**
193
+ * Detect if AbortController function has been rewritten.
194
+ * Polyfills can rewrite those function without a proper implementation
195
+ * leading to issues.
196
+ * In this case it's preferable to use XHR over fetch, because fetch uses
197
+ * AbortSignal to cancel requests.
198
+ * @see https://github.com/TanStack/query/discussions/9049
199
+ */
190
200
  !isNullOrUndefined(_AbortController) &&
201
+ nativeCodeRegex.test(_AbortController.toString()) &&
191
202
  !isNullOrUndefined(_Headers));
192
203
  }
Binary file
package/dist/rx-player.js CHANGED
@@ -4977,8 +4977,8 @@ function canReuseMediaKeys() {
4977
4977
  * renewed on each content.
4978
4978
  * @returns {Boolean}
4979
4979
  */
4980
- function shouldRenewMediaKeySystemAccess() {
4981
- return browser_detection/* isIE11 */.lw;
4980
+ function shouldRenewMediaKeySystemAccess(keySystem) {
4981
+ return keySystem.indexOf("playready") !== -1 && (browser_detection/* isIE11 */.lw || browser_detection/* isEdgeChromium */.op || browser_detection/* isFirefox */.gm);
4982
4982
  }
4983
4983
  ;// CONCATENATED MODULE: ./src/compat/can_rely_on_request_media_key_system_access.ts
4984
4984
  /**
@@ -5010,13 +5010,19 @@ function shouldRenewMediaKeySystemAccess() {
5010
5010
  * "com.microsoft.playready.recommendation.3000", generating a request with
5011
5011
  * `generateRequest` throws an error: "NotSupportedError: Failed to execute
5012
5012
  * 'generateRequest' on 'MediaKeySession': Failed to create MF PR CdmSession".
5013
- * In this particular case, the work-around was to consider
5014
- * recommendation.3000 as not supported and try another keySystem.
5013
+ * In this particular case, the work-around was to consider recommendation.3000 as not supported
5014
+ * and try another keySystem.
5015
+ *
5016
+ * - On Firefox v.137:
5017
+ * Similar issue with requestMediaKeySystemAccess that resolves correctly with
5018
+ * 'com.microsoft.playready.recommendation.3000' but fail at the `createMediaKeys``
5019
+ * step with error `WMFCDMProxy: Init: WMFCDM init error`
5020
+ *
5015
5021
  * @param keySystem - The key system in use.
5016
5022
  * @returns {boolean}
5017
5023
  */
5018
5024
  function canRelyOnRequestMediaKeySystemAccess(keySystem) {
5019
- if (browser_detection/* isEdgeChromium */.op && keySystem.indexOf("playready") !== -1) {
5025
+ if ((browser_detection/* isEdgeChromium */.op || browser_detection/* isFirefox */.gm) && keySystem.indexOf("playready") !== -1) {
5020
5026
  return false;
5021
5027
  }
5022
5028
  return true;
@@ -5400,7 +5406,7 @@ function getMediaKeySystemAccess(mediaElement, keySystemsConfigs, cancelSignal)
5400
5406
  break;
5401
5407
  }
5402
5408
  keySystemConfiguration = keySystemConfigurations[configIdx]; // Check if the current `MediaKeySystemAccess` created cannot be reused here
5403
- if (!(currentState !== null && !shouldRenewMediaKeySystemAccess() &&
5409
+ if (!(currentState !== null && !shouldRenewMediaKeySystemAccess(currentState.mediaKeySystemAccess.keySystem) &&
5404
5410
  // TODO: Do it with MediaKeySystemAccess.prototype.keySystem instead?
5405
5411
  keyType === currentState.mediaKeySystemAccess.keySystem && eme.implementation === currentState.emeImplementation.implementation && isNewMediaKeySystemConfigurationCompatibleWithPreviousOne(keySystemConfiguration, currentState.askedConfiguration))) {
5406
5412
  _context.next = 15;
@@ -7078,7 +7084,7 @@ var PersistentSessionsStore = /*#__PURE__*/function () {
7078
7084
  if (entry.initDataType === initData.type) {
7079
7085
  switch (entry.version) {
7080
7086
  case 4:
7081
- if (initData.keyIds !== undefined) {
7087
+ if (Array.isArray(initData.keyIds) && initData.keyIds.length > 0) {
7082
7088
  var foundCompatible = initData.keyIds.every(function (keyId) {
7083
7089
  var keyIdB64 = (0,utils_base64/* bytesToBase64 */.i)(keyId);
7084
7090
  for (var _iterator = persistent_sessions_store_createForOfIteratorHelperLoose(entry.keyIds), _step; !(_step = _iterator()).done;) {
@@ -9783,6 +9789,7 @@ var currentMediaState = new WeakMap();
9783
9789
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
9784
9790
  /* harmony export */ A: function() { return /* binding */ DirectFileContentInitializer; }
9785
9791
  /* harmony export */ });
9792
+ /* unused harmony export setAutoplay */
9786
9793
  /* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7387);
9787
9794
  /* harmony import */ var _compat__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3116);
9788
9795
  /* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(9477);
@@ -9880,6 +9887,10 @@ var DirectFileContentInitializer = /*#__PURE__*/function (_ContentInitializer) {
9880
9887
  */
9881
9888
  var decryptionRef = new _utils_reference__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A(null);
9882
9889
  decryptionRef.finish();
9890
+ // Set the autoplay attribute on the mediaElement.
9891
+ // On Apple devices, the native HLS player needs autoplay to be set
9892
+ // in order to start buffering,which is required for our API's autoplay to work.
9893
+ setAutoplay(mediaElement, this._settings.autoPlay, cancelSignal);
9883
9894
  var drmInitRef = (0,_utils_initialize_content_decryption__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(mediaElement, keySystems, decryptionRef, {
9884
9895
  onError: function onError(err) {
9885
9896
  return _this2._onFatalError(err);
@@ -10004,13 +10015,38 @@ var DirectFileContentInitializer = /*#__PURE__*/function (_ContentInitializer) {
10004
10015
  };
10005
10016
  return DirectFileContentInitializer;
10006
10017
  }(_types__WEBPACK_IMPORTED_MODULE_11__/* .ContentInitializer */ .Y);
10018
+ /**
10019
+ * Set autoplay value on the mediaElement.
10020
+ *
10021
+ * @param {HTMLElement} mediaElement - The media element whose `autoplay`
10022
+ * attribute will be modified.
10023
+ * @param {CancellationSignal} cancellationSignal - The signal that, when triggered,
10024
+ * restores the `autoplay` attribute to its original value.
10025
+ */
10026
+
10027
+ function setAutoplay(mediaElement, autoplay, cancellationSignal) {
10028
+ if (!autoplay) {
10029
+ // If autoplay option is set to false, don't touch to `autoplay`
10030
+ // videoElement attribute.
10031
+ return;
10032
+ }
10033
+ var autoplayPreviousValue = mediaElement.autoplay;
10034
+ mediaElement.autoplay = autoplay;
10035
+ cancellationSignal.register(function () {
10036
+ /**
10037
+ * Restore the `autoplay` attribute to its previous value.
10038
+ * This ensures that the media element's state is the same as it was before
10039
+ * calling `RxPlayer.loadVideo` in the application.
10040
+ */
10041
+ mediaElement.autoplay = autoplayPreviousValue;
10042
+ });
10043
+ }
10007
10044
  /**
10008
10045
  * calculate initial time as a position in seconds.
10009
10046
  * @param {HTMLMediaElement} mediaElement
10010
10047
  * @param {Object|undefined} [startAt]
10011
10048
  * @returns {number}
10012
10049
  */
10013
-
10014
10050
  function getDirectFileInitialTime(mediaElement, startAt) {
10015
10051
  if ((0,_utils_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_12__/* ["default"] */ .A)(startAt)) {
10016
10052
  return 0;
@@ -20175,7 +20211,7 @@ function setMediaSourceDuration(mediaSource, duration, isRealEndKnown) {
20175
20211
  var sourceBuffer = mediaSource.sourceBuffers[i];
20176
20212
  var sbBufferedLen = sourceBuffer.buffered.length;
20177
20213
  if (sbBufferedLen > 0) {
20178
- maxBufferedEnd = Math.max(sourceBuffer.buffered.end(sbBufferedLen - 1));
20214
+ maxBufferedEnd = Math.max(maxBufferedEnd, sourceBuffer.buffered.end(sbBufferedLen - 1));
20179
20215
  }
20180
20216
  }
20181
20217
  if (newDuration === mediaSource.duration) {
@@ -23589,7 +23625,8 @@ var HTMLTextSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) {
23589
23625
  while (i >= 0 && cues[i].start >= appendWindowEnd) {
23590
23626
  i--;
23591
23627
  }
23592
- cues.splice(i, cues.length);
23628
+ // cues[i] is the last cue we want to keep, remove from i + 1
23629
+ cues.splice(i + 1, cues.length);
23593
23630
  i = cues.length - 1;
23594
23631
  while (i >= 0 && cues[i].end > appendWindowEnd) {
23595
23632
  cues[i].end = appendWindowEnd;
@@ -40965,7 +41002,18 @@ function fetchRequest(options) {
40965
41002
  * @return {boolean}
40966
41003
  */
40967
41004
  function fetchIsSupported() {
40968
- return typeof window.fetch === "function" && !(0,is_null_or_undefined/* default */.A)(_AbortController) && !(0,is_null_or_undefined/* default */.A)(_Headers);
41005
+ // Match [native code] and variants with different white space.
41006
+ var nativeCodeRegex = /\[\s*native\s+code\s*\]/;
41007
+ return typeof window.fetch === "function" &&
41008
+ /**
41009
+ * Detect if AbortController function has been rewritten.
41010
+ * Polyfills can rewrite those function without a proper implementation
41011
+ * leading to issues.
41012
+ * In this case it's preferable to use XHR over fetch, because fetch uses
41013
+ * AbortSignal to cancel requests.
41014
+ * @see https://github.com/TanStack/query/discussions/9049
41015
+ */
41016
+ !(0,is_null_or_undefined/* default */.A)(_AbortController) && nativeCodeRegex.test(_AbortController.toString()) && !(0,is_null_or_undefined/* default */.A)(_Headers);
40969
41017
  }
40970
41018
  // EXTERNAL MODULE: ./src/utils/warn_once.ts
40971
41019
  var warn_once = __webpack_require__(5950);
@@ -53832,7 +53880,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
53832
53880
  // Workaround to support Firefox autoplay on FF 42.
53833
53881
  // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
53834
53882
  videoElement.preload = "auto";
53835
- _this.version = /* PLAYER_VERSION */"3.33.5-dev.2025040100";
53883
+ _this.version = /* PLAYER_VERSION */"3.33.6";
53836
53884
  _this.log = src_log/* default */.A;
53837
53885
  _this.state = "STOPPED";
53838
53886
  _this.videoElement = videoElement;
@@ -56320,7 +56368,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
56320
56368
  * Use of a WeakSet ensure the object is garbage collected if it's not used anymore.
56321
56369
  */
56322
56370
  Player._priv_currentlyUsedVideoElements = new WeakSet();
56323
- Player.version = /* PLAYER_VERSION */"3.33.5-dev.2025040100";
56371
+ Player.version = /* PLAYER_VERSION */"3.33.6";
56324
56372
  /* harmony default export */ var public_api = (Player);
56325
56373
  ;// CONCATENATED MODULE: ./src/core/api/index.ts
56326
56374
  /**