rx-player 3.33.2 → 3.33.3

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 (90) hide show
  1. package/CHANGELOG.md +1079 -1128
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/compat/can_rely_on_request_media_key_system_access.d.ts +34 -0
  4. package/dist/_esm5.processed/compat/can_rely_on_request_media_key_system_access.js +40 -0
  5. package/dist/_esm5.processed/compat/generate_init_data.d.ts +14 -0
  6. package/dist/_esm5.processed/compat/generate_init_data.js +61 -0
  7. package/dist/_esm5.processed/compat/may_media_element_fail_on_undecipherable_data.d.ts +16 -0
  8. package/dist/_esm5.processed/compat/may_media_element_fail_on_undecipherable_data.js +17 -0
  9. package/dist/_esm5.processed/compat/should_wait_for_data_before_loaded.d.ts +1 -1
  10. package/dist/_esm5.processed/compat/should_wait_for_data_before_loaded.js +5 -3
  11. package/dist/_esm5.processed/config.d.ts +2 -0
  12. package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +1 -1
  13. package/dist/_esm5.processed/core/api/debug/buffer_graph.js +3 -3
  14. package/dist/_esm5.processed/core/api/public_api.d.ts +17 -0
  15. package/dist/_esm5.processed/core/api/public_api.js +41 -2
  16. package/dist/_esm5.processed/core/api/tracks_management/media_element_track_choice_manager.js +21 -25
  17. package/dist/_esm5.processed/core/decrypt/attach_media_keys.js +6 -6
  18. package/dist/_esm5.processed/core/decrypt/find_key_system.d.ts +10 -0
  19. package/dist/_esm5.processed/core/decrypt/find_key_system.js +42 -1
  20. package/dist/_esm5.processed/core/decrypt/session_events_listener.js +2 -2
  21. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +2 -2
  22. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +1 -1
  23. package/dist/_esm5.processed/core/init/media_source_content_initializer.js +34 -12
  24. package/dist/_esm5.processed/core/init/utils/get_loaded_reference.js +6 -1
  25. package/dist/_esm5.processed/core/init/utils/initial_seek_and_play.js +4 -1
  26. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +24 -25
  27. package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.js +1 -1
  28. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +1 -1
  29. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/text_track_cues_store.js +2 -2
  30. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/utils.d.ts +15 -0
  31. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/utils.js +23 -0
  32. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +1 -1
  33. package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.d.ts +18 -4
  34. package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.js +57 -13
  35. package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.js +3 -0
  36. package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.js +15 -8
  37. package/dist/_esm5.processed/core/stream/representation/utils/get_buffer_status.js +1 -37
  38. package/dist/_esm5.processed/core/stream/representation/utils/get_needed_segments.js +19 -11
  39. package/dist/_esm5.processed/core/stream/representation/utils/push_init_segment.js +6 -6
  40. package/dist/_esm5.processed/core/stream/representation/utils/push_media_segment.js +9 -9
  41. package/dist/_esm5.processed/default_config.d.ts +31 -0
  42. package/dist/_esm5.processed/default_config.js +48 -17
  43. package/dist/_esm5.processed/errors/assertion_error.d.ts +0 -1
  44. package/dist/_esm5.processed/errors/assertion_error.js +1 -2
  45. package/dist/_esm5.processed/errors/custom_loader_error.d.ts +0 -1
  46. package/dist/_esm5.processed/errors/custom_loader_error.js +1 -2
  47. package/dist/_esm5.processed/errors/encrypted_media_error.d.ts +0 -1
  48. package/dist/_esm5.processed/errors/encrypted_media_error.js +1 -2
  49. package/dist/_esm5.processed/errors/media_error.d.ts +0 -1
  50. package/dist/_esm5.processed/errors/media_error.js +1 -2
  51. package/dist/_esm5.processed/errors/network_error.d.ts +0 -1
  52. package/dist/_esm5.processed/errors/network_error.js +1 -2
  53. package/dist/_esm5.processed/errors/other_error.d.ts +0 -1
  54. package/dist/_esm5.processed/errors/other_error.js +1 -2
  55. package/dist/_esm5.processed/errors/request_error.d.ts +0 -1
  56. package/dist/_esm5.processed/errors/request_error.js +17 -15
  57. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader_error.d.ts +0 -1
  58. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader_error.js +2 -2
  59. package/dist/_esm5.processed/experimental/tools/createMetaplaylist/get_duration_from_manifest.js +1 -1
  60. package/dist/_esm5.processed/experimental/tools/mediaCapabilitiesProber/probers/decodingInfo.js +4 -4
  61. package/dist/_esm5.processed/parsers/containers/isobmff/utils.js +3 -1
  62. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +1 -3
  63. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representation_index.js +9 -5
  64. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/utils.d.ts +0 -1
  65. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/utils.js +1 -2
  66. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/ContentComponent.d.ts +1 -1
  67. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/ContentComponent.js +1 -1
  68. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/ContentProtection.d.ts +1 -1
  69. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/ContentProtection.js +1 -1
  70. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/Scheme.d.ts +1 -1
  71. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/Scheme.js +1 -1
  72. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/parsers_stack.d.ts +2 -1
  73. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/types.d.ts +55 -55
  74. package/dist/_esm5.processed/parsers/manifest/smooth/parse_protection_node.js +1 -1
  75. package/dist/_esm5.processed/transports/dash/extract_complete_chunks.d.ts +1 -1
  76. package/dist/_esm5.processed/transports/dash/extract_complete_chunks.js +6 -2
  77. package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.js +4 -2
  78. package/dist/_esm5.processed/utils/languages/ISO_639-1_to_ISO_639-3.js +182 -182
  79. package/dist/_esm5.processed/utils/languages/ISO_639-2_to_ISO_639-3.js +19 -19
  80. package/dist/_esm5.processed/utils/languages/normalize.js +4 -1
  81. package/dist/_esm5.processed/utils/resolve_url.d.ts +13 -10
  82. package/dist/_esm5.processed/utils/resolve_url.js +220 -69
  83. package/dist/_esm5.processed/utils/string_parsing.d.ts +1 -1
  84. package/dist/_esm5.processed/utils/string_parsing.js +1 -1
  85. package/dist/_esm5.processed/utils/task_canceller.d.ts +0 -1
  86. package/dist/_esm5.processed/utils/task_canceller.js +3 -2
  87. package/dist/mpd-parser.wasm +0 -0
  88. package/dist/rx-player.js +3951 -3398
  89. package/dist/rx-player.min.js +1 -1
  90. package/package.json +40 -40
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.33.2
1
+ 3.33.3
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Copyright 2015 CANAL+ Group
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * This functions tells if the RxPlayer can trust the browser when it has
18
+ * successfully granted the MediaKeySystemAccess with
19
+ * `navigator.requestMediaKeySystemAccess(keySystem)` function, or if it should do
20
+ * some additional testing to confirm that the `keySystem` is supported on the device.
21
+ *
22
+ * This behavior has been experienced on the following device:
23
+ *
24
+ * On a Microsoft Surface with Edge v.124:
25
+ * - Althought `requestMediaKeySystemAccess` resolve correctly with the keySystem
26
+ * "com.microsoft.playready.recommendation.3000", generating a request with
27
+ * `generateRequest` throws an error: "NotSupportedError: Failed to execute
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.
31
+ * @param keySystem - The key system in use.
32
+ * @returns {boolean}
33
+ */
34
+ export declare function canRelyOnRequestMediaKeySystemAccess(keySystem: string): boolean;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Copyright 2015 CANAL+ Group
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { isEdgeChromium } from "./browser_detection";
17
+ /**
18
+ * This functions tells if the RxPlayer can trust the browser when it has
19
+ * successfully granted the MediaKeySystemAccess with
20
+ * `navigator.requestMediaKeySystemAccess(keySystem)` function, or if it should do
21
+ * some additional testing to confirm that the `keySystem` is supported on the device.
22
+ *
23
+ * This behavior has been experienced on the following device:
24
+ *
25
+ * On a Microsoft Surface with Edge v.124:
26
+ * - Althought `requestMediaKeySystemAccess` resolve correctly with the keySystem
27
+ * "com.microsoft.playready.recommendation.3000", generating a request with
28
+ * `generateRequest` throws an error: "NotSupportedError: Failed to execute
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.
32
+ * @param keySystem - The key system in use.
33
+ * @returns {boolean}
34
+ */
35
+ export function canRelyOnRequestMediaKeySystemAccess(keySystem) {
36
+ if (isEdgeChromium && keySystem.indexOf("playready") !== -1) {
37
+ return false;
38
+ }
39
+ return true;
40
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The PlayReadyHeader sample that will be used to test if the CDM is supported.
3
+ * The KID does not matter because no content will be played, it's only to check if
4
+ * the CDM is capable of creating a session and generating a request.
5
+ */
6
+ export declare const DUMMY_PLAY_READY_HEADER = "<WRMHEADER xmlns=\"http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader\" version=\"4.0.0.0\"><DATA><PROTECTINFO><KEYLEN>16</KEYLEN><ALGID>AESCTR</ALGID></PROTECTINFO><KID>ckB07BNLskeUq0qd83fTbA==</KID><DS_ID>yYIPDBca1kmMfL60IsfgAQ==</DS_ID><CUSTOMATTRIBUTES xmlns=\"\"><encryptionref>312_4024_2018127108</encryptionref></CUSTOMATTRIBUTES><CHECKSUM>U/tsUYRgMzw=</CHECKSUM></DATA></WRMHEADER>";
7
+ /**
8
+ * Generate the "cenc" init data for playready from the PlayreadyHeader string.
9
+ * @param {string} playreadyHeader - String representing the PlayreadyHeader XML.
10
+ * @returns {Uint8Array} The init data generated for that PlayreadyHeader.
11
+ * @see https://learn.microsoft.com/en-us/playready/specifications/playready-hea
12
+ * der-specification
13
+ */
14
+ export declare function generatePlayReadyInitData(playreadyHeader: string): Uint8Array;
@@ -0,0 +1,61 @@
1
+ import { itole4, itobe4, itole2, concat } from "../utils/byte_parsing";
2
+ import { strToUtf8, strToUtf16LE, hexToBytes } from "../utils/string_parsing";
3
+ /**
4
+ * The PlayReadyHeader sample that will be used to test if the CDM is supported.
5
+ * The KID does not matter because no content will be played, it's only to check if
6
+ * the CDM is capable of creating a session and generating a request.
7
+ */
8
+ export var DUMMY_PLAY_READY_HEADER =
9
+ /* eslint-disable-next-line max-len */
10
+ "<WRMHEADER xmlns=\"http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader\" version=\"4.0.0.0\"><DATA><PROTECTINFO><KEYLEN>16</KEYLEN><ALGID>AESCTR</ALGID></PROTECTINFO><KID>ckB07BNLskeUq0qd83fTbA==</KID><DS_ID>yYIPDBca1kmMfL60IsfgAQ==</DS_ID><CUSTOMATTRIBUTES xmlns=\"\"><encryptionref>312_4024_2018127108</encryptionref></CUSTOMATTRIBUTES><CHECKSUM>U/tsUYRgMzw=</CHECKSUM></DATA></WRMHEADER>";
11
+ /**
12
+ * Generate the "cenc" init data for playready from the PlayreadyHeader string.
13
+ * @param {string} playreadyHeader - String representing the PlayreadyHeader XML.
14
+ * @returns {Uint8Array} The init data generated for that PlayreadyHeader.
15
+ * @see https://learn.microsoft.com/en-us/playready/specifications/playready-hea
16
+ * der-specification
17
+ */
18
+ export function generatePlayReadyInitData(playreadyHeader) {
19
+ var recordValueEncoded = strToUtf16LE(playreadyHeader);
20
+ var recordLength = itole2(recordValueEncoded.length);
21
+ // RecordType: 0x0001 Indicates that the record contains a PlayReady Header (PRH).
22
+ var recordType = new Uint8Array([1, 0]);
23
+ var numberOfObjects = new Uint8Array([1, 0]); // 1 PlayReady object
24
+ /* playReadyObjectLength equals = X bytes for record + 2 bytes for record length,
25
+ + 2 bytes for record types + 2 bytes for number of object */
26
+ var playReadyObjectLength = itole4(recordValueEncoded.length + 6);
27
+ var playReadyObject = concat(playReadyObjectLength, // 4 bytes for the Playready object length
28
+ numberOfObjects, // 2 bytes for the number of PlayReady objects
29
+ recordType, // 2 bytes for record type
30
+ recordLength, // 2 bytes for record length
31
+ recordValueEncoded // X bytes for record value
32
+ );
33
+ /** the systemId is define at https://dashif.org/identifiers/content_protection/ */
34
+ var playreadySystemId = hexToBytes("9a04f07998404286ab92e65be0885f95");
35
+ return generateInitData(playReadyObject, playreadySystemId);
36
+ }
37
+ /**
38
+ * Generate the "cenc" initData given the data and the systemId to use.
39
+ * Note this will generate an initData for version 0 of pssh.
40
+ * @param data - The data that is contained inside the pssh.
41
+ * @param systemId - The systemId to use.
42
+ * @returns
43
+ */
44
+ function generateInitData(data, systemId) {
45
+ var psshBoxName = strToUtf8("pssh");
46
+ var versionAndFlags = new Uint8Array([0, 0, 0, 0]); // pssh version 0
47
+ var sizeOfData = itobe4(data.length);
48
+ var psshSize = itobe4(4 /* pssh size */ +
49
+ 4 /* pssh box */ +
50
+ 4 /* version and flags */ +
51
+ 16 /* systemId */ +
52
+ 4 /* size of data */ +
53
+ data.length /* data */);
54
+ return concat(psshSize, // 4 bytes for the pssh size
55
+ psshBoxName, // 4 bytes for the pssh box
56
+ versionAndFlags, // 4 bytes for version and flags
57
+ systemId, // 16 bytes for the systemId
58
+ sizeOfData, // 4 bytes for the data size
59
+ data // X bytes for data
60
+ );
61
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * We noticed that the PlayStation 5 may have the HTMLMediaElement on which the
3
+ * content is played stop on a `MEDIA_ERR_DECODE` error if it encounters
4
+ * encrypted media data whose key is not usable due to policy restrictions (the
5
+ * most usual issue being non-respect of HDCP restrictions).
6
+ *
7
+ * This is not an usual behavior, other platforms just do not attempt to decode
8
+ * the encrypted media data and stall the playback instead (which is a much
9
+ * preferable behavior for us as we have some advanced mechanism to restart
10
+ * playback when this happens).
11
+ *
12
+ * Consequently, we have to specifically consider platforms with that
13
+ * fail-on-undecipherable-data issue, to perform a work-around in that case.
14
+ */
15
+ declare const mayMediaElementFailOnUndecipherableData: boolean;
16
+ export default mayMediaElementFailOnUndecipherableData;
@@ -0,0 +1,17 @@
1
+ import { isPlayStation5 } from "./browser_detection";
2
+ /**
3
+ * We noticed that the PlayStation 5 may have the HTMLMediaElement on which the
4
+ * content is played stop on a `MEDIA_ERR_DECODE` error if it encounters
5
+ * encrypted media data whose key is not usable due to policy restrictions (the
6
+ * most usual issue being non-respect of HDCP restrictions).
7
+ *
8
+ * This is not an usual behavior, other platforms just do not attempt to decode
9
+ * the encrypted media data and stall the playback instead (which is a much
10
+ * preferable behavior for us as we have some advanced mechanism to restart
11
+ * playback when this happens).
12
+ *
13
+ * Consequently, we have to specifically consider platforms with that
14
+ * fail-on-undecipherable-data issue, to perform a work-around in that case.
15
+ */
16
+ var mayMediaElementFailOnUndecipherableData = isPlayStation5;
17
+ export default mayMediaElementFailOnUndecipherableData;
@@ -21,4 +21,4 @@
21
21
  * @param {Boolean} isDirectfile
22
22
  * @returns {Boolean}
23
23
  */
24
- export default function shouldWaitForDataBeforeLoaded(isDirectfile: boolean, mustPlayInline: boolean): boolean;
24
+ export default function shouldWaitForDataBeforeLoaded(isDirectfile: boolean): boolean;
@@ -22,9 +22,11 @@ import { isSafariMobile } from "./browser_detection";
22
22
  * @param {Boolean} isDirectfile
23
23
  * @returns {Boolean}
24
24
  */
25
- export default function shouldWaitForDataBeforeLoaded(isDirectfile, mustPlayInline) {
25
+ export default function shouldWaitForDataBeforeLoaded(isDirectfile) {
26
26
  if (isDirectfile && isSafariMobile) {
27
- return mustPlayInline;
27
+ return false;
28
+ }
29
+ else {
30
+ return true;
28
31
  }
29
- return true;
30
32
  }
@@ -121,6 +121,8 @@ declare class ConfigHandler {
121
121
  UNFREEZING_SEEK_DELAY: number;
122
122
  FREEZING_STALLED_DELAY: number;
123
123
  UNFREEZING_DELTA_POSITION: number;
124
+ SEGMENT_SYNCHRONIZATION_DELAY: number;
125
+ MISSING_DATA_TRIGGER_SYNC_DELAY: number;
124
126
  MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT: number;
125
127
  MAX_MANIFEST_BUFFERED_START_END_DIFFERENCE: number;
126
128
  MAX_MANIFEST_BUFFERED_DURATION_DIFFERENCE: number;
@@ -222,7 +222,7 @@ function getEstimateReference(_a, stopAllEstimates) {
222
222
  var manualRepresentation = selectOptimalRepresentation(representations, manualBitrateVal, 0, Infinity);
223
223
  return {
224
224
  representation: manualRepresentation,
225
- bitrate: undefined,
225
+ bitrate: undefined, // Bitrate estimation is deactivated here
226
226
  knownStableBitrate: undefined,
227
227
  manual: true,
228
228
  urgent: true, // a manual bitrate switch should happen immediately
@@ -4,9 +4,9 @@ var COLORS = [
4
4
  "#fed766",
5
5
  "#4dd248",
6
6
  "#a22c28",
7
- "#556b2f",
8
- "#add8e6",
9
- "#90ee90",
7
+ "#556b2f", // darkolivegreen
8
+ "#add8e6", // lightblue
9
+ "#90ee90", // lightgreen
10
10
  "#444444",
11
11
  "#40bfc1",
12
12
  "#57557e",
@@ -30,6 +30,12 @@ declare class Player extends EventEmitter<IPublicAPIEvent> {
30
30
  static version: string;
31
31
  /** Current version of the RxPlayer. */
32
32
  readonly version: string;
33
+ /**
34
+ * Store all video elements currently in use by an RxPlayer instance.
35
+ * This is used to check that a video element is not shared between multiple instances.
36
+ * Use of a WeakSet ensure the object is garbage collected if it's not used anymore.
37
+ */
38
+ private static _priv_currentlyUsedVideoElements;
33
39
  /**
34
40
  * Media element attached to the RxPlayer.
35
41
  * Set to `null` when the RxPlayer is disposed.
@@ -132,6 +138,17 @@ declare class Player extends EventEmitter<IPublicAPIEvent> {
132
138
  * @param {Array.<Object>} featureList - Features wanted.
133
139
  */
134
140
  static addFeatures(featureList: IFeature[]): void;
141
+ /**
142
+ * Register the video element to the set of elements currently in use.
143
+ * @param videoElement the video element to register.
144
+ * @throws Error - Throws if the element is already used by another player instance.
145
+ */
146
+ private static _priv_registerVideoElement;
147
+ /**
148
+ * Deregister the video element of the set of elements currently in use.
149
+ * @param videoElement the video element to deregister.
150
+ */
151
+ static _priv_deregisterVideoElement(videoElement: HTMLMediaElement): void;
135
152
  /**
136
153
  * @constructor
137
154
  * @param {Object} options
@@ -88,10 +88,11 @@ 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.2";
91
+ _this.version = /* PLAYER_VERSION */ "3.33.3";
92
92
  _this.log = log;
93
93
  _this.state = "STOPPED";
94
94
  _this.videoElement = videoElement;
95
+ Player._priv_registerVideoElement(_this.videoElement);
95
96
  var destroyCanceller = new TaskCanceller();
96
97
  _this._destroyCanceller = destroyCanceller;
97
98
  _this._priv_pictureInPictureRef = getPictureOnPictureStateRef(videoElement, destroyCanceller.signal);
@@ -218,6 +219,37 @@ var Player = /** @class */ (function (_super) {
218
219
  Player.addFeatures = function (featureList) {
219
220
  addFeatures(featureList);
220
221
  };
222
+ /**
223
+ * Register the video element to the set of elements currently in use.
224
+ * @param videoElement the video element to register.
225
+ * @throws Error - Throws if the element is already used by another player instance.
226
+ */
227
+ Player._priv_registerVideoElement = function (videoElement) {
228
+ if (Player._priv_currentlyUsedVideoElements.has(videoElement)) {
229
+ var errorMessage = "The video element is already attached to another RxPlayer instance." +
230
+ "\nMake sure to dispose the previous instance with player.dispose() " +
231
+ "before creating a new player instance attaching that video element.";
232
+ // eslint-disable-next-line no-console
233
+ console.warn(errorMessage);
234
+ /*
235
+ * TODO: for next major version 5.0: this need to throw an error instead
236
+ * of just logging this was not done for minor version as it could be
237
+ * considerated a breaking change.
238
+ *
239
+ * throw new Error(errorMessage);
240
+ */
241
+ }
242
+ Player._priv_currentlyUsedVideoElements.add(videoElement);
243
+ };
244
+ /**
245
+ * Deregister the video element of the set of elements currently in use.
246
+ * @param videoElement the video element to deregister.
247
+ */
248
+ Player._priv_deregisterVideoElement = function (videoElement) {
249
+ if (Player._priv_currentlyUsedVideoElements.has(videoElement)) {
250
+ Player._priv_currentlyUsedVideoElements.delete(videoElement);
251
+ }
252
+ };
221
253
  /**
222
254
  * Register a new callback for a player event event.
223
255
  *
@@ -253,6 +285,7 @@ var Player = /** @class */ (function (_super) {
253
285
  // free resources linked to the loaded content
254
286
  this.stop();
255
287
  if (this.videoElement !== null) {
288
+ Player._priv_deregisterVideoElement(this.videoElement);
256
289
  // free resources used for decryption management
257
290
  disposeDecryptionResources(this.videoElement)
258
291
  .catch(function (err) {
@@ -2470,7 +2503,13 @@ var Player = /** @class */ (function (_super) {
2470
2503
  });
2471
2504
  return mediaElementTrackChoiceManager;
2472
2505
  };
2506
+ /**
2507
+ * Store all video elements currently in use by an RxPlayer instance.
2508
+ * This is used to check that a video element is not shared between multiple instances.
2509
+ * Use of a WeakSet ensure the object is garbage collected if it's not used anymore.
2510
+ */
2511
+ Player._priv_currentlyUsedVideoElements = new WeakSet();
2473
2512
  return Player;
2474
2513
  }(EventEmitter));
2475
- Player.version = /* PLAYER_VERSION */ "3.33.2";
2514
+ Player.version = /* PLAYER_VERSION */ "3.33.3";
2476
2515
  export default Player;
@@ -64,20 +64,20 @@ function createAudioTracks(audioTracks) {
64
64
  var languagesOccurences = {};
65
65
  for (var i = 0; i < audioTracks.length; i++) {
66
66
  var audioTrack = audioTracks[i];
67
- var language = audioTrack.language === "" ? "nolang" :
68
- audioTrack.language;
67
+ var language = audioTrack.language === "" ? "nolang" : audioTrack.language;
69
68
  var occurences = (_a = languagesOccurences[language]) !== null && _a !== void 0 ? _a : 1;
70
- var id = "gen_audio_" +
71
- language +
72
- "_" +
73
- occurences.toString();
69
+ var id = "gen_audio_" + language + "_" + occurences.toString();
74
70
  languagesOccurences[language] = occurences + 1;
75
- var track = { language: audioTrack.language, id: id, normalized: normalizeLanguage(audioTrack.language),
71
+ var track = {
72
+ language: audioTrack.language,
73
+ id: id,
74
+ normalized: normalizeLanguage(audioTrack.language),
76
75
  audioDescription: audioTrack.kind === "descriptions" ||
77
76
  // Safari seem to prefer the non-standard singular
78
77
  // version, funnily enough
79
78
  audioTrack.kind === "description",
80
- representations: [] };
79
+ representations: [],
80
+ };
81
81
  newAudioTracks.push({ track: track, nativeTrack: audioTrack });
82
82
  }
83
83
  return newAudioTracks;
@@ -93,23 +93,23 @@ function createTextTracks(textTracks) {
93
93
  var languagesOccurences = {};
94
94
  for (var i = 0; i < textTracks.length; i++) {
95
95
  var textTrack = textTracks[i];
96
- var language = textTrack.language === "" ? "nolang" :
97
- textTrack.language;
96
+ var language = textTrack.language === "" ? "nolang" : textTrack.language;
98
97
  var occurences = (_a = languagesOccurences[language]) !== null && _a !== void 0 ? _a : 1;
99
- var id = "gen_text_" +
100
- language +
101
- "_" +
102
- occurences.toString();
98
+ var id = "gen_text_" + language + "_" + occurences.toString();
103
99
  languagesOccurences[language] = occurences + 1;
104
100
  // Safari seems to be indicating that the subtitles track is a forced
105
101
  // subtitles track by setting the `kind` attribute to `"forced"`.
106
102
  // As of now (2023-04-04), this is not standard.
107
103
  // @see https://github.com/whatwg/html/issues/4472
108
- var forced = textTrack.kind === "forced" ?
109
- true :
110
- undefined;
111
- var track = { language: textTrack.language, forced: forced, label: textTrack.label, id: id, normalized: normalizeLanguage(textTrack.language),
112
- closedCaption: textTrack.kind === "captions" };
104
+ var forced = textTrack.kind === "forced" ? true : undefined;
105
+ var track = {
106
+ language: textTrack.language,
107
+ forced: forced,
108
+ label: textTrack.label,
109
+ id: id,
110
+ normalized: normalizeLanguage(textTrack.language),
111
+ closedCaption: textTrack.kind === "captions",
112
+ };
113
113
  newTextTracks.push({ track: track, nativeTrack: textTrack });
114
114
  }
115
115
  return newTextTracks;
@@ -125,13 +125,9 @@ function createVideoTracks(videoTracks) {
125
125
  var languagesOccurences = {};
126
126
  for (var i = 0; i < videoTracks.length; i++) {
127
127
  var videoTrack = videoTracks[i];
128
- var language = videoTrack.language === "" ? "nolang" :
129
- videoTrack.language;
128
+ var language = videoTrack.language === "" ? "nolang" : videoTrack.language;
130
129
  var occurences = (_a = languagesOccurences[language]) !== null && _a !== void 0 ? _a : 1;
131
- var id = "gen_video_" +
132
- language +
133
- "_" +
134
- occurences.toString();
130
+ var id = "gen_video_" + language + "_" + occurences.toString();
135
131
  languagesOccurences[language] = occurences + 1;
136
132
  newVideoTracks.push({ track: { id: id, representations: [] },
137
133
  nativeTrack: videoTrack });
@@ -77,12 +77,12 @@ export function disableMediaKeys(mediaElement) {
77
77
  * @param {Object} cancelSignal
78
78
  * @returns {Promise}
79
79
  */
80
- export default function attachMediaKeys(mediaElement, _a, cancelSignal) {
81
- var emeImplementation = _a.emeImplementation, keySystemOptions = _a.keySystemOptions, loadedSessionsStore = _a.loadedSessionsStore, mediaKeySystemAccess = _a.mediaKeySystemAccess, mediaKeys = _a.mediaKeys;
82
- return __awaiter(this, void 0, void 0, function () {
80
+ export default function attachMediaKeys(mediaElement_1, _a, cancelSignal_1) {
81
+ return __awaiter(this, arguments, void 0, function (mediaElement, _b, cancelSignal) {
83
82
  var previousState, closeAllSessions;
84
- return __generator(this, function (_b) {
85
- switch (_b.label) {
83
+ var emeImplementation = _b.emeImplementation, keySystemOptions = _b.keySystemOptions, loadedSessionsStore = _b.loadedSessionsStore, mediaKeySystemAccess = _b.mediaKeySystemAccess, mediaKeys = _b.mediaKeys;
84
+ return __generator(this, function (_c) {
85
+ switch (_c.label) {
86
86
  case 0:
87
87
  previousState = MediaKeysInfosStore.getState(mediaElement);
88
88
  closeAllSessions = previousState !== null &&
@@ -91,7 +91,7 @@ export default function attachMediaKeys(mediaElement, _a, cancelSignal) {
91
91
  Promise.resolve();
92
92
  return [4 /*yield*/, closeAllSessions];
93
93
  case 1:
94
- _b.sent();
94
+ _c.sent();
95
95
  // If this task has been cancelled while we were closing previous sessions,
96
96
  // stop now (and thus avoid setting the new media keys);
97
97
  if (cancelSignal.isCancelled()) {
@@ -46,3 +46,13 @@ export type IFoundMediaKeySystemAccessEvent = IReuseMediaKeySystemAccessEvent |
46
46
  * @returns {Promise.<Object>}
47
47
  */
48
48
  export default function getMediaKeySystemAccess(mediaElement: HTMLMediaElement, keySystemsConfigs: IKeySystemOption[], cancelSignal: CancellationSignal): Promise<IFoundMediaKeySystemAccessEvent>;
49
+ /**
50
+ * Test a key system configuration, resolves with the MediaKeySystemAccess
51
+ * or reject if the key system is unsupported.
52
+ * @param {string} keyType - The KeySystem string to test
53
+ * (ex: com.microsoft.playready.recommendation)
54
+ * @param {Array.<MediaKeySystemMediaCapability>} keySystemConfigurations -
55
+ * Configurations for this keySystem
56
+ * @returns Promise resolving with the MediaKeySystemAccess. Rejects if unsupported.
57
+ */
58
+ export declare function testKeySystem(keyType: string, keySystemConfigurations: MediaKeySystemConfiguration[]): Promise<MediaKeySystemAccess | import("../../compat/eme/custom_key_system_access").default>;
@@ -61,7 +61,9 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
61
61
  }
62
62
  };
63
63
  import { shouldRenewMediaKeySystemAccess, } from "../../compat";
64
+ import { canRelyOnRequestMediaKeySystemAccess, } from "../../compat/can_rely_on_request_media_key_system_access";
64
65
  import eme from "../../compat/eme";
66
+ import { generatePlayReadyInitData, DUMMY_PLAY_READY_HEADER, } from "../../compat/generate_init_data";
65
67
  import config from "../../config";
66
68
  import { EncryptedMediaError } from "../../errors";
67
69
  import log from "../../log";
@@ -311,7 +313,7 @@ export default function getMediaKeySystemAccess(mediaElement, keySystemsConfigs,
311
313
  _b.label = 1;
312
314
  case 1:
313
315
  _b.trys.push([1, 3, , 4]);
314
- return [4 /*yield*/, eme.requestMediaKeySystemAccess(keyType, keySystemConfigurations)];
316
+ return [4 /*yield*/, testKeySystem(keyType, keySystemConfigurations)];
315
317
  case 2:
316
318
  keySystemAccess = _b.sent();
317
319
  log.info("DRM: Found compatible keysystem", keyType, index + 1);
@@ -331,3 +333,42 @@ export default function getMediaKeySystemAccess(mediaElement, keySystemsConfigs,
331
333
  });
332
334
  }
333
335
  }
336
+ /**
337
+ * Test a key system configuration, resolves with the MediaKeySystemAccess
338
+ * or reject if the key system is unsupported.
339
+ * @param {string} keyType - The KeySystem string to test
340
+ * (ex: com.microsoft.playready.recommendation)
341
+ * @param {Array.<MediaKeySystemMediaCapability>} keySystemConfigurations -
342
+ * Configurations for this keySystem
343
+ * @returns Promise resolving with the MediaKeySystemAccess. Rejects if unsupported.
344
+ */
345
+ export function testKeySystem(keyType, keySystemConfigurations) {
346
+ return __awaiter(this, void 0, void 0, function () {
347
+ var keySystemAccess, mediaKeys, session, initData, err_1;
348
+ return __generator(this, function (_a) {
349
+ switch (_a.label) {
350
+ case 0: return [4 /*yield*/, eme.requestMediaKeySystemAccess(keyType, keySystemConfigurations)];
351
+ case 1:
352
+ keySystemAccess = _a.sent();
353
+ if (!!canRelyOnRequestMediaKeySystemAccess(keyType)) return [3 /*break*/, 6];
354
+ _a.label = 2;
355
+ case 2:
356
+ _a.trys.push([2, 5, , 6]);
357
+ return [4 /*yield*/, keySystemAccess.createMediaKeys()];
358
+ case 3:
359
+ mediaKeys = _a.sent();
360
+ session = mediaKeys.createSession();
361
+ initData = generatePlayReadyInitData(DUMMY_PLAY_READY_HEADER);
362
+ return [4 /*yield*/, session.generateRequest("cenc", initData)];
363
+ case 4:
364
+ _a.sent();
365
+ return [3 /*break*/, 6];
366
+ case 5:
367
+ err_1 = _a.sent();
368
+ log.debug("DRM: KeySystemAccess was granted but it is not usable");
369
+ throw err_1;
370
+ case 6: return [2 /*return*/, keySystemAccess];
371
+ }
372
+ });
373
+ });
374
+ }
@@ -360,7 +360,7 @@ function updateSessionWithMessage(session, message) {
360
360
  var BlacklistedSessionError = /** @class */ (function (_super) {
361
361
  __extends(BlacklistedSessionError, _super);
362
362
  function BlacklistedSessionError(sessionError) {
363
- var _this = _super.call(this) || this;
363
+ var _this = _super.call(this, sessionError.message) || this;
364
364
  // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class
365
365
  Object.setPrototypeOf(_this, BlacklistedSessionError.prototype);
366
366
  _this.sessionError = sessionError;
@@ -377,7 +377,7 @@ export { BlacklistedSessionError };
377
377
  var GetLicenseTimeoutError = /** @class */ (function (_super) {
378
378
  __extends(GetLicenseTimeoutError, _super);
379
379
  function GetLicenseTimeoutError(message) {
380
- var _this = _super.call(this) || this;
380
+ var _this = _super.call(this, message) || this;
381
381
  // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class
382
382
  Object.setPrototypeOf(_this, BlacklistedSessionError.prototype);
383
383
  _this.message = message;
@@ -182,7 +182,6 @@ var ManifestFetcher = /** @class */ (function (_super) {
182
182
  * @returns {Promise}
183
183
  */
184
184
  ManifestFetcher.prototype._fetchManifest = function (url) {
185
- var _a;
186
185
  return __awaiter(this, void 0, void 0, function () {
187
186
  /**
188
187
  * Call the resolver part of the pipeline, retrying if it fails according
@@ -218,6 +217,7 @@ var ManifestFetcher = /** @class */ (function (_super) {
218
217
  }
219
218
  var cancelSignal, settings, pipelines, requestUrl, backoffSettings, loadingPromise, response_1, err_1;
220
219
  var _this = this;
220
+ var _a;
221
221
  return __generator(this, function (_b) {
222
222
  switch (_b.label) {
223
223
  case 0:
@@ -277,7 +277,6 @@ var ManifestFetcher = /** @class */ (function (_super) {
277
277
  * @returns {Promise}
278
278
  */
279
279
  ManifestFetcher.prototype._parseLoadedManifest = function (loaded, parserOptions, requestUrl) {
280
- var _a;
281
280
  return __awaiter(this, void 0, void 0, function () {
282
281
  /**
283
282
  * Perform a request with the same retry mechanisms and error handling
@@ -334,6 +333,7 @@ var ManifestFetcher = /** @class */ (function (_super) {
334
333
  }
335
334
  var parsingTimeStart, cancelSignal, trigger, sendingTime, receivedTime, backoffSettings, originalUrl, opts, res, manifest, err_2, formattedError;
336
335
  var _this = this;
336
+ var _a;
337
337
  return __generator(this, function (_b) {
338
338
  switch (_b.label) {
339
339
  case 0:
@@ -109,7 +109,6 @@ export default function createSegmentFetcher(bufferType, pipeline, cdnPrioritize
109
109
  * @returns {Promise}
110
110
  */
111
111
  return function fetchSegment(content, fetcherCallbacks, cancellationSignal) {
112
- var _a, _b, _c;
113
112
  return __awaiter(this, void 0, void 0, function () {
114
113
  function onCancellation() {
115
114
  var _a;
@@ -190,6 +189,7 @@ export default function createSegmentFetcher(bufferType, pipeline, cdnPrioritize
190
189
  }
191
190
  }
192
191
  var segmentIdString, requestId, requestInfo, parsedChunks, segmentDurationAcc, metricsSent, loaderCallbacks, cached, res, loadedData, err_1;
192
+ var _a, _b, _c;
193
193
  return __generator(this, function (_d) {
194
194
  switch (_d.label) {
195
195
  case 0: