rx-player
Version:
Canal+ HTML5 Video Player
579 lines (578 loc) • 30.3 kB
JavaScript
;
/**
* Copyright 2015 CANAL+ Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractCodecSupportListFromConfiguration = extractCodecSupportListFromConfiguration;
exports.default = getMediaKeySystemAccess;
exports.testKeySystem = testKeySystem;
var can_rely_on_request_media_key_system_access_1 = require("../../compat/can_rely_on_request_media_key_system_access");
var eme_1 = require("../../compat/eme");
var generate_init_data_1 = require("../../compat/generate_init_data");
var should_renew_media_key_system_access_1 = require("../../compat/should_renew_media_key_system_access");
var config_1 = require("../../config");
var errors_1 = require("../../errors");
var log_1 = require("../../log");
var are_codecs_compatible_1 = require("../../utils/are_codecs_compatible");
var array_includes_1 = require("../../utils/array_includes");
var flat_map_1 = require("../../utils/flat_map");
var is_null_or_undefined_1 = require("../../utils/is_null_or_undefined");
var media_keys_attacher_1 = require("./utils/media_keys_attacher");
/**
* Takes a `newConfiguration` `MediaKeySystemConfiguration`, that is intended
* for the creation of a `MediaKeySystemAccess`, and a `prevConfiguration`
* `MediaKeySystemConfiguration`, that was the one used at creation of the
* current `MediaKeySystemAccess`.
*
* This function will then return `true` if it determined that the new
* configuration is conceptually compatible with the one used before, and
* `false` otherwise.
* @param {Object} newConfiguration - New wanted `MediaKeySystemConfiguration`
* @param {Object} prevConfiguration - The `MediaKeySystemConfiguration` that is
* relied on util now.
* @returns {boolean} - `true` if `newConfiguration` is compatible with
* `prevConfiguration`.
*/
function isNewMediaKeySystemConfigurationCompatibleWithPreviousOne(newConfiguration, prevConfiguration) {
var e_1, _a;
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
if (newConfiguration.label !== prevConfiguration.label) {
return false;
}
var prevDistinctiveIdentifier = (_b = prevConfiguration.distinctiveIdentifier) !== null && _b !== void 0 ? _b : "optional";
var newDistinctiveIdentifier = (_c = newConfiguration.distinctiveIdentifier) !== null && _c !== void 0 ? _c : "optional";
if (prevDistinctiveIdentifier !== newDistinctiveIdentifier) {
return false;
}
var prevPersistentState = (_d = prevConfiguration.persistentState) !== null && _d !== void 0 ? _d : "optional";
var newPersistentState = (_e = newConfiguration.persistentState) !== null && _e !== void 0 ? _e : "optional";
if (prevPersistentState !== newPersistentState) {
return false;
}
var prevInitDataTypes = (_f = prevConfiguration.initDataTypes) !== null && _f !== void 0 ? _f : [];
var newInitDataTypes = (_g = newConfiguration.initDataTypes) !== null && _g !== void 0 ? _g : [];
if (!isArraySubsetOf(newInitDataTypes, prevInitDataTypes)) {
return false;
}
var prevSessionTypes = (_h = prevConfiguration.sessionTypes) !== null && _h !== void 0 ? _h : [];
var newSessionTypes = (_j = newConfiguration.sessionTypes) !== null && _j !== void 0 ? _j : [];
if (!isArraySubsetOf(newSessionTypes, prevSessionTypes)) {
return false;
}
var _loop_1 = function (prop) {
var newCapabilities = (_k = newConfiguration[prop]) !== null && _k !== void 0 ? _k : [];
var prevCapabilities = (_l = prevConfiguration[prop]) !== null && _l !== void 0 ? _l : [];
var wasFound = newCapabilities.every(function (n) {
var _a, _b, _c, _d, _e, _f;
for (var i = 0; i < prevCapabilities.length; i++) {
var prevCap = prevCapabilities[i];
if (((_a = prevCap.robustness) !== null && _a !== void 0 ? _a : "") === ((_b = n.robustness) !== null && _b !== void 0 ? _b : "") ||
((_c = prevCap.encryptionScheme) !== null && _c !== void 0 ? _c : null) === ((_d = n.encryptionScheme) !== null && _d !== void 0 ? _d : null) ||
((_e = prevCap.robustness) !== null && _e !== void 0 ? _e : "") === ((_f = n.robustness) !== null && _f !== void 0 ? _f : "")) {
return true;
}
}
return false;
});
if (!wasFound) {
return { value: false };
}
};
try {
for (var _m = __values(["audioCapabilities", "videoCapabilities"]), _o = _m.next(); !_o.done; _o = _m.next()) {
var prop = _o.value;
var state_1 = _loop_1(prop);
if (typeof state_1 === "object")
return state_1.value;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_o && !_o.done && (_a = _m.return)) _a.call(_m);
}
finally { if (e_1) throw e_1.error; }
}
return true;
}
/**
* Find key system canonical name from key system type.
* @param {string} ksType - Obtained via inversion
* @returns {string|undefined} - Either the canonical name, or undefined.
*/
function findKeySystemCanonicalName(ksType) {
var e_2, _a;
var EME_KEY_SYSTEMS = config_1.default.getCurrent().EME_KEY_SYSTEMS;
try {
for (var _b = __values(Object.keys(EME_KEY_SYSTEMS)), _c = _b.next(); !_c.done; _c = _b.next()) {
var ksName = _c.value;
if ((0, array_includes_1.default)(EME_KEY_SYSTEMS[ksName], ksType)) {
return ksName;
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
return undefined;
}
/**
* Build configuration for the requestMediaKeySystemAccess EME API, based
* on the current keySystem object.
* @param {Object} keySystemTypeInfo
* @returns {Array.<Object>} - Configuration to give to the
* requestMediaKeySystemAccess API.
*/
function buildKeySystemConfigurations(keySystemTypeInfo) {
var keyName = keySystemTypeInfo.keyName, keyType = keySystemTypeInfo.keyType, keySystem = keySystemTypeInfo.keySystemOptions;
var sessionTypes;
var persistentState = "optional";
var distinctiveIdentifier = "optional";
if (Array.isArray(keySystem.wantedSessionTypes)) {
sessionTypes = keySystem.wantedSessionTypes;
if ((0, array_includes_1.default)(keySystem.wantedSessionTypes, "persistent-license") &&
!(0, is_null_or_undefined_1.default)(keySystem.persistentLicenseConfig)) {
persistentState = "required";
}
}
else if (!(0, is_null_or_undefined_1.default)(keySystem.persistentLicenseConfig)) {
persistentState = "required";
sessionTypes = ["persistent-license"];
}
else {
sessionTypes = ["temporary"];
}
if (!(0, is_null_or_undefined_1.default)(keySystem.persistentState)) {
persistentState = keySystem.persistentState;
}
if (!(0, is_null_or_undefined_1.default)(keySystem.distinctiveIdentifier)) {
distinctiveIdentifier = keySystem.distinctiveIdentifier;
}
var _a = config_1.default.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_RECOMMENDATION_ROBUSTNESSES = _a.EME_DEFAULT_PLAYREADY_RECOMMENDATION_ROBUSTNESSES;
// From the W3 EME spec, we have to provide videoCapabilities and
// audioCapabilities.
// These capabilities must specify a codec (even though you can use a
// completely different codec afterward).
// It is also strongly recommended to specify the required security
// robustness. As we do not want to forbide any security level, we specify
// every existing security level from highest to lowest so that the best
// security level is selected.
// More details here:
// https://storage.googleapis.com/wvdocs/Chrome_EME_Changes_and_Best_Practices.pdf
// https://www.w3.org/TR/encrypted-media/#get-supported-configuration-and-consent
var audioCapabilities;
var videoCapabilities;
var audioCapabilitiesConfig = keySystem.audioCapabilitiesConfig, videoCapabilitiesConfig = keySystem.videoCapabilitiesConfig;
if ((audioCapabilitiesConfig === null || audioCapabilitiesConfig === void 0 ? void 0 : audioCapabilitiesConfig.type) === "full") {
audioCapabilities = audioCapabilitiesConfig.value;
}
else {
var audioRobustnesses = void 0;
if ((audioCapabilitiesConfig === null || audioCapabilitiesConfig === void 0 ? void 0 : audioCapabilitiesConfig.type) === "robustness") {
audioRobustnesses = audioCapabilitiesConfig.value;
}
else if (keyName === "widevine") {
audioRobustnesses = EME_DEFAULT_WIDEVINE_ROBUSTNESSES;
}
else if (keyType === "com.microsoft.playready.recommendation") {
audioRobustnesses = EME_DEFAULT_PLAYREADY_RECOMMENDATION_ROBUSTNESSES;
}
else {
audioRobustnesses = [];
}
if (audioRobustnesses.length === 0) {
audioRobustnesses.push(undefined);
}
var audioCodecs_1 = (audioCapabilitiesConfig === null || audioCapabilitiesConfig === void 0 ? void 0 : audioCapabilitiesConfig.type) === "contentType"
? audioCapabilitiesConfig.value
: EME_DEFAULT_AUDIO_CODECS;
audioCapabilities = (0, flat_map_1.default)(audioRobustnesses, function (robustness) {
return audioCodecs_1.map(function (contentType) {
return robustness !== undefined ? { contentType: contentType, robustness: robustness } : { contentType: contentType };
});
});
}
if ((videoCapabilitiesConfig === null || videoCapabilitiesConfig === void 0 ? void 0 : videoCapabilitiesConfig.type) === "full") {
videoCapabilities = videoCapabilitiesConfig.value;
}
else {
var videoRobustnesses = void 0;
if ((videoCapabilitiesConfig === null || videoCapabilitiesConfig === void 0 ? void 0 : videoCapabilitiesConfig.type) === "robustness") {
videoRobustnesses = videoCapabilitiesConfig.value;
}
else if (keyName === "widevine") {
videoRobustnesses = EME_DEFAULT_WIDEVINE_ROBUSTNESSES;
}
else if (keyType === "com.microsoft.playready.recommendation") {
videoRobustnesses = EME_DEFAULT_PLAYREADY_RECOMMENDATION_ROBUSTNESSES;
}
else {
videoRobustnesses = [];
}
if (videoRobustnesses.length === 0) {
videoRobustnesses.push(undefined);
}
var videoCodecs_1 = (videoCapabilitiesConfig === null || videoCapabilitiesConfig === void 0 ? void 0 : videoCapabilitiesConfig.type) === "contentType"
? videoCapabilitiesConfig.value
: EME_DEFAULT_VIDEO_CODECS;
videoCapabilities = (0, flat_map_1.default)(videoRobustnesses, function (robustness) {
return videoCodecs_1.map(function (contentType) {
return robustness !== undefined ? { contentType: contentType, robustness: robustness } : { contentType: contentType };
});
});
}
var wantedMediaKeySystemConfiguration = {
initDataTypes: ["cenc"],
videoCapabilities: videoCapabilities,
audioCapabilities: audioCapabilities,
distinctiveIdentifier: distinctiveIdentifier,
persistentState: persistentState,
sessionTypes: sessionTypes,
};
if (audioCapabilitiesConfig !== undefined) {
if (videoCapabilitiesConfig !== undefined) {
return [wantedMediaKeySystemConfiguration];
}
return [
wantedMediaKeySystemConfiguration,
__assign(__assign({}, wantedMediaKeySystemConfiguration), {
// Re-try without `videoCapabilities` in case the EME implementation is
// buggy
videoCapabilities: undefined }),
];
}
else if (videoCapabilitiesConfig !== undefined) {
return [
wantedMediaKeySystemConfiguration,
__assign(__assign({}, wantedMediaKeySystemConfiguration), {
// Re-try without `audioCapabilities` in case the EME implementation is
// buggy
audioCapabilities: undefined }),
];
}
return [
wantedMediaKeySystemConfiguration,
// Some legacy implementations have issues with `audioCapabilities` and
// `videoCapabilities`, so we're including a supplementary
// `MediaKeySystemConfiguration` without those properties.
__assign(__assign({}, wantedMediaKeySystemConfiguration), { audioCapabilities: undefined, videoCapabilities: undefined }),
];
}
/**
* Extract from the current mediaKeys the supported Codecs.
* @param {Object} initialConfiguration - The MediaKeySystemConfiguration given
* to the `navigator.requestMediaKeySystemAccess` API.
* @param {Object | undefined} mksConfiguration - The result of
* getConfiguration() of the media keys.
* @return {Array} The list of supported codec by the CDM.
*/
function extractCodecSupportListFromConfiguration(initialConfiguration, mksConfiguration) {
var _a, _b, _c, _d, _e, _f;
var testedAudioCodecs = (_b = (_a = initialConfiguration.audioCapabilities) === null || _a === void 0 ? void 0 : _a.map(function (v) { return v.contentType; })) !== null && _b !== void 0 ? _b : [];
var testedVideoCodecs = (_d = (_c = initialConfiguration.videoCapabilities) === null || _c === void 0 ? void 0 : _c.map(function (v) { return v.contentType; })) !== null && _d !== void 0 ? _d : [];
var testedCodecs = testedAudioCodecs
.concat(testedVideoCodecs)
.filter(function (c) { return c !== undefined; });
var supportedVideoCodecs = (_e = mksConfiguration.videoCapabilities) === null || _e === void 0 ? void 0 : _e.map(function (entry) { return entry.contentType; });
var supportedAudioCodecs = (_f = mksConfiguration.audioCapabilities) === null || _f === void 0 ? void 0 : _f.map(function (entry) { return entry.contentType; });
var supportedCodecs = __spreadArray(__spreadArray([], __read((supportedVideoCodecs !== null && supportedVideoCodecs !== void 0 ? supportedVideoCodecs : [])), false), __read((supportedAudioCodecs !== null && supportedAudioCodecs !== void 0 ? supportedAudioCodecs : [])), false).filter(function (contentType) { return contentType !== undefined; });
if (supportedCodecs.length === 0) {
// Some legacy implementations have issues with `audioCapabilities` and
// `videoCapabilities` in requestMediaKeySystemAccess so the codecs are not provided.
// In this case, we can't tell which codec is supported or not.
// Let's instead provide an empty list.
// Note: on a correct EME implementation, if a list of codec is provided
// with `audioCapabilities` or `videoCapabilities`, but none of them is supported,
// requestMediaKeySystemAccess should yield an error "NotSupported" and we should
// never reach this code.
return [];
}
var codecSupportList = testedCodecs.map(function (codec) {
var _a = (0, are_codecs_compatible_1.parseCodec)(codec), codecs = _a.codecs, mimeType = _a.mimeType;
var isSupported = (0, array_includes_1.default)(supportedCodecs, codec);
return {
codec: codecs,
mimeType: mimeType,
result: isSupported,
};
});
return codecSupportList;
}
/**
* Try to find a compatible key system from the keySystems array given.
*
* This function will request a MediaKeySystemAccess based on the various
* keySystems provided.
*
* This Promise might either:
* - resolves the MediaKeySystemAccess and the keySystems as an object, when
* found.
* - reject if no compatible key system has been found.
*
* @param {HTMLMediaElement} mediaElement
* @param {Array.<Object>} keySystemsConfigs - The keySystems you want to test.
* @param {Object} cancelSignal
* @returns {Promise.<Object>}
*/
function getMediaKeySystemAccess(mediaElement, keySystemsConfigs, cancelSignal) {
log_1.default.info("DRM: Searching for compatible MediaKeySystemAccess");
/** Array of set keySystems for this content. */
var keySystemsType = keySystemsConfigs.reduce(function (arr, keySystemOptions) {
var EME_KEY_SYSTEMS = config_1.default.getCurrent().EME_KEY_SYSTEMS;
var managedRDNs = EME_KEY_SYSTEMS[keySystemOptions.type];
var ksType;
if (!(0, is_null_or_undefined_1.default)(managedRDNs)) {
ksType = managedRDNs.map(function (keyType) {
var keyName = keySystemOptions.type;
return { keyName: keyName, keyType: keyType, keySystemOptions: keySystemOptions };
});
}
else {
var keyName = findKeySystemCanonicalName(keySystemOptions.type);
var keyType = keySystemOptions.type;
ksType = [{ keyName: keyName, keyType: keyType, keySystemOptions: keySystemOptions }];
}
return arr.concat(ksType);
}, []);
return recursivelyTestKeySystems(0);
/**
* Test all key system configuration stored in `keySystemsType` one by one
* recursively.
* Returns a Promise which will emit the MediaKeySystemAccess if one was
* found compatible with one of the configurations or just reject if none
* were found to be compatible.
* @param {Number} index - The index in `keySystemsType` to start from.
* Should be set to `0` when calling directly.
* @returns {Promise.<Object>}
*/
function recursivelyTestKeySystems(index) {
return __awaiter(this, void 0, void 0, function () {
var chosenType, keyType, keySystemOptions, keySystemConfigurations, keySystemAccess, currentState, configIdx, keySystemConfiguration, _1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
// if we iterated over the whole keySystemsType Array, quit on error
if (index >= keySystemsType.length) {
throw new errors_1.EncryptedMediaError("INCOMPATIBLE_KEYSYSTEMS", "No key system compatible with your wanted " +
"configuration has been found in the current " +
"browser.");
}
if ((0, is_null_or_undefined_1.default)(eme_1.default.requestMediaKeySystemAccess)) {
throw new Error("requestMediaKeySystemAccess is not implemented in your browser.");
}
chosenType = keySystemsType[index];
keyType = chosenType.keyType, keySystemOptions = chosenType.keySystemOptions;
keySystemConfigurations = buildKeySystemConfigurations(chosenType);
log_1.default.debug("DRM: Request keysystem access ".concat(keyType, ",") +
"".concat(index + 1, " of ").concat(keySystemsType.length));
return [4 /*yield*/, media_keys_attacher_1.default.getAttachedMediaKeysState(mediaElement)];
case 1:
currentState = _a.sent();
configIdx = 0;
_a.label = 2;
case 2:
if (!(configIdx < keySystemConfigurations.length)) return [3 /*break*/, 7];
keySystemConfiguration = keySystemConfigurations[configIdx];
// Check if the current `MediaKeySystemAccess` created cannot be reused here
if (currentState !== null &&
!(0, should_renew_media_key_system_access_1.default)() &&
// TODO: Do it with MediaKeySystemAccess.prototype.keySystem instead?
keyType === currentState.mediaKeySystemAccess.keySystem &&
eme_1.default.implementation === currentState.emeImplementation.implementation &&
isNewMediaKeySystemConfigurationCompatibleWithPreviousOne(keySystemConfiguration, currentState.askedConfiguration)) {
log_1.default.info("DRM: Found cached compatible keySystem");
return [2 /*return*/, Promise.resolve({
type: "reuse-media-key-system-access",
value: {
mediaKeySystemAccess: currentState.mediaKeySystemAccess,
askedConfiguration: currentState.askedConfiguration,
options: keySystemOptions,
codecSupport: extractCodecSupportListFromConfiguration(currentState.askedConfiguration, currentState.mediaKeySystemAccess.getConfiguration()),
},
})];
}
_a.label = 3;
case 3:
_a.trys.push([3, 5, , 6]);
return [4 /*yield*/, testKeySystem(keyType, [keySystemConfiguration])];
case 4:
keySystemAccess = _a.sent();
log_1.default.info("DRM: Found compatible keysystem", keyType, index + 1);
return [2 /*return*/, {
type: "create-media-key-system-access",
value: {
options: keySystemOptions,
mediaKeySystemAccess: keySystemAccess,
askedConfiguration: keySystemConfiguration,
codecSupport: extractCodecSupportListFromConfiguration(keySystemConfiguration, keySystemAccess.getConfiguration()),
},
}];
case 5:
_1 = _a.sent();
log_1.default.debug("DRM: Rejected access to keysystem", keyType, index + 1, configIdx);
if (cancelSignal.cancellationError !== null) {
throw cancelSignal.cancellationError;
}
return [3 /*break*/, 6];
case 6:
configIdx++;
return [3 /*break*/, 2];
case 7: return [2 /*return*/, recursivelyTestKeySystems(index + 1)];
}
});
});
}
}
/**
* Test a key system configuration, resolves with the MediaKeySystemAccess
* or reject if the key system is unsupported.
* @param {string} keyType - The KeySystem string to test (ex: com.microsoft.playready.recommendation)
* @param {Array.<MediaKeySystemMediaCapability>} keySystemConfigurations - Configurations for this keySystem
* @returns Promise resolving with the MediaKeySystemAccess. Rejects if unsupported.
*/
function testKeySystem(keyType, keySystemConfigurations) {
return __awaiter(this, void 0, void 0, function () {
var keySystemAccess, mediaKeys, session, initData, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, eme_1.default.requestMediaKeySystemAccess(keyType, keySystemConfigurations)];
case 1:
keySystemAccess = _a.sent();
if (!!(0, can_rely_on_request_media_key_system_access_1.canRelyOnRequestMediaKeySystemAccess)(keyType)) return [3 /*break*/, 6];
_a.label = 2;
case 2:
_a.trys.push([2, 5, , 6]);
return [4 /*yield*/, keySystemAccess.createMediaKeys()];
case 3:
mediaKeys = _a.sent();
session = mediaKeys.createSession();
initData = (0, generate_init_data_1.generatePlayReadyInitData)(generate_init_data_1.DUMMY_PLAY_READY_HEADER);
return [4 /*yield*/, session.generateRequest("cenc", initData)];
case 4:
_a.sent();
session.close().catch(function () {
log_1.default.warn("DRM: Failed to close the dummy session");
});
return [3 /*break*/, 6];
case 5:
err_1 = _a.sent();
log_1.default.debug("DRM: KeySystemAccess was granted but it is not usable");
throw err_1;
case 6: return [2 /*return*/, keySystemAccess];
}
});
});
}
/**
* Returns `true` if `arr1`'s values are entirely contained in `arr2`.
* @param {string} arr1
* @param {string} arr2
* @return {boolean}
*/
function isArraySubsetOf(arr1, arr2) {
for (var i = 0; i < arr1.length; i++) {
if (!(0, array_includes_1.default)(arr2, arr1[i])) {
return false;
}
}
return true;
}