rx-player
Version:
Canal+ HTML5 Video Player
115 lines (114 loc) • 5.14 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.
*/
import canReuseMediaKeys from "../../compat/can_reuse_media_keys";
import { EncryptedMediaError } from "../../errors";
import log from "../../log";
import isNullOrUndefined from "../../utils/is_null_or_undefined";
import getMediaKeySystemAccess from "./find_key_system";
import LoadedSessionsStore from "./utils/loaded_sessions_store";
import MediaKeysAttacher from "./utils/media_keys_attacher";
import PersistentSessionsStore from "./utils/persistent_sessions_store";
import ServerCertificateStore from "./utils/server_certificate_store";
/**
* @throws {EncryptedMediaError}
* @param {Object} keySystemOptions
* @returns {Object|null}
*/
function createPersistentSessionsStorage(keySystemOptions) {
const { persistentLicenseConfig } = keySystemOptions;
if (isNullOrUndefined(persistentLicenseConfig)) {
return null;
}
log.debug("DRM", "Set the given license storage");
return new PersistentSessionsStore(persistentLicenseConfig);
}
/**
* Create a MediaKeys instance and associated structures (or just return the
* current ones if sufficient) based on a wanted configuration.
* @param {Object} eme - current EME implementation
* @param {HTMLMediaElement} mediaElement - The HTMLMediaElement on which you
* will attach the MediaKeys instance.
* This Element is here only used to check if the current MediaKeys and
* MediaKeySystemAccess instances are sufficient
* @param {Array.<Object>} keySystemsConfigs - The key system configuration.
* Needed to ask the right MediaKeySystemAccess.
* @param {Object} cancelSignal - CancellationSignal allowing to cancel the
* creation of the MediaKeys instance while the task is still pending.
* @returns {Promise.<Object>}
*/
export default async function getMediaKeysInfos(eme, mediaElement, keySystemsConfigs, cancelSignal) {
const evt = await getMediaKeySystemAccess(eme, mediaElement, keySystemsConfigs, cancelSignal);
if (cancelSignal.cancellationError !== null) {
throw cancelSignal.cancellationError;
}
const { options, mediaKeySystemAccess, askedConfiguration, codecSupport } = evt.value;
const currentState = await MediaKeysAttacher.getAttachedMediaKeysState(mediaElement);
const persistentSessionsStore = createPersistentSessionsStorage(options);
if (evt.value.options.reuseMediaKeys !== false &&
canReuseMediaKeys() &&
currentState !== null &&
evt.type === "reuse-media-key-system-access") {
log.debug("DRM", "Reusing already created MediaKeys");
const { mediaKeys, loadedSessionsStore } = currentState;
// We might just rely on the currently attached MediaKeys instance.
// First check if server certificate parameters are the same than in the
// current MediaKeys instance. If not, re-create MediaKeys from scratch.
if (ServerCertificateStore.hasOne(mediaKeys) === false ||
(!isNullOrUndefined(options.serverCertificate) &&
ServerCertificateStore.has(mediaKeys, options.serverCertificate))) {
return {
mediaKeys,
mediaKeySystemAccess,
askedConfiguration,
stores: { loadedSessionsStore, persistentSessionsStore },
options,
codecSupport,
};
}
}
const mediaKeys = await createMediaKeys(mediaKeySystemAccess);
log.info("DRM", "MediaKeys created with success");
const loadedSessionsStore = new LoadedSessionsStore(mediaKeys);
return {
mediaKeys,
mediaKeySystemAccess,
askedConfiguration,
stores: { loadedSessionsStore, persistentSessionsStore },
options,
codecSupport,
};
}
/**
* Create `MediaKeys` from the `MediaKeySystemAccess` given.
* Throws the right formatted error if it fails.
* @param {MediaKeySystemAccess} mediaKeySystemAccess
* @returns {Promise.<MediaKeys>}
*/
async function createMediaKeys(mediaKeySystemAccess) {
log.info("DRM", "Calling createMediaKeys on the MediaKeySystemAccess");
try {
const mediaKeys = await mediaKeySystemAccess.createMediaKeys();
return mediaKeys;
}
catch (error) {
const message = error instanceof Error ? error.message : "Unknown error when creating MediaKeys.";
throw new EncryptedMediaError("CREATE_MEDIA_KEYS_ERROR", message, {
keyStatuses: undefined,
keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
keySystem: mediaKeySystemAccess.keySystem,
});
}
}