rx-player 3.30.0-dev.2023022200 → 3.30.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.
- package/.eslintrc.js +8 -0
- package/CHANGELOG.md +4 -1
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/browser_detection.d.ts +23 -12
- package/dist/_esm5.processed/compat/browser_detection.js +80 -38
- package/dist/_esm5.processed/compat/can_reuse_media_keys.js +2 -2
- package/dist/_esm5.processed/config.d.ts +2 -0
- package/dist/_esm5.processed/core/api/debug/buffer_size_graph.js +0 -1
- package/dist/_esm5.processed/core/api/public_api.js +3 -3
- package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.d.ts +27 -8
- package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.js +28 -7
- package/dist/_esm5.processed/core/decrypt/find_key_system.js +33 -24
- package/dist/_esm5.processed/core/decrypt/session_events_listener.js +27 -13
- package/dist/_esm5.processed/core/fetchers/utils/schedule_request.js +13 -4
- package/dist/_esm5.processed/core/init/utils/media_duration_updater.js +1 -1
- package/dist/_esm5.processed/core/init/utils/rebuffering_controller.js +1 -1
- package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.js +15 -5
- package/dist/_esm5.processed/default_config.d.ts +16 -0
- package/dist/_esm5.processed/default_config.js +19 -0
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +5 -2
- package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +5 -2
- package/dist/rx-player.js +162 -72
- package/dist/rx-player.min.js +1 -1
- package/package.json +2 -1
- package/sonar-project.properties +1 -1
- package/src/compat/browser_detection.ts +99 -52
- package/src/compat/can_reuse_media_keys.ts +5 -2
- package/src/core/api/debug/buffer_size_graph.ts +0 -1
- package/src/core/api/public_api.ts +3 -3
- package/src/core/decrypt/__tests__/__global__/utils.ts +61 -40
- package/src/core/decrypt/find_key_system.ts +36 -35
- package/src/core/decrypt/session_events_listener.ts +28 -15
- package/src/core/fetchers/utils/schedule_request.ts +14 -4
- package/src/core/init/utils/media_duration_updater.ts +1 -1
- package/src/core/init/utils/rebuffering_controller.ts +1 -1
- package/src/core/stream/adaptation/adaptation_stream.ts +18 -8
- package/src/default_config.ts +30 -9
- package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +4 -1
- package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +5 -2
package/.eslintrc.js
CHANGED
|
@@ -16,10 +16,18 @@ module.exports = {
|
|
|
16
16
|
"plugins": [
|
|
17
17
|
"eslint-plugin-import",
|
|
18
18
|
"eslint-plugin-jsdoc",
|
|
19
|
+
"ban",
|
|
19
20
|
"@typescript-eslint",
|
|
20
21
|
"@typescript-eslint/tslint"
|
|
21
22
|
],
|
|
22
23
|
"rules": {
|
|
24
|
+
"ban/ban": [
|
|
25
|
+
2,
|
|
26
|
+
{
|
|
27
|
+
"name": ["*", "finally"],
|
|
28
|
+
"message": "Promise.prototype.finally is forbidden due to poor support from older devices.\nNote that this linting rule just bans naively all \"finally\" method calls, if in this case it wasn't called on a Promise, you can safely ignore this error",
|
|
29
|
+
}
|
|
30
|
+
],
|
|
23
31
|
"@typescript-eslint/adjacent-overload-signatures": "error",
|
|
24
32
|
"@typescript-eslint/array-type": [
|
|
25
33
|
"error",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## v3.30.0-
|
|
3
|
+
## v3.30.0 (2023-03-07)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
|
|
@@ -26,7 +26,10 @@
|
|
|
26
26
|
|
|
27
27
|
### Other improvements
|
|
28
28
|
|
|
29
|
+
- DASH: better detect closed captions [#1187]
|
|
29
30
|
- DASH: handle `endNumber` DASH attribute [#1186]
|
|
31
|
+
- Support encrypted contents on Panasonic 2019 TVs [#1226]
|
|
32
|
+
- Better handle SourceBuffer's QuotaExceededError, responsible for `MediaError` with the `BUFFER_FULL_ERROR` code [#1221]
|
|
30
33
|
- API: send available...TracksChange events in the very unlikely scenario where tracks are added after a manifest update [#1197]
|
|
31
34
|
- Completely remove RxJS dependency from the RxPlayer's source code [#1193]
|
|
32
35
|
- DRM: Request PR recommendation when PlayReady is asked and try default recommendation robustnesses [#1189]
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.30.0
|
|
1
|
+
3.30.0
|
|
@@ -13,17 +13,28 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
|
|
17
|
-
declare
|
|
18
|
-
|
|
19
|
-
declare
|
|
20
|
-
|
|
21
|
-
declare
|
|
22
|
-
|
|
23
|
-
declare
|
|
24
|
-
declare const isWebOs2022: boolean;
|
|
16
|
+
/** Edge Chromium, regardless of the device */
|
|
17
|
+
declare let isEdgeChromium: boolean;
|
|
18
|
+
/** IE11, regardless of the device */
|
|
19
|
+
declare let isIE11: boolean;
|
|
20
|
+
/** IE11 or Edge __Legacy__ (not Edge Chromium), regardless of the device */
|
|
21
|
+
declare let isIEOrEdge: boolean;
|
|
22
|
+
/** Firefox, regardless of the device */
|
|
23
|
+
declare let isFirefox: boolean;
|
|
25
24
|
/** `true` on Safari on a PC platform (i.e. not iPhone / iPad etc.) */
|
|
26
|
-
declare
|
|
25
|
+
declare let isSafariDesktop: boolean;
|
|
27
26
|
/** `true` on Safari on an iPhone, iPad & iPod platform */
|
|
28
|
-
declare
|
|
29
|
-
|
|
27
|
+
declare let isSafariMobile: boolean;
|
|
28
|
+
/** Samsung's own browser application */
|
|
29
|
+
declare let isSamsungBrowser: boolean;
|
|
30
|
+
/** `true` on devices where Tizen is the OS (e.g. Samsung TVs). */
|
|
31
|
+
declare let isTizen: boolean;
|
|
32
|
+
/** `true` on devices where WebOS is the OS (e.g. LG TVs). */
|
|
33
|
+
declare let isWebOs: boolean;
|
|
34
|
+
/** `true` specifically for WebOS 2021 version. */
|
|
35
|
+
declare let isWebOs2021: boolean;
|
|
36
|
+
/** `true` specifically for WebOS 2022 version. */
|
|
37
|
+
declare let isWebOs2022: boolean;
|
|
38
|
+
/** `true` for Panasonic devices. */
|
|
39
|
+
declare let isPanasonic: boolean;
|
|
40
|
+
export { isEdgeChromium, isIE11, isIEOrEdge, isFirefox, isPanasonic, isSafariDesktop, isSafariMobile, isSamsungBrowser, isTizen, isWebOs, isWebOs2021, isWebOs2022, };
|
|
@@ -13,44 +13,86 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
var _a, _b;
|
|
17
16
|
import isNode from "./is_node";
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
navigator.appName === "Microsoft Internet Explorer" ||
|
|
27
|
-
navigator.appName === "Netscape" &&
|
|
28
|
-
/(Trident|Edge)\//.test(navigator.userAgent);
|
|
29
|
-
var isEdgeChromium = !isNode &&
|
|
30
|
-
navigator.userAgent.toLowerCase().indexOf("edg/") !== -1;
|
|
31
|
-
var isFirefox = !isNode &&
|
|
32
|
-
navigator.userAgent.toLowerCase().indexOf("firefox") !== -1;
|
|
33
|
-
var isSamsungBrowser = !isNode &&
|
|
34
|
-
/SamsungBrowser/.test(navigator.userAgent);
|
|
35
|
-
var isTizen = !isNode &&
|
|
36
|
-
/Tizen/.test(navigator.userAgent);
|
|
37
|
-
var isWebOs = !isNode &&
|
|
38
|
-
navigator.userAgent.indexOf("Web0S") >= 0;
|
|
39
|
-
// Inspired form: http://webostv.developer.lge.com/discover/specifications/web-engine/
|
|
40
|
-
// Note: even that page doesn't correspond to what we've actually seen in the
|
|
41
|
-
// wild
|
|
42
|
-
var isWebOs2021 = isWebOs &&
|
|
43
|
-
(/[Ww]eb[O0]S.TV-2021/.test(navigator.userAgent) ||
|
|
44
|
-
/[Cc]hr[o0]me\/79/.test(navigator.userAgent));
|
|
45
|
-
var isWebOs2022 = isWebOs &&
|
|
46
|
-
(/[Ww]eb[O0]S.TV-2022/.test(navigator.userAgent) ||
|
|
47
|
-
/[Cc]hr[o0]me\/87/.test(navigator.userAgent));
|
|
17
|
+
/** Edge Chromium, regardless of the device */
|
|
18
|
+
var isEdgeChromium = false;
|
|
19
|
+
/** IE11, regardless of the device */
|
|
20
|
+
var isIE11 = false;
|
|
21
|
+
/** IE11 or Edge __Legacy__ (not Edge Chromium), regardless of the device */
|
|
22
|
+
var isIEOrEdge = false;
|
|
23
|
+
/** Firefox, regardless of the device */
|
|
24
|
+
var isFirefox = false;
|
|
48
25
|
/** `true` on Safari on a PC platform (i.e. not iPhone / iPad etc.) */
|
|
49
|
-
var isSafariDesktop =
|
|
50
|
-
((_b = (_a = window.safari) === null || _a === void 0 ? void 0 : _a.pushNotification) === null || _b === void 0 ? void 0 : _b.toString()) ===
|
|
51
|
-
"[object SafariRemoteNotification]");
|
|
26
|
+
var isSafariDesktop = false;
|
|
52
27
|
/** `true` on Safari on an iPhone, iPad & iPod platform */
|
|
53
|
-
var isSafariMobile =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
28
|
+
var isSafariMobile = false;
|
|
29
|
+
/** Samsung's own browser application */
|
|
30
|
+
var isSamsungBrowser = false;
|
|
31
|
+
/** `true` on devices where Tizen is the OS (e.g. Samsung TVs). */
|
|
32
|
+
var isTizen = false;
|
|
33
|
+
/** `true` on devices where WebOS is the OS (e.g. LG TVs). */
|
|
34
|
+
var isWebOs = false;
|
|
35
|
+
/** `true` specifically for WebOS 2021 version. */
|
|
36
|
+
var isWebOs2021 = false;
|
|
37
|
+
/** `true` specifically for WebOS 2022 version. */
|
|
38
|
+
var isWebOs2022 = false;
|
|
39
|
+
/** `true` for Panasonic devices. */
|
|
40
|
+
var isPanasonic = false;
|
|
41
|
+
((function findCurrentBrowser() {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
if (isNode) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// 1 - Find out browser between IE/Edge Legacy/Edge Chromium/Firefox/Safari
|
|
47
|
+
if (typeof window.MSInputMethodContext !== "undefined" &&
|
|
48
|
+
typeof document.documentMode !== "undefined") {
|
|
49
|
+
isIE11 = true;
|
|
50
|
+
isIEOrEdge = true;
|
|
51
|
+
}
|
|
52
|
+
else if (navigator.appName === "Microsoft Internet Explorer" ||
|
|
53
|
+
navigator.appName === "Netscape" &&
|
|
54
|
+
/(Trident|Edge)\//.test(navigator.userAgent)) {
|
|
55
|
+
isIEOrEdge = true;
|
|
56
|
+
}
|
|
57
|
+
else if (navigator.userAgent.toLowerCase().indexOf("edg/") !== -1) {
|
|
58
|
+
isEdgeChromium = true;
|
|
59
|
+
}
|
|
60
|
+
else if (navigator.userAgent.toLowerCase().indexOf("firefox") !== -1) {
|
|
61
|
+
isFirefox = true;
|
|
62
|
+
}
|
|
63
|
+
else if (typeof navigator.platform === "string" &&
|
|
64
|
+
/iPad|iPhone|iPod/.test(navigator.platform)) {
|
|
65
|
+
isSafariMobile = true;
|
|
66
|
+
}
|
|
67
|
+
else if (Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor") >= 0 ||
|
|
68
|
+
((_b = (_a = window.safari) === null || _a === void 0 ? void 0 : _a.pushNotification) === null || _b === void 0 ? void 0 : _b.toString()) ===
|
|
69
|
+
"[object SafariRemoteNotification]") {
|
|
70
|
+
isSafariDesktop = true;
|
|
71
|
+
}
|
|
72
|
+
// 2 - Find out specific device/platform information
|
|
73
|
+
// Samsung browser e.g. on Android
|
|
74
|
+
if (/SamsungBrowser/.test(navigator.userAgent)) {
|
|
75
|
+
isSamsungBrowser = true;
|
|
76
|
+
}
|
|
77
|
+
if (/Tizen/.test(navigator.userAgent)) {
|
|
78
|
+
isTizen = true;
|
|
79
|
+
// Inspired form: http://webostv.developer.lge.com/discover/specifications/web-engine/
|
|
80
|
+
// Note: even that page doesn't correspond to what we've actually seen in the
|
|
81
|
+
// wild
|
|
82
|
+
}
|
|
83
|
+
else if (/[Ww]eb[O0]S/.test(navigator.userAgent)) {
|
|
84
|
+
isWebOs = true;
|
|
85
|
+
if (/[Ww]eb[O0]S.TV-2022/.test(navigator.userAgent) ||
|
|
86
|
+
/[Cc]hr[o0]me\/87/.test(navigator.userAgent)) {
|
|
87
|
+
isWebOs2022 = true;
|
|
88
|
+
}
|
|
89
|
+
else if (/[Ww]eb[O0]S.TV-2021/.test(navigator.userAgent) ||
|
|
90
|
+
/[Cc]hr[o0]me\/79/.test(navigator.userAgent)) {
|
|
91
|
+
isWebOs2021 = true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (/[Pp]anasonic/.test(navigator.userAgent)) {
|
|
95
|
+
isPanasonic = true;
|
|
96
|
+
}
|
|
97
|
+
})());
|
|
98
|
+
export { isEdgeChromium, isIE11, isIEOrEdge, isFirefox, isPanasonic, isSafariDesktop, isSafariMobile, isSamsungBrowser, isTizen, isWebOs, isWebOs2021, isWebOs2022, };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isWebOs } from "./browser_detection";
|
|
1
|
+
import { isPanasonic, isWebOs, } from "./browser_detection";
|
|
2
2
|
/**
|
|
3
3
|
* Returns `true` if a `MediaKeys` instance (the `Encrypted Media Extension`
|
|
4
4
|
* concept) can be reused between contents.
|
|
@@ -12,5 +12,5 @@ import { isWebOs } from "./browser_detection";
|
|
|
12
12
|
* @returns {boolean}
|
|
13
13
|
*/
|
|
14
14
|
export default function canReuseMediaKeys() {
|
|
15
|
-
return !isWebOs;
|
|
15
|
+
return !isWebOs && !isPanasonic;
|
|
16
16
|
}
|
|
@@ -136,6 +136,8 @@ declare class ConfigHandler {
|
|
|
136
136
|
SEGMENT_PRIORITIES_STEPS: number[];
|
|
137
137
|
MAX_HIGH_PRIORITY_LEVEL: number;
|
|
138
138
|
MIN_CANCELABLE_PRIORITY: number;
|
|
139
|
+
EME_DEFAULT_VIDEO_CODECS: string[];
|
|
140
|
+
EME_DEFAULT_AUDIO_CODECS: string[];
|
|
139
141
|
EME_DEFAULT_WIDEVINE_ROBUSTNESSES: string[];
|
|
140
142
|
EME_DEFAULT_PLAYREADY_ROBUSTNESSES: string[];
|
|
141
143
|
EME_KEY_SYSTEMS: Partial<Record<string, string[]>>;
|
|
@@ -57,7 +57,6 @@ var BufferSizeGraph = /** @class */ (function () {
|
|
|
57
57
|
var gridHeight = height / currentMaxSize;
|
|
58
58
|
var gridWidth = width / TIME_SAMPLES_MS;
|
|
59
59
|
drawData();
|
|
60
|
-
// drawGrid();
|
|
61
60
|
/**
|
|
62
61
|
* Get more appropriate maximum buffer size to put on top of the graph
|
|
63
62
|
* according to current history.
|
|
@@ -89,7 +89,7 @@ var Player = /** @class */ (function (_super) {
|
|
|
89
89
|
// Workaround to support Firefox autoplay on FF 42.
|
|
90
90
|
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
|
|
91
91
|
videoElement.preload = "auto";
|
|
92
|
-
_this.version = /* PLAYER_VERSION */ "3.30.0
|
|
92
|
+
_this.version = /* PLAYER_VERSION */ "3.30.0";
|
|
93
93
|
_this.log = log;
|
|
94
94
|
_this.state = "STOPPED";
|
|
95
95
|
_this.videoElement = videoElement;
|
|
@@ -618,7 +618,7 @@ var Player = /** @class */ (function (_super) {
|
|
|
618
618
|
// Previous call could have performed all kind of side-effects, thus,
|
|
619
619
|
// we re-check the current state associated to the RxPlayer
|
|
620
620
|
if (_this.state === "ENDED" /* PLAYER_STATES.ENDED */ && _this._priv_stopAtEnd) {
|
|
621
|
-
|
|
621
|
+
_this.stop();
|
|
622
622
|
}
|
|
623
623
|
}, { emitCurrentValue: true, clearSignal: currentContentCanceller.signal });
|
|
624
624
|
// React to playback conditions change
|
|
@@ -2339,5 +2339,5 @@ var Player = /** @class */ (function (_super) {
|
|
|
2339
2339
|
};
|
|
2340
2340
|
return Player;
|
|
2341
2341
|
}(EventEmitter));
|
|
2342
|
-
Player.version = /* PLAYER_VERSION */ "3.30.0
|
|
2342
|
+
Player.version = /* PLAYER_VERSION */ "3.30.0";
|
|
2343
2343
|
export default Player;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import { IEncryptedEventData } from "../../../../compat/eme";
|
|
18
18
|
import EventEmitter from "../../../../utils/event_emitter";
|
|
19
19
|
/** Default MediaKeySystemAccess configuration used by the RxPlayer. */
|
|
20
|
-
export declare const defaultKSConfig: {
|
|
20
|
+
export declare const defaultKSConfig: ({
|
|
21
21
|
audioCapabilities: {
|
|
22
22
|
contentType: string;
|
|
23
23
|
}[];
|
|
@@ -28,12 +28,19 @@ export declare const defaultKSConfig: {
|
|
|
28
28
|
videoCapabilities: {
|
|
29
29
|
contentType: string;
|
|
30
30
|
}[];
|
|
31
|
-
}
|
|
31
|
+
} | {
|
|
32
|
+
audioCapabilities: undefined;
|
|
33
|
+
distinctiveIdentifier: "optional";
|
|
34
|
+
initDataTypes: readonly ["cenc"];
|
|
35
|
+
persistentState: "optional";
|
|
36
|
+
sessionTypes: readonly ["temporary"];
|
|
37
|
+
videoCapabilities: undefined;
|
|
38
|
+
})[];
|
|
32
39
|
/**
|
|
33
40
|
* Default "com.microsoft.playready.recommendation" MediaKeySystemAccess
|
|
34
41
|
* configuration used by the RxPlayer.
|
|
35
42
|
*/
|
|
36
|
-
export declare const defaultPRRecommendationKSConfig: {
|
|
43
|
+
export declare const defaultPRRecommendationKSConfig: ({
|
|
37
44
|
audioCapabilities: {
|
|
38
45
|
robustness: string;
|
|
39
46
|
contentType: string;
|
|
@@ -46,22 +53,34 @@ export declare const defaultPRRecommendationKSConfig: {
|
|
|
46
53
|
robustness: string;
|
|
47
54
|
contentType: string;
|
|
48
55
|
}[];
|
|
49
|
-
}
|
|
56
|
+
} | {
|
|
57
|
+
audioCapabilities: undefined;
|
|
58
|
+
distinctiveIdentifier: "optional";
|
|
59
|
+
initDataTypes: readonly ["cenc"];
|
|
60
|
+
persistentState: "optional";
|
|
61
|
+
sessionTypes: readonly ["temporary"];
|
|
62
|
+
videoCapabilities: undefined;
|
|
63
|
+
})[];
|
|
50
64
|
/** Default Widevine MediaKeySystemAccess configuration used by the RxPlayer. */
|
|
51
|
-
export declare const defaultWidevineConfig: {
|
|
65
|
+
export declare const defaultWidevineConfig: ({
|
|
52
66
|
audioCapabilities: {
|
|
53
67
|
contentType: string;
|
|
54
|
-
robustness: string;
|
|
55
68
|
}[];
|
|
69
|
+
distinctiveIdentifier: "optional";
|
|
70
|
+
initDataTypes: readonly ["cenc"];
|
|
71
|
+
persistentState: "optional";
|
|
72
|
+
sessionTypes: readonly ["temporary"];
|
|
56
73
|
videoCapabilities: {
|
|
57
74
|
contentType: string;
|
|
58
|
-
robustness: string;
|
|
59
75
|
}[];
|
|
76
|
+
} | {
|
|
77
|
+
audioCapabilities: undefined;
|
|
60
78
|
distinctiveIdentifier: "optional";
|
|
61
79
|
initDataTypes: readonly ["cenc"];
|
|
62
80
|
persistentState: "optional";
|
|
63
81
|
sessionTypes: readonly ["temporary"];
|
|
64
|
-
|
|
82
|
+
videoCapabilities: undefined;
|
|
83
|
+
})[];
|
|
65
84
|
/**
|
|
66
85
|
* Custom implementation of an EME-compliant MediaKeyStatusMap.
|
|
67
86
|
* @class MediaKeyStatusMapImpl
|
|
@@ -44,7 +44,8 @@ import EventEmitter from "../../../../utils/event_emitter";
|
|
|
44
44
|
import flatMap from "../../../../utils/flat_map";
|
|
45
45
|
import { strToUtf8, utf8ToStr, } from "../../../../utils/string_parsing";
|
|
46
46
|
/** Default MediaKeySystemAccess configuration used by the RxPlayer. */
|
|
47
|
-
export var defaultKSConfig = [
|
|
47
|
+
export var defaultKSConfig = [
|
|
48
|
+
{
|
|
48
49
|
audioCapabilities: [{ contentType: "audio/mp4;codecs=\"mp4a.40.2\"" },
|
|
49
50
|
{ contentType: "audio/webm;codecs=opus" }],
|
|
50
51
|
distinctiveIdentifier: "optional",
|
|
@@ -54,12 +55,22 @@ export var defaultKSConfig = [{
|
|
|
54
55
|
videoCapabilities: [{ contentType: "video/mp4;codecs=\"avc1.4d401e\"" },
|
|
55
56
|
{ contentType: "video/mp4;codecs=\"avc1.42e01e\"" },
|
|
56
57
|
{ contentType: "video/webm;codecs=\"vp8\"" }],
|
|
57
|
-
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
audioCapabilities: undefined,
|
|
61
|
+
distinctiveIdentifier: "optional",
|
|
62
|
+
initDataTypes: ["cenc"],
|
|
63
|
+
persistentState: "optional",
|
|
64
|
+
sessionTypes: ["temporary"],
|
|
65
|
+
videoCapabilities: undefined,
|
|
66
|
+
},
|
|
67
|
+
];
|
|
58
68
|
/**
|
|
59
69
|
* Default "com.microsoft.playready.recommendation" MediaKeySystemAccess
|
|
60
70
|
* configuration used by the RxPlayer.
|
|
61
71
|
*/
|
|
62
|
-
export var defaultPRRecommendationKSConfig = [
|
|
72
|
+
export var defaultPRRecommendationKSConfig = [
|
|
73
|
+
{
|
|
63
74
|
audioCapabilities: [{ robustness: "3000",
|
|
64
75
|
contentType: "audio/mp4;codecs=\"mp4a.40.2\"" },
|
|
65
76
|
{ robustness: "3000",
|
|
@@ -84,7 +95,16 @@ export var defaultPRRecommendationKSConfig = [{
|
|
|
84
95
|
contentType: "video/mp4;codecs=\"avc1.42e01e\"" },
|
|
85
96
|
{ robustness: "2000",
|
|
86
97
|
contentType: "video/webm;codecs=\"vp8\"" }],
|
|
87
|
-
}
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
audioCapabilities: undefined,
|
|
101
|
+
distinctiveIdentifier: "optional",
|
|
102
|
+
initDataTypes: ["cenc"],
|
|
103
|
+
persistentState: "optional",
|
|
104
|
+
sessionTypes: ["temporary"],
|
|
105
|
+
videoCapabilities: undefined,
|
|
106
|
+
},
|
|
107
|
+
];
|
|
88
108
|
/** Default Widevine MediaKeySystemAccess configuration used by the RxPlayer. */
|
|
89
109
|
export var defaultWidevineConfig = (function () {
|
|
90
110
|
var ROBUSTNESSES = ["HW_SECURE_ALL",
|
|
@@ -101,9 +121,10 @@ export var defaultWidevineConfig = (function () {
|
|
|
101
121
|
return [{ contentType: "audio/mp4;codecs=\"mp4a.40.2\"", robustness: robustness },
|
|
102
122
|
{ contentType: "audio/webm;codecs=opus", robustness: robustness }];
|
|
103
123
|
});
|
|
104
|
-
return
|
|
105
|
-
|
|
106
|
-
|
|
124
|
+
return [
|
|
125
|
+
__assign(__assign({}, defaultKSConfig[0]), { audioCapabilities: audioCapabilities, videoCapabilities: videoCapabilities }),
|
|
126
|
+
defaultKSConfig[1],
|
|
127
|
+
];
|
|
107
128
|
})();
|
|
108
129
|
/**
|
|
109
130
|
* Custom implementation of an EME-compliant MediaKeyStatusMap.
|
|
@@ -13,6 +13,17 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
var __assign = (this && this.__assign) || function () {
|
|
17
|
+
__assign = Object.assign || function(t) {
|
|
18
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
19
|
+
s = arguments[i];
|
|
20
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
21
|
+
t[p] = s[p];
|
|
22
|
+
}
|
|
23
|
+
return t;
|
|
24
|
+
};
|
|
25
|
+
return __assign.apply(this, arguments);
|
|
26
|
+
};
|
|
16
27
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
17
28
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
18
29
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -130,7 +141,7 @@ function buildKeySystemConfigurations(ksName, ksType, keySystem) {
|
|
|
130
141
|
if (keySystem.distinctiveIdentifierRequired === true) {
|
|
131
142
|
distinctiveIdentifier = "required";
|
|
132
143
|
}
|
|
133
|
-
var _a = config.getCurrent(), EME_DEFAULT_WIDEVINE_ROBUSTNESSES = _a.EME_DEFAULT_WIDEVINE_ROBUSTNESSES, EME_DEFAULT_PLAYREADY_ROBUSTNESSES = _a.EME_DEFAULT_PLAYREADY_ROBUSTNESSES;
|
|
144
|
+
var _a = config.getCurrent(), EME_DEFAULT_AUDIO_CODECS = _a.EME_DEFAULT_AUDIO_CODECS, EME_DEFAULT_VIDEO_CODECS = _a.EME_DEFAULT_VIDEO_CODECS, EME_DEFAULT_WIDEVINE_ROBUSTNESSES = _a.EME_DEFAULT_WIDEVINE_ROBUSTNESSES, EME_DEFAULT_PLAYREADY_ROBUSTNESSES = _a.EME_DEFAULT_PLAYREADY_ROBUSTNESSES;
|
|
134
145
|
// Set robustness, in order of consideration:
|
|
135
146
|
// 1. the user specified its own robustnesses
|
|
136
147
|
// 2. a "widevine" key system is used, in that case set the default widevine
|
|
@@ -180,34 +191,32 @@ function buildKeySystemConfigurations(ksName, ksType, keySystem) {
|
|
|
180
191
|
// https://storage.googleapis.com/wvdocs/Chrome_EME_Changes_and_Best_Practices.pdf
|
|
181
192
|
// https://www.w3.org/TR/encrypted-media/#get-supported-configuration-and-consent
|
|
182
193
|
var videoCapabilities = flatMap(videoRobustnesses, function (robustness) {
|
|
183
|
-
return
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
return robustness !== undefined ? { contentType: contentType, robustness: robustness } :
|
|
187
|
-
{ contentType: contentType };
|
|
194
|
+
return EME_DEFAULT_VIDEO_CODECS.map(function (contentType) {
|
|
195
|
+
return robustness === undefined ? { contentType: contentType } :
|
|
196
|
+
{ contentType: contentType, robustness: robustness };
|
|
188
197
|
});
|
|
189
198
|
});
|
|
190
199
|
var audioCapabilities = flatMap(audioRobustnesses, function (robustness) {
|
|
191
|
-
return
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
{ contentType: contentType };
|
|
200
|
+
return EME_DEFAULT_AUDIO_CODECS.map(function (contentType) {
|
|
201
|
+
return robustness === undefined ? { contentType: contentType } :
|
|
202
|
+
{ contentType: contentType, robustness: robustness };
|
|
195
203
|
});
|
|
196
204
|
});
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
205
|
+
var wantedMediaKeySystemConfiguration = {
|
|
206
|
+
initDataTypes: ["cenc"],
|
|
207
|
+
videoCapabilities: videoCapabilities,
|
|
208
|
+
audioCapabilities: audioCapabilities,
|
|
209
|
+
distinctiveIdentifier: distinctiveIdentifier,
|
|
210
|
+
persistentState: persistentState,
|
|
211
|
+
sessionTypes: sessionTypes,
|
|
212
|
+
};
|
|
213
|
+
return [
|
|
214
|
+
wantedMediaKeySystemConfiguration,
|
|
215
|
+
// Some legacy implementations have issues with `audioCapabilities` and
|
|
216
|
+
// `videoCapabilities`, so we're including a supplementary
|
|
217
|
+
// `MediaKeySystemConfiguration` without those properties.
|
|
218
|
+
__assign(__assign({}, wantedMediaKeySystemConfiguration), { audioCapabilities: undefined, videoCapabilities: undefined }),
|
|
219
|
+
];
|
|
211
220
|
}
|
|
212
221
|
/**
|
|
213
222
|
* Try to find a compatible key system from the keySystems array given.
|
|
@@ -241,20 +241,34 @@ export default function SessionEventsListener(session, keySystemOptions, keySyst
|
|
|
241
241
|
function runGetLicense(message, messageType) {
|
|
242
242
|
var timeoutId;
|
|
243
243
|
return new Promise(function (res, rej) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
244
|
+
try {
|
|
245
|
+
log.debug("DRM: Calling `getLicense`", messageType);
|
|
246
|
+
var getLicense = keySystemOptions.getLicense(message, messageType);
|
|
247
|
+
var getLicenseTimeout_1 = isNullOrUndefined(getLicenseConfig.timeout) ?
|
|
248
|
+
10 * 1000 :
|
|
249
|
+
getLicenseConfig.timeout;
|
|
250
|
+
if (getLicenseTimeout_1 >= 0) {
|
|
251
|
+
timeoutId = setTimeout(function () {
|
|
252
|
+
rej(new GetLicenseTimeoutError("\"getLicense\" timeout exceeded (".concat(getLicenseTimeout_1, " ms)")));
|
|
253
|
+
}, getLicenseTimeout_1);
|
|
254
|
+
}
|
|
255
|
+
Promise.resolve(getLicense)
|
|
256
|
+
.then(clearTimeoutAndResolve, clearTimeoutAndReject);
|
|
257
|
+
}
|
|
258
|
+
catch (err) {
|
|
259
|
+
clearTimeoutAndReject(err);
|
|
253
260
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
261
|
+
function clearTimeoutAndResolve(data) {
|
|
262
|
+
if (timeoutId !== undefined) {
|
|
263
|
+
clearTimeout(timeoutId);
|
|
264
|
+
}
|
|
265
|
+
res(data);
|
|
266
|
+
}
|
|
267
|
+
function clearTimeoutAndReject(err) {
|
|
268
|
+
if (timeoutId !== undefined) {
|
|
269
|
+
clearTimeout(timeoutId);
|
|
270
|
+
}
|
|
271
|
+
rej(err);
|
|
258
272
|
}
|
|
259
273
|
});
|
|
260
274
|
}
|
|
@@ -333,17 +333,26 @@ export function scheduleRequestWithCdns(cdns, cdnPrioritizer, performRequest, op
|
|
|
333
333
|
throw cancellationSignal.cancellationError;
|
|
334
334
|
}
|
|
335
335
|
if (updatedPrioritaryCdn === undefined) {
|
|
336
|
-
return
|
|
336
|
+
return cleanAndReject(prevRequestError);
|
|
337
337
|
}
|
|
338
338
|
if (updatedPrioritaryCdn !== nextWantedCdn) {
|
|
339
339
|
canceller.cancel();
|
|
340
340
|
waitPotentialBackoffAndRequest(updatedPrioritaryCdn, prevRequestError)
|
|
341
|
-
.then(
|
|
341
|
+
.then(cleanAndResolve, cleanAndReject);
|
|
342
342
|
}
|
|
343
343
|
}, canceller.signal);
|
|
344
344
|
cancellableSleep(blockedFor, canceller.signal)
|
|
345
|
-
.then(function () { return requestCdn(nextWantedCdn)
|
|
346
|
-
|
|
345
|
+
.then(function () { return requestCdn(nextWantedCdn)
|
|
346
|
+
.then(cleanAndResolve, cleanAndReject); }, noop);
|
|
347
|
+
function cleanAndResolve(response) {
|
|
348
|
+
unlinkCanceller();
|
|
349
|
+
res(response);
|
|
350
|
+
}
|
|
351
|
+
function cleanAndReject(err) {
|
|
352
|
+
unlinkCanceller();
|
|
353
|
+
rej(err);
|
|
354
|
+
}
|
|
355
|
+
});
|
|
347
356
|
}
|
|
348
357
|
/**
|
|
349
358
|
* Takes in input the list of CDN that can be used to request the resource, in
|
|
@@ -153,7 +153,7 @@ function setMediaSourceDuration(mediaSource, manifest, knownDuration) {
|
|
|
153
153
|
if (maxBufferedEnd < mediaSource.duration) {
|
|
154
154
|
try {
|
|
155
155
|
log.info("Init: Updating duration to what is currently buffered", maxBufferedEnd);
|
|
156
|
-
mediaSource.duration =
|
|
156
|
+
mediaSource.duration = maxBufferedEnd;
|
|
157
157
|
}
|
|
158
158
|
catch (err) {
|
|
159
159
|
log.warn("Duration Updater: Can't update duration on the MediaSource.", err instanceof Error ? err : "");
|
|
@@ -100,7 +100,7 @@ var RebufferingController = /** @class */ (function (_super) {
|
|
|
100
100
|
this._canceller.signal.register(function () {
|
|
101
101
|
playbackRateUpdater.dispose();
|
|
102
102
|
});
|
|
103
|
-
var prevFreezingState;
|
|
103
|
+
var prevFreezingState = null;
|
|
104
104
|
this._playbackObserver.listen(function (observation) {
|
|
105
105
|
var _a;
|
|
106
106
|
var discontinuitiesStore = _this._discontinuitiesStore;
|
|
@@ -17,6 +17,8 @@ import nextTick from "next-tick";
|
|
|
17
17
|
import config from "../../../config";
|
|
18
18
|
import { formatError } from "../../../errors";
|
|
19
19
|
import log from "../../../log";
|
|
20
|
+
import cancellableSleep from "../../../utils/cancellable_sleep";
|
|
21
|
+
import noop from "../../../utils/noop";
|
|
20
22
|
import objectAssign from "../../../utils/object_assign";
|
|
21
23
|
import { createMappedReference, createSharedReference, } from "../../../utils/reference";
|
|
22
24
|
import TaskCanceller from "../../../utils/task_canceller";
|
|
@@ -252,16 +254,24 @@ export default function AdaptationStream(_a, callbacks, parentCancelSignal) {
|
|
|
252
254
|
defaultCode: "NONE",
|
|
253
255
|
defaultReason: "Unknown `RepresentationStream` error",
|
|
254
256
|
});
|
|
255
|
-
if (formattedError.code
|
|
257
|
+
if (formattedError.code !== "BUFFER_FULL_ERROR") {
|
|
258
|
+
representationStreamCallbacks.error(err);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
256
261
|
var wba = wantedBufferAhead.getValue();
|
|
257
262
|
var lastBufferGoalRatio = (_a = bufferGoalRatioMap.get(representation.id)) !== null && _a !== void 0 ? _a : 1;
|
|
258
|
-
|
|
263
|
+
// 70%, 49%, 34.3%, 24%, 16.81%, 11.76%, 8.24% and 5.76%
|
|
264
|
+
var newBufferGoalRatio = lastBufferGoalRatio * 0.7;
|
|
265
|
+
if (newBufferGoalRatio <= 0.05 || wba * newBufferGoalRatio <= 2) {
|
|
259
266
|
throw formattedError;
|
|
260
267
|
}
|
|
261
|
-
bufferGoalRatioMap.set(representation.id,
|
|
262
|
-
|
|
268
|
+
bufferGoalRatioMap.set(representation.id, newBufferGoalRatio);
|
|
269
|
+
// We wait 4 seconds to let the situation evolve by itself before
|
|
270
|
+
// retrying loading segments with a lower buffer goal
|
|
271
|
+
cancellableSleep(4000, adapStreamCanceller.signal).then(function () {
|
|
272
|
+
return createRepresentationStream(representation, terminateCurrentStream, fastSwitchThreshold, representationStreamCallbacks);
|
|
273
|
+
}).catch(noop);
|
|
263
274
|
}
|
|
264
|
-
representationStreamCallbacks.error(err);
|
|
265
275
|
},
|
|
266
276
|
terminating: function () {
|
|
267
277
|
terminatingRepStreamCanceller.cancel();
|