rx-player 4.0.0-alpha.2023012000 → 4.0.0-beta.0

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 (45) hide show
  1. package/CHANGELOG.md +18 -2
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/compat/event_listeners.d.ts +24 -4
  4. package/dist/_esm5.processed/compat/event_listeners.js +72 -37
  5. package/dist/_esm5.processed/compat/should_reload_media_source_on_decipherability_update.d.ts +2 -2
  6. package/dist/_esm5.processed/compat/should_reload_media_source_on_decipherability_update.js +2 -2
  7. package/dist/_esm5.processed/config.d.ts +1 -1
  8. package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.d.ts +3 -2
  9. package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +12 -11
  10. package/dist/_esm5.processed/core/adaptive/utils/{filter_by_width.d.ts → filter_by_resolution.d.ts} +11 -5
  11. package/dist/_esm5.processed/core/adaptive/utils/{filter_by_width.js → filter_by_resolution.js} +14 -6
  12. package/dist/_esm5.processed/core/api/option_utils.d.ts +1 -1
  13. package/dist/_esm5.processed/core/api/option_utils.js +5 -5
  14. package/dist/_esm5.processed/core/api/public_api.d.ts +12 -9
  15. package/dist/_esm5.processed/core/api/public_api.js +35 -23
  16. package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.d.ts +5 -5
  17. package/dist/_esm5.processed/core/decrypt/{get_current_key_system.d.ts → get_key_system_configuration.d.ts} +4 -3
  18. package/dist/_esm5.processed/core/decrypt/{get_current_key_system.js → get_key_system_configuration.js} +11 -5
  19. package/dist/_esm5.processed/core/decrypt/index.d.ts +2 -2
  20. package/dist/_esm5.processed/core/decrypt/index.js +2 -2
  21. package/dist/_esm5.processed/core/init/media_source_content_initializer.js +3 -3
  22. package/dist/_esm5.processed/default_config.d.ts +6 -5
  23. package/dist/_esm5.processed/default_config.js +6 -5
  24. package/dist/_esm5.processed/public_types.d.ts +8 -1
  25. package/dist/rx-player.js +177 -107
  26. package/dist/rx-player.min.js +1 -1
  27. package/package.json +11 -11
  28. package/sonar-project.properties +1 -1
  29. package/src/compat/__tests__/should_reload_media_source_on_decipherability_update.test.ts +1 -1
  30. package/src/compat/event_listeners.ts +108 -40
  31. package/src/compat/should_reload_media_source_on_decipherability_update.ts +3 -3
  32. package/src/core/adaptive/adaptive_representation_selector.ts +24 -17
  33. package/src/core/adaptive/utils/__tests__/filter_by_resolution.test.ts +82 -0
  34. package/src/core/adaptive/utils/{filter_by_width.ts → filter_by_resolution.ts} +21 -7
  35. package/src/core/api/__tests__/option_utils.test.ts +11 -7
  36. package/src/core/api/option_utils.ts +8 -7
  37. package/src/core/api/public_api.ts +42 -27
  38. package/src/core/decrypt/{get_current_key_system.ts → get_key_system_configuration.ts} +12 -6
  39. package/src/core/decrypt/index.ts +2 -2
  40. package/src/core/init/media_source_content_initializer.ts +3 -3
  41. package/src/default_config.ts +6 -5
  42. package/src/manifest/__tests__/period.test.ts +8 -4
  43. package/src/public_types.ts +11 -2
  44. package/a.js +0 -381
  45. package/src/core/adaptive/utils/__tests__/filter_by_width.test.ts +0 -60
package/CHANGELOG.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Changelog
2
2
 
3
- ## v4.0.0-alpha.2022110300 (2022-11-03)
3
+ ## v4.0.0-beta.0 (2023-01-27)
4
4
 
5
- ### Changed
5
+ ### Changes
6
6
 
7
7
  - Create `"FREEZING"` player state for cases where the playback position is currently not advancing due to an unknown reason, to separate it from regular `"BUFFERING"`. [#1146]
8
8
  - The `RELOADING` player state (gettable through the `getPlayerState` and `playerStateChange` API) can now happen at any time to unlock playback.
@@ -17,6 +17,7 @@
17
17
  - Remove `audioBitrateChange` and `videoBitrateChange` events in profit of the new `audioRepresentationChange` and `videoRepresentationChange` events
18
18
  - Remove `availableAudioBitratesChange` and `availableVideoBitratesChange` events. Those are less needed with the new Representations lock API and can be mostly replicated through the `audioTrackChange` and `videoTrackChange` events
19
19
  - "Flatten" the `transportOptions` loadVideo options by putting all its inner properties directly at the top level of loadVideo options, to simplify its documentation and discoverability [#1149]
20
+ - Remove `limitVideoWidth` constructor option in profit of the more configurable `videoResolutionLimit` constructor option
20
21
  - Rename `networkConfig` into `requestConfig` and re-organize its inner properties to pave the way for future request-related APIs.
21
22
  - Remove `stopAtEnd` `loadVideo` option and don't automatically stop when reaching the end by default. This behavior can be counter-intuitive and can be very easily implemented by the application.
22
23
  - Remove `decipherabilityUpdate` event as it appeared to be not easily exploitable and exposed internal logic too much [#1168]
@@ -74,7 +75,10 @@
74
75
  - Add `lockVideoRepresentations`, `lockAudioRepresentations`, `getLockedVideoRepresentations`, `getLockedAudioRepresentations`, `unlockVideoRepresentations` and `unlockAudioRepresentations` methods to allow a complex selection of Representations that are currently allowed to play.
75
76
  - Add `getVideoRepresentation` and `getAudioRepresentation` method to retrieve information on the currently loaded representations [#1144]
76
77
  - Add `audioRepresentationChange` and `videoRepresentationChange` events to be notified when the currently-loaded Representation for the current Period changes.
78
+ - Add `updateContentUrls` API, allowing to update the Manifest's URL during playback [#1182]
79
+ - DASH: implement forced-subtitles, adding the `forced` property to the audio tracks API and selecting by default a forced text track linked to the audio track's language if present [#1187]
77
80
  - Add `getContentUrls` allowing to retrieve the one or several known URLs through which the current Manifest or content is reachable.
81
+ - Add `videoResolutionLimit` constructor option allowing to automatically limit a video Representation's resolution.
78
82
  - Add `newAvailablePeriods` event to signal new Period on which a track and/or Representation choice can be made
79
83
  - Add `brokenRepresentationsLock` event for when a Representations lock could not be respected anymore
80
84
  - Add `trackUpdate` event for when a track has been updated for any type and Period
@@ -99,6 +103,18 @@
99
103
  - Add `IVideoTrackSetting` public type to define the object that may be given to the `setVideoTrack` method
100
104
  - Add `ITextTrackSetting` public type to define the object that may be given to the `setTextTrack` method
101
105
 
106
+ ### Bug fixes
107
+
108
+ - Fix segment requesting error when playing a DASH content without an url and without BaseURL elements [#1192]
109
+ - API: Stop sending events if the content is stopped due to a side-effect of one of the event handler [#1197]
110
+ - text-tracks/ttml: fix inconsistent line spacing when resizing the `textTrackElement` [#1191]
111
+ - DRM: Fix race condition leading to a JS error instead of a `NO_PLAYABLE_REPRESENTATION` [#1201]
112
+ - DRM/Compat: Renew MediaKeys at each `loadVideo` on all WebOS (LG TV) platforms to work around issues [#1188]
113
+
114
+ ### Other improvements
115
+
116
+ - Remove dependency to RxJS, improving the debugging experience and preventing some uncaught Error from being thrown
117
+
102
118
 
103
119
  ## v3.29.0 (2022-11-16)
104
120
 
package/VERSION CHANGED
@@ -1 +1 @@
1
- 4.0.0-alpha.2023012000
1
+ 4.0.0-beta.0
@@ -22,6 +22,12 @@ export interface IEventEmitterLike {
22
22
  removeEventListener: (eventName: string, handler: () => void) => void;
23
23
  }
24
24
  export type IEventTargetLike = HTMLElement | IEventEmitterLike | IEventEmitter<unknown>;
25
+ /**
26
+ * Get video width from Picture-in-Picture window
27
+ * @param {HTMLMediaElement} mediaElement
28
+ * @param {Object} pipWindow
29
+ * @returns {number}
30
+ */
25
31
  export interface IPictureInPictureEvent {
26
32
  isEnabled: boolean;
27
33
  pipWindow: ICompatPictureInPictureWindow | null;
@@ -45,14 +51,28 @@ declare function getPictureOnPictureStateRef(elt: HTMLMediaElement, stopListenin
45
51
  */
46
52
  declare function getVideoVisibilityRef(pipStatus: IReadOnlySharedReference<IPictureInPictureEvent>, stopListening: CancellationSignal): IReadOnlySharedReference<boolean>;
47
53
  /**
48
- * Get video width from HTML video element, or video estimated dimensions
49
- * when Picture-in-Picture is activated.
54
+ * Get video width and height from the screen dimensions.
55
+ * @param {Object} stopListening
56
+ * @returns {Object}
57
+ */
58
+ declare function getScreenResolutionRef(stopListening: CancellationSignal): IReadOnlySharedReference<{
59
+ width: number | undefined;
60
+ height: number | undefined;
61
+ pixelRatio: number;
62
+ }>;
63
+ /**
64
+ * Get video width and height from HTML media element, or video estimated
65
+ * dimensions when Picture-in-Picture is activated.
50
66
  * @param {HTMLMediaElement} mediaElement
51
67
  * @param {Object} pipStatusRef
52
68
  * @param {Object} stopListening
53
69
  * @returns {Object}
54
70
  */
55
- declare function getVideoWidthRef(mediaElement: HTMLMediaElement, pipStatusRef: IReadOnlySharedReference<IPictureInPictureEvent>, stopListening: CancellationSignal): IReadOnlySharedReference<number>;
71
+ declare function getElementResolutionRef(mediaElement: HTMLMediaElement, pipStatusRef: IReadOnlySharedReference<IPictureInPictureEvent>, stopListening: CancellationSignal): IReadOnlySharedReference<{
72
+ width: number | undefined;
73
+ height: number | undefined;
74
+ pixelRatio: number;
75
+ }>;
56
76
  /**
57
77
  * @param {HTMLMediaElement} mediaElement
58
78
  */
@@ -142,4 +162,4 @@ declare const onEnded: (element: IEventTargetLike, listener: (event?: unknown) =
142
162
  * emits
143
163
  */
144
164
  declare function addEventListener(elt: IEventEmitterLike, evt: string, listener: (x?: unknown) => void, stopListening: CancellationSignal): void;
145
- export { addEventListener, getPictureOnPictureStateRef, getVideoVisibilityRef, getVideoWidthRef, onEncrypted, onEnded, onKeyAdded, onKeyError, onKeyMessage, onKeyStatusesChange, onLoadedMetadata, onRemoveSourceBuffers, onSeeked, onSeeking, onSourceClose, onSourceEnded, onSourceOpen, onTimeUpdate, onSourceBufferUpdate, onTextTrackAdded, onTextTrackRemoved, };
165
+ export { addEventListener, getPictureOnPictureStateRef, getVideoVisibilityRef, getElementResolutionRef, getScreenResolutionRef, onEncrypted, onEnded, onKeyAdded, onKeyError, onKeyMessage, onKeyStatusesChange, onLoadedMetadata, onRemoveSourceBuffers, onSeeked, onSeeking, onSourceClose, onSourceEnded, onSourceOpen, onTimeUpdate, onSourceBufferUpdate, onTextTrackAdded, onTextTrackRemoved, };
@@ -19,13 +19,8 @@ import isNonEmptyString from "../utils/is_non_empty_string";
19
19
  import isNullOrUndefined from "../utils/is_null_or_undefined";
20
20
  import noop from "../utils/noop";
21
21
  import createSharedReference from "../utils/reference";
22
- import isNode from "./is_node";
23
22
  import shouldFavourCustomSafariEME from "./should_favour_custom_safari_EME";
24
23
  var BROWSER_PREFIXES = ["", "webkit", "moz", "ms"];
25
- var pixelRatio = isNode ||
26
- window.devicePixelRatio == null ||
27
- window.devicePixelRatio === 0 ? 1 :
28
- window.devicePixelRatio;
29
24
  /**
30
25
  * Find the first supported event from the list given.
31
26
  * @param {HTMLElement} element
@@ -167,18 +162,6 @@ function getDocumentVisibilityRef(stopListening) {
167
162
  }, stopListening);
168
163
  return ref;
169
164
  }
170
- /**
171
- * Get video width from Picture-in-Picture window
172
- * @param {HTMLMediaElement} mediaElement
173
- * @param {Object} pipWindow
174
- * @returns {number}
175
- */
176
- function getVideoWidthFromPIPWindow(mediaElement, pipWindow) {
177
- var width = pipWindow.width, height = pipWindow.height;
178
- var videoRatio = mediaElement.clientHeight / mediaElement.clientWidth;
179
- var calcWidth = height / videoRatio;
180
- return Math.min(width, calcWidth);
181
- }
182
165
  /**
183
166
  * Emit when video enters and leaves Picture-In-Picture mode.
184
167
  * @param {HTMLMediaElement} elt
@@ -252,46 +235,98 @@ function getVideoVisibilityRef(pipStatus, stopListening) {
252
235
  }
253
236
  }
254
237
  /**
255
- * Get video width from HTML video element, or video estimated dimensions
256
- * when Picture-in-Picture is activated.
238
+ * Get video width and height from the screen dimensions.
239
+ * @param {Object} stopListening
240
+ * @returns {Object}
241
+ */
242
+ function getScreenResolutionRef(stopListening) {
243
+ var pixelRatio = window.devicePixelRatio == null ||
244
+ window.devicePixelRatio === 0 ? 1 :
245
+ window.devicePixelRatio;
246
+ var ref = createSharedReference({ width: window.screen.width,
247
+ height: window.screen.height, pixelRatio: pixelRatio }, stopListening);
248
+ var interval = window.setInterval(checkScreenResolution, 20000);
249
+ stopListening.register(function stopUpdating() {
250
+ clearInterval(interval);
251
+ });
252
+ return ref;
253
+ function checkScreenResolution() {
254
+ var oldVal = ref.getValue();
255
+ if (oldVal.width !== screen.width ||
256
+ oldVal.height !== screen.height ||
257
+ oldVal.pixelRatio !== pixelRatio) {
258
+ ref.setValue({ width: screen.width,
259
+ height: screen.height, pixelRatio: pixelRatio });
260
+ }
261
+ }
262
+ }
263
+ /**
264
+ * Get video width and height from HTML media element, or video estimated
265
+ * dimensions when Picture-in-Picture is activated.
257
266
  * @param {HTMLMediaElement} mediaElement
258
267
  * @param {Object} pipStatusRef
259
268
  * @param {Object} stopListening
260
269
  * @returns {Object}
261
270
  */
262
- function getVideoWidthRef(mediaElement, pipStatusRef, stopListening) {
263
- var ref = createSharedReference(mediaElement.clientWidth * pixelRatio, stopListening);
271
+ function getElementResolutionRef(mediaElement, pipStatusRef, stopListening) {
272
+ var pixelRatio = window.devicePixelRatio == null ||
273
+ window.devicePixelRatio === 0 ? 1 :
274
+ window.devicePixelRatio;
275
+ var ref = createSharedReference({ width: mediaElement.clientWidth,
276
+ height: mediaElement.clientHeight, pixelRatio: pixelRatio }, stopListening);
264
277
  var clearPreviousEventListener = noop;
265
- pipStatusRef.onUpdate(checkVideoWidth, { clearSignal: stopListening });
266
- addEventListener(window, "resize", checkVideoWidth, stopListening);
267
- var interval = window.setInterval(checkVideoWidth, 20000);
268
- checkVideoWidth();
269
- stopListening.register(function stopUpdatingVideoWidthRef() {
278
+ pipStatusRef.onUpdate(checkElementResolution, { clearSignal: stopListening });
279
+ addEventListener(window, "resize", checkElementResolution, stopListening);
280
+ addEventListener(mediaElement, "enterpictureinpicture", checkElementResolution, stopListening);
281
+ addEventListener(mediaElement, "leavepictureinpicture", checkElementResolution, stopListening);
282
+ var interval = window.setInterval(checkElementResolution, 20000);
283
+ checkElementResolution();
284
+ stopListening.register(function stopUpdating() {
270
285
  clearPreviousEventListener();
271
286
  clearInterval(interval);
272
287
  });
273
288
  return ref;
274
- function checkVideoWidth() {
289
+ function checkElementResolution() {
275
290
  clearPreviousEventListener();
276
291
  var pipStatus = pipStatusRef.getValue();
292
+ var pipWindow = pipStatus.pipWindow;
277
293
  if (!pipStatus.isEnabled) {
278
- ref.setValueIfChanged(mediaElement.clientWidth * pixelRatio);
294
+ var oldVal = ref.getValue();
295
+ if (oldVal.width !== mediaElement.clientWidth ||
296
+ oldVal.height !== mediaElement.clientHeight ||
297
+ oldVal.pixelRatio !== pixelRatio) {
298
+ ref.setValue({ width: mediaElement.clientWidth,
299
+ height: mediaElement.clientHeight, pixelRatio: pixelRatio });
300
+ }
279
301
  }
280
- else if (!isNullOrUndefined(pipStatus.pipWindow)) {
281
- var pipWindow_1 = pipStatus.pipWindow;
282
- var firstWidth = getVideoWidthFromPIPWindow(mediaElement, pipWindow_1);
302
+ else if (!isNullOrUndefined(pipWindow)) {
283
303
  var onPipResize_1 = function () {
284
- ref.setValueIfChanged(getVideoWidthFromPIPWindow(mediaElement, pipWindow_1) * pixelRatio);
304
+ updateToPipWindowResolution();
285
305
  };
286
- pipWindow_1.addEventListener("resize", onPipResize_1);
306
+ pipWindow.addEventListener("resize", onPipResize_1);
287
307
  clearPreviousEventListener = function () {
288
- pipWindow_1.removeEventListener("resize", onPipResize_1);
308
+ pipWindow.removeEventListener("resize", onPipResize_1);
289
309
  clearPreviousEventListener = noop;
290
310
  };
291
- ref.setValueIfChanged(firstWidth * pixelRatio);
311
+ updateToPipWindowResolution();
292
312
  }
293
313
  else {
294
- ref.setValueIfChanged(Infinity);
314
+ var oldVal = ref.getValue();
315
+ if (oldVal.width !== undefined ||
316
+ oldVal.height !== undefined ||
317
+ oldVal.pixelRatio !== pixelRatio) {
318
+ ref.setValue({ width: undefined,
319
+ height: undefined, pixelRatio: pixelRatio });
320
+ }
321
+ }
322
+ function updateToPipWindowResolution() {
323
+ var oldVal = ref.getValue();
324
+ if (oldVal.width !== (pipWindow === null || pipWindow === void 0 ? void 0 : pipWindow.width) ||
325
+ oldVal.height !== (pipWindow === null || pipWindow === void 0 ? void 0 : pipWindow.height) ||
326
+ oldVal.pixelRatio !== pixelRatio) {
327
+ ref.setValue({ width: pipWindow === null || pipWindow === void 0 ? void 0 : pipWindow.width,
328
+ height: pipWindow === null || pipWindow === void 0 ? void 0 : pipWindow.height, pixelRatio: pixelRatio });
329
+ }
295
330
  }
296
331
  }
297
332
  }
@@ -390,4 +425,4 @@ function addEventListener(elt, evt, listener, stopListening) {
390
425
  elt.removeEventListener(evt, listener);
391
426
  });
392
427
  }
393
- export { addEventListener, getPictureOnPictureStateRef, getVideoVisibilityRef, getVideoWidthRef, onEncrypted, onEnded, onKeyAdded, onKeyError, onKeyMessage, onKeyStatusesChange, onLoadedMetadata, onRemoveSourceBuffers, onSeeked, onSeeking, onSourceClose, onSourceEnded, onSourceOpen, onTimeUpdate, onSourceBufferUpdate, onTextTrackAdded, onTextTrackRemoved, };
428
+ export { addEventListener, getPictureOnPictureStateRef, getVideoVisibilityRef, getElementResolutionRef, getScreenResolutionRef, onEncrypted, onEnded, onKeyAdded, onKeyError, onKeyMessage, onKeyStatusesChange, onLoadedMetadata, onRemoveSourceBuffers, onSeeked, onSeeking, onSourceClose, onSourceEnded, onSourceOpen, onTimeUpdate, onSourceBufferUpdate, onTextTrackAdded, onTextTrackRemoved, };
@@ -20,7 +20,7 @@
20
20
  * We found that on all Widevine targets tested, a simple seek is sufficient.
21
21
  * As widevine clients make a good chunk of users, we can make a difference
22
22
  * between them and others as it is for the better.
23
- * @param {string|null} currentKeySystem
23
+ * @param {string|undefined} currentKeySystem
24
24
  * @returns {Boolean}
25
25
  */
26
- export default function shouldReloadMediaSourceOnDecipherabilityUpdate(currentKeySystem: string | null): boolean;
26
+ export default function shouldReloadMediaSourceOnDecipherabilityUpdate(currentKeySystem: string | undefined): boolean;
@@ -20,10 +20,10 @@
20
20
  * We found that on all Widevine targets tested, a simple seek is sufficient.
21
21
  * As widevine clients make a good chunk of users, we can make a difference
22
22
  * between them and others as it is for the better.
23
- * @param {string|null} currentKeySystem
23
+ * @param {string|undefined} currentKeySystem
24
24
  * @returns {Boolean}
25
25
  */
26
26
  export default function shouldReloadMediaSourceOnDecipherabilityUpdate(currentKeySystem) {
27
- return currentKeySystem === null ||
27
+ return currentKeySystem === undefined ||
28
28
  currentKeySystem.indexOf("widevine") < 0;
29
29
  }
@@ -39,7 +39,7 @@ declare class ConfigHandler {
39
39
  DEFAULT_BASE_BANDWIDTH: number;
40
40
  INACTIVITY_DELAY: number;
41
41
  DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN: boolean;
42
- DEFAULT_LIMIT_VIDEO_WIDTH: boolean;
42
+ DEFAULT_VIDEO_RESOLUTION_LIMIT: "none";
43
43
  DEFAULT_LIVE_GAP: {
44
44
  DEFAULT: number;
45
45
  LOW_LATENCY: number;
@@ -19,6 +19,7 @@ import { CancellationSignal } from "../../utils/task_canceller";
19
19
  import { IReadOnlyPlaybackObserver } from "../api";
20
20
  import { IBufferType } from "../segment_buffers";
21
21
  import BandwidthEstimator from "./utils/bandwidth_estimator";
22
+ import { IResolutionInfo } from "./utils/filter_by_resolution";
22
23
  import { IPendingRequestStoreBegin, IPendingRequestStoreProgress } from "./utils/pending_requests_store";
23
24
  /**
24
25
  * Select the most adapted Representation according to the network and buffer
@@ -219,7 +220,7 @@ export interface IRepresentationEstimatorArguments {
219
220
  currentRepresentation: IReadOnlySharedReference<Representation | null>;
220
221
  /** Throttle Representation pool according to filters. */
221
222
  filters: {
222
- limitWidth: IReadOnlySharedReference<number | undefined>;
223
+ limitResolution: IReadOnlySharedReference<IResolutionInfo | undefined>;
223
224
  throttleBitrate: IReadOnlySharedReference<number>;
224
225
  };
225
226
  /**
@@ -300,6 +301,6 @@ export interface IAdaptiveRepresentationSelectorArguments {
300
301
  * to choose from.
301
302
  */
302
303
  export interface IRepresentationEstimatorThrottlers {
303
- limitWidth: Partial<Record<IBufferType, IReadOnlySharedReference<number>>>;
304
+ limitResolution: Partial<Record<IBufferType, IReadOnlySharedReference<IResolutionInfo>>>;
304
305
  throttleBitrate: Partial<Record<IBufferType, IReadOnlySharedReference<number>>>;
305
306
  }
@@ -24,7 +24,7 @@ import GuessBasedChooser from "./guess_based_chooser";
24
24
  import NetworkAnalyzer from "./network_analyzer";
25
25
  import BandwidthEstimator from "./utils/bandwidth_estimator";
26
26
  import filterByBitrate from "./utils/filter_by_bitrate";
27
- import filterByWidth from "./utils/filter_by_width";
27
+ import filterByResolution from "./utils/filter_by_resolution";
28
28
  import LastEstimateStorage from "./utils/last_estimate_storage";
29
29
  import PendingRequestsStore from "./utils/pending_requests_store";
30
30
  import RepresentationScoreCalculator from "./utils/representation_score_calculator";
@@ -66,7 +66,7 @@ export default function createAdaptiveRepresentationSelector(options) {
66
66
  var bandwidthEstimator = _getBandwidthEstimator(type);
67
67
  var initialBitrate = takeFirstSet(initialBitrates[type], 0);
68
68
  var filters = {
69
- limitWidth: takeFirstSet(throttlers.limitWidth[type], limitWidthDefaultRef),
69
+ limitResolution: takeFirstSet(throttlers.limitResolution[type], limitWidthDefaultRef),
70
70
  throttleBitrate: takeFirstSet(throttlers.throttleBitrate[type], throttleBitrateDefaultRef),
71
71
  };
72
72
  return getEstimateReference({ bandwidthEstimator: bandwidthEstimator, context: context, currentRepresentation: currentRepresentation, filters: filters, initialBitrate: initialBitrate, playbackObserver: playbackObserver, representations: representations, lowLatencyMode: lowLatencyMode }, stopAllEstimates);
@@ -186,8 +186,8 @@ function getEstimateReference(_a, stopAllEstimates) {
186
186
  innerCancellationSignal.register(function () {
187
187
  onAddedSegment = noop;
188
188
  });
189
- filters.limitWidth.onUpdate(updateEstimate, { clearSignal: innerCancellationSignal });
190
- filters.limitWidth.onUpdate(updateEstimate, { clearSignal: innerCancellationSignal });
189
+ filters.throttleBitrate.onUpdate(updateEstimate, { clearSignal: innerCancellationSignal });
190
+ filters.limitResolution.onUpdate(updateEstimate, { clearSignal: innerCancellationSignal });
191
191
  return innerEstimateRef;
192
192
  function updateEstimate() {
193
193
  innerEstimateRef.setValue(getCurrentEstimate());
@@ -195,10 +195,10 @@ function getEstimateReference(_a, stopAllEstimates) {
195
195
  /** Returns the actual estimate based on all methods and algorithm available. */
196
196
  function getCurrentEstimate() {
197
197
  var bufferGap = lastPlaybackObservation.bufferGap, position = lastPlaybackObservation.position, maximumPosition = lastPlaybackObservation.maximumPosition;
198
- var widthLimit = filters.limitWidth.getValue();
198
+ var resolutionLimit = filters.limitResolution.getValue();
199
199
  var bitrateThrottle = filters.throttleBitrate.getValue();
200
200
  var currentRepresentationVal = currentRepresentation.getValue();
201
- var filteredReps = getFilteredRepresentations(representations, widthLimit, bitrateThrottle);
201
+ var filteredReps = getFilteredRepresentations(representations, resolutionLimit, bitrateThrottle);
202
202
  var requests = requestsStore.getRequests();
203
203
  var _a = networkAnalyzer
204
204
  .getBandwidthEstimate(lastPlaybackObservation, bandwidthEstimator, currentRepresentationVal, requests, prevEstimate.bandwidth), bandwidthEstimate = _a.bandwidthEstimate, bitrateChosen = _a.bitrateChosen;
@@ -338,16 +338,17 @@ function getEstimateReference(_a, stopAllEstimates) {
338
338
  /**
339
339
  * Filter representations given through filters options.
340
340
  * @param {Array.<Representation>} representations
341
- * @param {number | undefined} widthLimit - Filter Object.
341
+ * @param {Object | undefined} resolutionLimit
342
+ * @param {number | undefined} bitrateThrottle
342
343
  * @returns {Array.<Representation>}
343
344
  */
344
- function getFilteredRepresentations(representations, widthLimit, bitrateThrottle) {
345
+ function getFilteredRepresentations(representations, resolutionLimit, bitrateThrottle) {
345
346
  var filteredReps = representations;
346
- if (bitrateThrottle < Infinity) {
347
+ if (bitrateThrottle !== undefined && bitrateThrottle < Infinity) {
347
348
  filteredReps = filterByBitrate(filteredReps, bitrateThrottle);
348
349
  }
349
- if (widthLimit !== undefined) {
350
- filteredReps = filterByWidth(filteredReps, widthLimit);
350
+ if (resolutionLimit !== undefined) {
351
+ filteredReps = filterByResolution(filteredReps, resolutionLimit);
351
352
  }
352
353
  return filteredReps;
353
354
  }
@@ -15,11 +15,17 @@
15
15
  */
16
16
  import { Representation } from "../../../manifest";
17
17
  /**
18
- * Filter representations based on their width:
19
- * - the highest width considered will be the one linked to the first
20
- * representation which has a superior width to the one given.
18
+ * Filter representations based on their resolution.
19
+ * - the highest resolution considered will be the one linked to the first
20
+ * representation which has a superior resolution or equal to the one
21
+ * given.
21
22
  * @param {Array.<Object>} representations - The representations array
22
- * @param {Number} width
23
+ * @param {Object} resolution
23
24
  * @returns {Array.<Object>}
24
25
  */
25
- export default function filterByWidth(representations: Representation[], width: number): Representation[];
26
+ export default function filterByResolution(representations: Representation[], resolution: IResolutionInfo): Representation[];
27
+ export interface IResolutionInfo {
28
+ height: number | undefined;
29
+ width: number | undefined;
30
+ pixelRatio: number;
31
+ }
@@ -16,21 +16,29 @@
16
16
  import arrayFind from "../../../utils/array_find";
17
17
  import takeFirstSet from "../../../utils/take_first_set";
18
18
  /**
19
- * Filter representations based on their width:
20
- * - the highest width considered will be the one linked to the first
21
- * representation which has a superior width to the one given.
19
+ * Filter representations based on their resolution.
20
+ * - the highest resolution considered will be the one linked to the first
21
+ * representation which has a superior resolution or equal to the one
22
+ * given.
22
23
  * @param {Array.<Object>} representations - The representations array
23
- * @param {Number} width
24
+ * @param {Object} resolution
24
25
  * @returns {Array.<Object>}
25
26
  */
26
- export default function filterByWidth(representations, width) {
27
+ export default function filterByResolution(representations, resolution) {
28
+ if (resolution.width === undefined || resolution.height === undefined) {
29
+ return representations;
30
+ }
31
+ var width = resolution.width * resolution.pixelRatio;
32
+ var height = resolution.height * resolution.pixelRatio;
27
33
  var sortedRepsByWidth = representations
28
34
  .slice() // clone
29
35
  .sort(function (a, b) { return takeFirstSet(a.width, 0) -
30
36
  takeFirstSet(b.width, 0); });
31
37
  var repWithMaxWidth = arrayFind(sortedRepsByWidth, function (representation) {
32
38
  return typeof representation.width === "number" &&
33
- representation.width >= width;
39
+ representation.width >= width &&
40
+ typeof representation.height === "number" &&
41
+ representation.height >= height;
34
42
  });
35
43
  if (repWithMaxWidth === undefined) {
36
44
  return representations;
@@ -32,7 +32,7 @@ export interface IParsedConstructorOptions {
32
32
  maxBufferBehind: number;
33
33
  wantedBufferAhead: number;
34
34
  maxVideoBufferSize: number;
35
- limitVideoWidth: boolean;
35
+ videoResolutionLimit: "videoElement" | "screen" | "none";
36
36
  throttleVideoBitrateWhenHidden: boolean;
37
37
  videoElement: HTMLMediaElement;
38
38
  baseBandwidth: number;
@@ -38,7 +38,7 @@ function parseConstructorOptions(options) {
38
38
  var maxVideoBufferSize;
39
39
  var videoElement;
40
40
  var baseBandwidth;
41
- var _a = config.getCurrent(), DEFAULT_BASE_BANDWIDTH = _a.DEFAULT_BASE_BANDWIDTH, DEFAULT_LIMIT_VIDEO_WIDTH = _a.DEFAULT_LIMIT_VIDEO_WIDTH, DEFAULT_MAX_BUFFER_AHEAD = _a.DEFAULT_MAX_BUFFER_AHEAD, DEFAULT_MAX_BUFFER_BEHIND = _a.DEFAULT_MAX_BUFFER_BEHIND, DEFAULT_MAX_VIDEO_BUFFER_SIZE = _a.DEFAULT_MAX_VIDEO_BUFFER_SIZE, DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN = _a.DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN, DEFAULT_WANTED_BUFFER_AHEAD = _a.DEFAULT_WANTED_BUFFER_AHEAD;
41
+ var _a = config.getCurrent(), DEFAULT_BASE_BANDWIDTH = _a.DEFAULT_BASE_BANDWIDTH, DEFAULT_VIDEO_RESOLUTION_LIMIT = _a.DEFAULT_VIDEO_RESOLUTION_LIMIT, DEFAULT_MAX_BUFFER_AHEAD = _a.DEFAULT_MAX_BUFFER_AHEAD, DEFAULT_MAX_BUFFER_BEHIND = _a.DEFAULT_MAX_BUFFER_BEHIND, DEFAULT_MAX_VIDEO_BUFFER_SIZE = _a.DEFAULT_MAX_VIDEO_BUFFER_SIZE, DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN = _a.DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN, DEFAULT_WANTED_BUFFER_AHEAD = _a.DEFAULT_WANTED_BUFFER_AHEAD;
42
42
  if (isNullOrUndefined(options.maxBufferAhead)) {
43
43
  maxBufferAhead = DEFAULT_MAX_BUFFER_AHEAD;
44
44
  }
@@ -79,9 +79,9 @@ function parseConstructorOptions(options) {
79
79
  /* eslint-enable max-len */
80
80
  }
81
81
  }
82
- var limitVideoWidth = isNullOrUndefined(options.limitVideoWidth) ?
83
- DEFAULT_LIMIT_VIDEO_WIDTH :
84
- !!options.limitVideoWidth;
82
+ var videoResolutionLimit = isNullOrUndefined(options.videoResolutionLimit) ?
83
+ DEFAULT_VIDEO_RESOLUTION_LIMIT :
84
+ options.videoResolutionLimit;
85
85
  var throttleVideoBitrateWhenHidden = isNullOrUndefined(options.throttleVideoBitrateWhenHidden) ?
86
86
  DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN :
87
87
  !!options.throttleVideoBitrateWhenHidden;
@@ -107,7 +107,7 @@ function parseConstructorOptions(options) {
107
107
  /* eslint-enable max-len */
108
108
  }
109
109
  }
110
- return { maxBufferAhead: maxBufferAhead, maxBufferBehind: maxBufferBehind, limitVideoWidth: limitVideoWidth, videoElement: videoElement, wantedBufferAhead: wantedBufferAhead, maxVideoBufferSize: maxVideoBufferSize, throttleVideoBitrateWhenHidden: throttleVideoBitrateWhenHidden, baseBandwidth: baseBandwidth };
110
+ return { maxBufferAhead: maxBufferAhead, maxBufferBehind: maxBufferBehind, videoResolutionLimit: videoResolutionLimit, videoElement: videoElement, wantedBufferAhead: wantedBufferAhead, maxVideoBufferSize: maxVideoBufferSize, throttleVideoBitrateWhenHidden: throttleVideoBitrateWhenHidden, baseBandwidth: baseBandwidth };
111
111
  }
112
112
  /**
113
113
  * Check the format of given reload options.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Copyright 2015 CANAL+ Group
3
3
  *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * Licensed under the Apache License, Version 2.0 (the "License");publicapi
5
5
  * you may not use this file except in compliance with the License.
6
6
  * You may obtain a copy of the License at
7
7
  *
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { IErrorCode, IErrorType } from "../../errors";
17
17
  import Manifest from "../../manifest";
18
- import { IAudioRepresentation, IAudioTrack, IAudioTrackSetting, IAvailableAudioTrack, IAvailableTextTrack, IAvailableVideoTrack, IBrokenRepresentationsLockContext, IConstructorOptions, ILoadVideoOptions, ILockedAudioRepresentationsSettings, ILockedVideoRepresentationsSettings, ITrackUpdateEventPayload, IPeriod, IPeriodChangeEvent, IPlayerError, IPlayerState, IPositionUpdate, IStreamEvent, ITextTrack, IVideoRepresentation, ITextTrackSetting, IVideoTrack, IVideoTrackSetting } from "../../public_types";
18
+ import { IAudioRepresentation, IAudioTrack, IAudioTrackSetting, IAvailableAudioTrack, IAvailableTextTrack, IAvailableVideoTrack, IBrokenRepresentationsLockContext, IConstructorOptions, IKeySystemConfigurationOutput, ILoadVideoOptions, ILockedAudioRepresentationsSettings, ILockedVideoRepresentationsSettings, ITrackUpdateEventPayload, IPeriod, IPeriodChangeEvent, IPlayerError, IPlayerState, IPositionUpdate, IStreamEvent, ITextTrack, IVideoRepresentation, ITextTrackSetting, IVideoTrack, IVideoTrackSetting } from "../../public_types";
19
19
  import EventEmitter, { IListener } from "../../utils/event_emitter";
20
20
  import Logger from "../../utils/logger";
21
21
  import { IBufferedChunk, IBufferType } from "../segment_buffers";
@@ -76,8 +76,8 @@ declare class Player extends EventEmitter<IPublicAPIEvent> {
76
76
  private _priv_preferTrickModeTracks;
77
77
  /** Refer to last picture in picture event received. */
78
78
  private _priv_pictureInPictureRef;
79
- /** Store wanted configuration for the `limitVideoWidth` option. */
80
- private readonly _priv_limitVideoWidth;
79
+ /** Store wanted configuration for the `videoResolutionLimit` option. */
80
+ private readonly _priv_videoResolutionLimit;
81
81
  /** Store wanted configuration for the `throttleVideoBitrateWhenHidden` option. */
82
82
  private readonly _priv_throttleVideoBitrateWhenHidden;
83
83
  /** Store volume when mute is called, to restore it on unmute. */
@@ -421,13 +421,16 @@ declare class Player extends EventEmitter<IPublicAPIEvent> {
421
421
  * @returns {Number}
422
422
  */
423
423
  getMaxVideoBufferSize(): number;
424
+ getCurrentPeriod(): IPeriod | null;
424
425
  /**
425
- * Returns type of current keysystem (e.g. playready, widevine) if the content
426
- * is encrypted. null otherwise.
427
- * @returns {string|null}
426
+ * Returns both the name of the key system (e.g. `"com.widevine.alpha"`) and
427
+ * the `MediaKeySystemConfiguration` currently associated to the
428
+ * HTMLMediaElement linked to the RxPlayer.
429
+ *
430
+ * Returns `null` if no such capabilities is associated or if unknown.
431
+ * @returns {Object|null}
428
432
  */
429
- getCurrentKeySystem(): string | null;
430
- getCurrentPeriod(): IPeriod | null;
433
+ getKeySystemConfiguration(): IKeySystemConfigurationOutput | null;
431
434
  /**
432
435
  * Returns the list of available Periods for which the current audio, video or
433
436
  * text track can now be changed.