rx-player
Version:
Canal+ HTML5 Video Player
234 lines (233 loc) • 9.97 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 __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = getWebKitMediaKeysCallbacks;
var byte_parsing_1 = require("../../../utils/byte_parsing");
var event_emitter_1 = require("../../../utils/event_emitter");
var noop_1 = require("../../../utils/noop");
var starts_with_1 = require("../../../utils/starts_with");
var wrapInPromise_1 = require("../../../utils/wrapInPromise");
var get_webkit_fairplay_initdata_1 = require("../get_webkit_fairplay_initdata");
var webkit_media_keys_constructor_1 = require("./webkit_media_keys_constructor");
/**
* Check if keyType is for fairplay DRM
* @param {string} keyType
* @returns {boolean}
*/
function isFairplayKeyType(keyType) {
return (0, starts_with_1.default)(keyType, "com.apple.fps");
}
/**
* Set media keys on video element using native HTMLMediaElement
* setMediaKeys from WebKit.
* @param {HTMLMediaElement} elt
* @param {Object|null} mediaKeys
* @returns {Promise}
*/
function setWebKitMediaKeys(elt, mediaKeys) {
return (0, wrapInPromise_1.default)(function () {
if (elt.webkitSetMediaKeys === undefined) {
throw new Error("No webKitMediaKeys API.");
}
elt.webkitSetMediaKeys(mediaKeys);
});
}
/**
* On Safari browsers (>= 9), there are specific webkit prefixed APIs for cyphered
* content playback. Standard EME APIs are therefore available since Safari 12.1, but they
* don't allow to play fairplay cyphered content.
*
* This class implements a standard EME API polyfill that wraps webkit prefixed Safari
* EME custom APIs.
*/
var WebkitMediaKeySession = /** @class */ (function (_super) {
__extends(WebkitMediaKeySession, _super);
/**
* @param {HTMLMediaElement} mediaElement
* @param {string} keyType
* @param {Uint8Array | undefined} serverCertificate
*/
function WebkitMediaKeySession(mediaElement, keyType, serverCertificate) {
var _this = _super.call(this) || this;
_this._serverCertificate = serverCertificate;
_this._videoElement = mediaElement;
_this._keyType = keyType;
_this._unbindSession = noop_1.default;
_this._closeSession = noop_1.default; // Just here to make TypeScript happy
_this.closed = new Promise(function (resolve) {
_this._closeSession = resolve;
});
_this.keyStatuses = new Map();
_this.expiration = NaN;
return _this;
}
WebkitMediaKeySession.prototype.update = function (license) {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this._nativeSession === undefined ||
_this._nativeSession.update === undefined ||
typeof _this._nativeSession.update !== "function") {
return reject("Unavailable WebKit key session.");
}
try {
var uInt8Arraylicense = (0, byte_parsing_1.toUint8Array)(license);
resolve(_this._nativeSession.update(uInt8Arraylicense));
}
catch (err) {
reject(err);
}
});
};
WebkitMediaKeySession.prototype.generateRequest = function (_initDataType, initData) {
var _this = this;
return new Promise(function (resolve) {
var _a;
var elt = _this._videoElement;
if (((_a = elt.webkitKeys) === null || _a === void 0 ? void 0 : _a.createSession) === undefined) {
throw new Error("No WebKitMediaKeys API.");
}
var formattedInitData;
if (isFairplayKeyType(_this._keyType)) {
if (_this._serverCertificate === undefined) {
throw new Error("A server certificate is needed for creating fairplay session.");
}
formattedInitData = (0, get_webkit_fairplay_initdata_1.default)(initData, _this._serverCertificate);
}
else {
formattedInitData = initData;
}
var keySession = elt.webkitKeys.createSession("video/mp4", formattedInitData);
if (keySession === undefined || keySession === null) {
throw new Error("Impossible to get the key sessions");
}
_this._listenEvent(keySession);
_this._nativeSession = keySession;
resolve();
});
};
WebkitMediaKeySession.prototype.close = function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this._unbindSession();
_this._closeSession("closed-by-application");
if (_this._nativeSession === undefined) {
reject("No session to close.");
return;
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
_this._nativeSession.close();
resolve();
});
};
WebkitMediaKeySession.prototype.load = function () {
return Promise.resolve(false);
};
WebkitMediaKeySession.prototype.remove = function () {
return Promise.resolve();
};
Object.defineProperty(WebkitMediaKeySession.prototype, "sessionId", {
get: function () {
var _a, _b;
return (_b = (_a = this._nativeSession) === null || _a === void 0 ? void 0 : _a.sessionId) !== null && _b !== void 0 ? _b : "";
},
enumerable: false,
configurable: true
});
WebkitMediaKeySession.prototype._listenEvent = function (session) {
var _this = this;
this._unbindSession(); // If previous session was linked
var onEvent = function (evt) {
_this.trigger(evt.type, evt);
};
["keymessage", "message", "keyadded", "ready", "keyerror", "error"].forEach(function (evt) {
session.addEventListener(evt, onEvent);
session.addEventListener("webkit".concat(evt), onEvent);
});
this._unbindSession = function () {
["keymessage", "message", "keyadded", "ready", "keyerror", "error"].forEach(function (evt) {
session.removeEventListener(evt, onEvent);
session.removeEventListener("webkit".concat(evt), onEvent);
});
};
};
return WebkitMediaKeySession;
}(event_emitter_1.default));
var WebKitCustomMediaKeys = /** @class */ (function () {
function WebKitCustomMediaKeys(keyType) {
var WebKitMediaKeysConstructor = (0, webkit_media_keys_constructor_1.default)();
if (WebKitMediaKeysConstructor === undefined) {
throw new Error("No WebKitMediaKeys API.");
}
this._keyType = keyType;
this._mediaKeys = new WebKitMediaKeysConstructor(keyType);
}
WebKitCustomMediaKeys.prototype._setVideo = function (videoElement) {
this._videoElement = videoElement;
if (this._videoElement === undefined) {
throw new Error("Video not attached to the MediaKeys");
}
return setWebKitMediaKeys(this._videoElement, this._mediaKeys);
};
WebKitCustomMediaKeys.prototype.createSession = function ( /* sessionType */) {
if (this._videoElement === undefined || this._mediaKeys === undefined) {
throw new Error("Video not attached to the MediaKeys");
}
return new WebkitMediaKeySession(this._videoElement, this._keyType, this._serverCertificate);
};
WebKitCustomMediaKeys.prototype.setServerCertificate = function (serverCertificate) {
this._serverCertificate = serverCertificate;
return Promise.resolve(true);
};
return WebKitCustomMediaKeys;
}());
function getWebKitMediaKeysCallbacks() {
var WebKitMediaKeysConstructor = (0, webkit_media_keys_constructor_1.default)();
if (WebKitMediaKeysConstructor === undefined) {
throw new Error("No WebKitMediaKeys API.");
}
var isTypeSupported = WebKitMediaKeysConstructor.isTypeSupported;
var createCustomMediaKeys = function (keyType) { return new WebKitCustomMediaKeys(keyType); };
var setMediaKeys = function (elt, mediaKeys) {
if (mediaKeys === null) {
return setWebKitMediaKeys(elt, mediaKeys);
}
if (!(mediaKeys instanceof WebKitCustomMediaKeys)) {
throw new Error("Custom setMediaKeys is supposed to be called " + "with webkit custom MediaKeys.");
}
return mediaKeys._setVideo(elt);
};
return {
isTypeSupported: isTypeSupported,
createCustomMediaKeys: createCustomMediaKeys,
setMediaKeys: setMediaKeys,
};
}