Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into ts-cea-parser
Browse files Browse the repository at this point in the history
avelad committed Nov 15, 2022
2 parents 2976dd7 + 9afce3b commit eaa5631
Showing 11 changed files with 208 additions and 38 deletions.
2 changes: 1 addition & 1 deletion build/build.py
Original file line number Diff line number Diff line change
@@ -54,7 +54,7 @@
shaka_version = shakaBuildHelpers.calculate_version()

common_closure_opts = [
'--language_out', 'ECMASCRIPT3',
'--language_out', 'ECMASCRIPT5',

'--jscomp_error=*',

1 change: 1 addition & 0 deletions build/conformance.textproto
Original file line number Diff line number Diff line change
@@ -269,6 +269,7 @@ requirement: {
whitelist_regexp: "demo/"
whitelist_regexp: "test/"
whitelist_regexp: "lib/util/delayed_tick.js"
whitelist_regexp: "lib/polyfill/abort_controller.js"
}
requirement: {
type: BANNED_NAME
2 changes: 0 additions & 2 deletions build/shaka-lab.yaml
Original file line number Diff line number Diff line change
@@ -164,8 +164,6 @@ Chromebook:

Tizen:
browser: tizen
# TODO: Re-enable Tizen (https://github.com/shaka-project/generic-webdriver-server/issues/57)
disabled: true

XboxOne:
browser: xboxone
1 change: 1 addition & 0 deletions build/types/polyfill
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Polyfills used to emulate missing browsers features.

+../../node_modules/eme-encryption-scheme-polyfill/index.js
+../../lib/polyfill/abort_controller.js
+../../lib/polyfill/aria.js
+../../lib/polyfill/encryption_scheme.js
+../../lib/polyfill/fullscreen.js
5 changes: 4 additions & 1 deletion lib/hls/hls_parser.js
Original file line number Diff line number Diff line change
@@ -2156,8 +2156,11 @@ shaka.hls.HlsParser = class {
shaka.util.Error.Code.HLS_AES_128_INVALID_KEY_LENGTH);
}

const algorithm = {
name: 'AES-CBC',
};
keyInfo.cryptoKey = await window.crypto.subtle.importKey(
'raw', keyResponse.data, 'AES-CBC', true, ['decrypt']);
'raw', keyResponse.data, algorithm, true, ['decrypt']);
keyInfo.fetchKey = undefined; // No longer needed.
};

11 changes: 7 additions & 4 deletions lib/media/media_source_engine.js
Original file line number Diff line number Diff line change
@@ -586,11 +586,14 @@ shaka.media.MediaSourceEngine = class {
mimeType = this.transmuxers_[contentType].getOrginalMimeType();
}
if (shaka.util.TsParser.probe(uint8ArrayData)) {
const metadata = new shaka.util.TsParser().parse(uint8ArrayData)
.getMetadata();
const tsParser = new shaka.util.TsParser().parse(uint8ArrayData);
// The SourceBuffer timestampOffset may or may not be set yet, so this is
// the timestamp offset that would eventually compute for this segment
// either way.
const timestampOffset =
reference.startTime - (tsParser.getStartTime()[contentType] || 0);
const metadata = tsParser.getMetadata();
if (metadata.length) {
const timestampOffset =
this.sourceBuffers_[contentType].timestampOffset;
this.onMetadata_(metadata, timestampOffset,
reference ? reference.endTime : null);
}
143 changes: 143 additions & 0 deletions lib/polyfill/abort_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*! @license
* Shaka Player
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

goog.provide('shaka.polyfill.AbortController');

goog.require('shaka.polyfill');
goog.require('shaka.util.FakeEvent');
goog.require('shaka.util.FakeEventTarget');

/**
* @summary A polyfill for systems that do not implement AbortController.
* This is used both with the fetch API for HTTP requests and inside the HLS
* parser.
* @export
* @extends AbortController
*/
shaka.polyfill.AbortController = class {
/**
* Install the polyfill if needed.
* @export
*/
static install() {
if (window.AbortController) {
// Not needed.
return;
}

window.AbortController = shaka.polyfill.AbortController;
window.AbortSignal = shaka.polyfill.AbortController.AbortSignal;
}

/** */
constructor() {
/** @private {!shaka.polyfill.AbortController.AbortSignal} */
this.signal_ = new shaka.polyfill.AbortController.AbortSignal();
}

/**
* @override
* @suppress {const|duplicate} Since the original is defined as "const", we
* need this suppression to override it.
*/
get signal() {
return this.signal_;
}

/**
* @param {*=} reason
* @override
*/
abort(reason) {
this.signal_.doAbort_(reason);
}
};

/**
* @summary A polyfill for AbortSignal, part of the AbortController API.
* @implements {AbortSignal}
*/
shaka.polyfill.AbortController.AbortSignal =
class extends shaka.util.FakeEventTarget {
/** */
constructor() {
super();

/** @private {boolean} */
this.aborted_ = false;

/** @private {*} */
this.reason_ = undefined;

/** @type {?function(!Event)} */
this.onabort = null;
}

/** @override */
get aborted() {
return this.aborted_;
}

/** @return {*} */
get reason() {
return this.reason_;
}

/**
* @param {*} reason
* @private
*/
doAbort_(reason) {
if (this.aborted_) {
return;
}

this.aborted_ = true;
this.reason_ = reason;
if (this.reason_ === undefined) {
// This is equivalent to a native implementation.
this.reason_ = new DOMException(
'signal is aborted without reason', 'AbortError');
}

// According to MDN:
// "Event type - A generic Event with no added properties."
const event = new shaka.util.FakeEvent('abort');
if (this.onabort) {
this.onabort(event);
}
this.dispatchEvent(event);
}


/**
* @param {*=} reason
* @return {!AbortSignal}
*/
static abort(reason) {
const signal = new shaka.polyfill.AbortController.AbortSignal();
signal.doAbort_(reason);
return signal;
}

/**
* @param {number} timeMs
* @return {!AbortSignal}
*/
static timeout(timeMs) {
const signal = new shaka.polyfill.AbortController.AbortSignal();

window.setTimeout(() => {
// This is equivalent to a native implementation.
signal.doAbort_(new DOMException('signal timed out', 'TimeoutError'));
}, timeMs);

return signal;
}
};


shaka.polyfill.register(shaka.polyfill.AbortController.install);
61 changes: 33 additions & 28 deletions lib/polyfill/patchedmediakeys_apple.js
Original file line number Diff line number Diff line change
@@ -27,38 +27,39 @@ goog.require('shaka.util.StringUtils');
shaka.polyfill.PatchedMediaKeysApple = class {
/**
* Installs the polyfill if needed.
* @param {boolean} enableUninstall enables uninstalling the polyfill
* @param {boolean=} enableUninstall enables uninstalling the polyfill
* @export
*/
static install(enableUninstall = false) {
// Alias
const PatchedMediaKeysApple = shaka.polyfill.PatchedMediaKeysApple;

if (!window.HTMLVideoElement || !window.WebKitMediaKeys) {
// No HTML5 video or no prefixed EME.
return;
}

if (enableUninstall) {
this.enableUninstall = true;
this.originalHTMLMediaElementPrototypeMediaKeys =
PatchedMediaKeysApple.enableUninstall = true;
PatchedMediaKeysApple.originalHTMLMediaElementPrototypeMediaKeys =
/** @type {!Object} */ (
Object.getOwnPropertyDescriptor(
// eslint-disable-next-line no-restricted-syntax
HTMLMediaElement.prototype, 'mediaKeys',
)
);
// eslint-disable-next-line no-restricted-syntax
this.originalHTMLMediaElementPrototypeSetMediaKeys = HTMLMediaElement
.prototype.setMediaKeys;
this.originalWindowMediaKeys = window.MediaKeys;
this.originalWindowMediaKeySystemAccess = window.MediaKeySystemAccess;
this.originalNavigatorRequestMediaKeySystemAccess = navigator
.requestMediaKeySystemAccess;
PatchedMediaKeysApple.originalHTMLMediaElementPrototypeSetMediaKeys =
// eslint-disable-next-line no-restricted-syntax
HTMLMediaElement.prototype.setMediaKeys;
PatchedMediaKeysApple.originalWindowMediaKeys = window.MediaKeys;
PatchedMediaKeysApple.originalWindowMediaKeySystemAccess =
window.MediaKeySystemAccess;
PatchedMediaKeysApple.originalNavigatorRequestMediaKeySystemAccess =
navigator.requestMediaKeySystemAccess;
}

shaka.log.info('Using Apple-prefixed EME');

// Alias
const PatchedMediaKeysApple = shaka.polyfill.PatchedMediaKeysApple;

// Delete mediaKeys to work around strict mode compatibility issues.
// eslint-disable-next-line no-restricted-syntax
delete HTMLMediaElement.prototype['mediaKeys'];
@@ -83,32 +84,36 @@ shaka.polyfill.PatchedMediaKeysApple = class {
* @export
*/
static uninstall() {
if (!this.enableUninstall) {
// Alias
const PatchedMediaKeysApple = shaka.polyfill.PatchedMediaKeysApple;

if (!PatchedMediaKeysApple.enableUninstall) {
return;
}

shaka.log.info('Un-installing Apple-prefixed EME');

this.enableUninstall = false;
PatchedMediaKeysApple.enableUninstall = false;
Object.defineProperty(
// eslint-disable-next-line no-restricted-syntax
HTMLMediaElement.prototype,
'mediaKeys',
this.originalHTMLMediaElementPrototypeMediaKeys,
PatchedMediaKeysApple.originalHTMLMediaElementPrototypeMediaKeys,
);
// eslint-disable-next-line no-restricted-syntax
HTMLMediaElement.prototype.setMediaKeys = this
.originalHTMLMediaElementPrototypeSetMediaKeys;
window.MediaKeys = this.originalWindowMediaKeys;
window.MediaKeySystemAccess = this.originalWindowMediaKeySystemAccess;
navigator.requestMediaKeySystemAccess = this
.originalNavigatorRequestMediaKeySystemAccess;

this.originalWindowMediaKeys = null;
this.originalWindowMediaKeySystemAccess = null;
this.originalHTMLMediaElementPrototypeSetMediaKeys = null;
this.originalNavigatorRequestMediaKeySystemAccess = null;
this.originalHTMLMediaElementPrototypeMediaKeys = null;
HTMLMediaElement.prototype.setMediaKeys =
PatchedMediaKeysApple.originalHTMLMediaElementPrototypeSetMediaKeys;
window.MediaKeys = PatchedMediaKeysApple.originalWindowMediaKeys;
window.MediaKeySystemAccess =
PatchedMediaKeysApple.originalWindowMediaKeySystemAccess;
navigator.requestMediaKeySystemAccess =
PatchedMediaKeysApple.originalNavigatorRequestMediaKeySystemAccess;

PatchedMediaKeysApple.originalWindowMediaKeys = null;
PatchedMediaKeysApple.originalWindowMediaKeySystemAccess = null;
PatchedMediaKeysApple.originalHTMLMediaElementPrototypeSetMediaKeys = null;
PatchedMediaKeysApple.originalNavigatorRequestMediaKeySystemAccess = null;
PatchedMediaKeysApple.originalHTMLMediaElementPrototypeMediaKeys = null;

window.shakaMediaKeysPolyfill = false;
}
1 change: 1 addition & 0 deletions shaka-player.uncompiled.js
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ goog.require('shaka.offline.OfflineManifestParser');
goog.require('shaka.offline.OfflineScheme');
goog.require('shaka.offline.Storage');
goog.require('shaka.offline.indexeddb.StorageMechanism');
goog.require('shaka.polyfill.AbortController');
goog.require('shaka.polyfill.Aria');
goog.require('shaka.polyfill.EncryptionScheme');
goog.require('shaka.polyfill.Fullscreen');
12 changes: 11 additions & 1 deletion test/media/drm_engine_unit.js
Original file line number Diff line number Diff line change
@@ -120,11 +120,17 @@ describe('DrmEngine', () => {
};

drmEngine = new shaka.media.DrmEngine(playerInterface);

config = shaka.util.PlayerConfiguration.createDefault().drm;
config.servers = {
'drm.abc': 'http://abc.drm/license',
'drm.def': 'http://def.drm/license',
};
// Some platforms, such as Xbox, default to parseInbandPssh: true, which
// ignores encrypted events. So set it explicitly to false, and let
// individual tests set it to true where relevant.
config.parseInbandPsshEnabled = false;

drmEngine.configure(config);
});

@@ -2548,7 +2554,11 @@ describe('DrmEngine', () => {
*/
async function sendEncryptedEvent(
initDataType = 'cenc', initData = new Uint8Array(1), keyId = null) {
mockVideo.on['encrypted']({initDataType, initData, keyId});
// For some platforms, such as Xbox, where parseInbandPssh defaults to
// true, this listener may never be set.
if (mockVideo.on['encrypted']) {
mockVideo.on['encrypted']({initDataType, initData, keyId});
}

await Util.shortDelay();
}
7 changes: 6 additions & 1 deletion test/util/xml_utils_unit.js
Original file line number Diff line number Diff line change
@@ -425,10 +425,15 @@ describe('XmlUtils', () => {
});

it('returns null on XML that embeds SVG', () => {
// Some platforms, such as Xbox One, don't recognize elements as SVG
// based on namespace alone. So the SVG element below needs to be a real
// SVG element.
const xmlString = [
'<?xml version="1.0"?>',
'<Root>',
' <Child xmlns="http://www.w3.org/2000/svg"></Child>',
' <svg viewBox="0 0 100 100">',
' <rect x="0" y="0" width="100" height"100" />',
' </svg>',
'</Root>',
].join('\n');
const doc = XmlUtils.parseXmlString(xmlString, 'Root');

0 comments on commit eaa5631

Please sign in to comment.