Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Jason Palmer <jason@jason-palmer.com>
Jesper Haug Karsrud <jesper.karsrud@gmail.com>
Johan Sundström <oyasumi@gmail.com>
Jonas Birmé <jonas.birme@eyevinn.se>
Jozef Chúťka <jozefchutka@gmail.com>
JW Player <*@jwplayer.com>
Lucas Gabriel Sánchez <unkiwii@gmail.com>
Mattias Wadman <mattias.wadman@gmail.com>
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Joey Parrish <joeyparrish@google.com>
Johan Sundström <oyasumi@gmail.com>
Jonas Birmé <jonas.birme@eyevinn.se>
Jono Ward <jonoward@gmail.com>
Jozef Chúťka <jozefchutka@gmail.com>
Lucas Gabriel Sánchez <unkiwii@gmail.com>
Mattias Wadman <mattias.wadman@gmail.com>
Natalie Harris <natalieharris@google.com>
Expand Down
9 changes: 8 additions & 1 deletion lib/polyfill/mediakeys.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@ shaka.polyfill.MediaKeys.install = function() {
shaka.log.info('Using native EME as-is.');
} else if (HTMLMediaElement.prototype.webkitGenerateKeyRequest) {
shaka.log.info('Using webkit-prefixed EME v0.1b');
shaka.polyfill.PatchedMediaKeysWebkit.install();
shaka.polyfill.PatchedMediaKeysWebkit.install('webkit');
} else if (HTMLMediaElement.prototype['generateKeyRequest']) {
// There is a compiler error that would convert
// "HTMLMediaElement.prototype.generateKeyRequest" into
// "HTMLMediaElement.prototype.a". Until resolved, array access
// seems to work ok.
shaka.log.info('Using nonprefixed EME v0.1b');
shaka.polyfill.PatchedMediaKeysWebkit.install('');
} else if (window.MSMediaKeys) {
shaka.log.info('Using ms-prefixed EME v20140218');
shaka.polyfill.PatchedMediaKeysMs.install();
Expand Down
71 changes: 55 additions & 16 deletions lib/polyfill/patchedmediakeys_webkit.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,32 @@ goog.require('shaka.util.StringUtils');
goog.require('shaka.util.Uint8ArrayUtils');


/**
* Store api prefix.
*
* @private {string}
*/
shaka.polyfill.PatchedMediaKeysWebkit.prefix_ = '';


/**
* Install a polyfill to implement {@link http://goo.gl/blgtZZ EME draft
* 12 March 2015} on top of webkit-prefixed
* {@link http://goo.gl/FSpoAo EME v0.1b}.
*
* @param {string} prefix
*/
shaka.polyfill.PatchedMediaKeysWebkit.install = function() {
shaka.polyfill.PatchedMediaKeysWebkit.install = function(prefix) {
shaka.log.debug('PatchedMediaKeysWebkit.install');

goog.asserts.assert(HTMLMediaElement.prototype.webkitGenerateKeyRequest,
'PatchedMediaKeysWebkit APIs not available!');

// Alias.
var PatchedMediaKeysWebkit = shaka.polyfill.PatchedMediaKeysWebkit;
PatchedMediaKeysWebkit.prefix_ = prefix;
var prefixApi = PatchedMediaKeysWebkit.prefixApi_;

goog.asserts.assert(
HTMLMediaElement.prototype[prefixApi('generateKeyRequest')],
'PatchedMediaKeysWebkit APIs not available!');

// Construct fake key ID. This is not done at load-time to avoid exceptions
// on unsupported browsers. This particular fake key ID was suggested in
Expand All @@ -60,6 +73,22 @@ shaka.polyfill.PatchedMediaKeysWebkit.install = function() {
};


/**
* Prefix api by stored prefix.
*
* @param {string} api
* @return {string}
* @private
*/
shaka.polyfill.PatchedMediaKeysWebkit.prefixApi_ = function(api) {
var prefix = shaka.polyfill.PatchedMediaKeysWebkit.prefix_;
if (prefix) {
return prefix + api.charAt(0).toUpperCase() + api.slice(1);
}
return api;
};


/**
* An implementation of navigator.requestMediaKeySystemAccess.
* Retrieve a MediaKeySystemAccess object.
Expand Down Expand Up @@ -340,21 +369,22 @@ shaka.polyfill.PatchedMediaKeysWebkit.MediaKeys.prototype.setMedia =
// Remove any old listeners.
this.eventManager_.removeAll();

var prefix = shaka.polyfill.PatchedMediaKeysWebkit.prefix_;
if (media) {
// Intercept and translate these prefixed EME events.
this.eventManager_.listen(media, 'webkitneedkey',
this.eventManager_.listen(media, prefix + 'needkey',
/** @type {shaka.util.EventManager.ListenerType} */ (
this.onWebkitNeedKey_.bind(this)));

this.eventManager_.listen(media, 'webkitkeymessage',
this.eventManager_.listen(media, prefix + 'keymessage',
/** @type {shaka.util.EventManager.ListenerType} */ (
this.onWebkitKeyMessage_.bind(this)));

this.eventManager_.listen(media, 'webkitkeyadded',
this.eventManager_.listen(media, prefix + 'keyadded',
/** @type {shaka.util.EventManager.ListenerType} */ (
this.onWebkitKeyAdded_.bind(this)));

this.eventManager_.listen(media, 'webkitkeyerror',
this.eventManager_.listen(media, prefix + 'keyerror',
/** @type {shaka.util.EventManager.ListenerType} */ (
this.onWebkitKeyError_.bind(this)));
}
Expand Down Expand Up @@ -412,10 +442,12 @@ shaka.polyfill.PatchedMediaKeysWebkit.MediaKeys.prototype.onWebkitNeedKey_ =
shaka.log.debug('PatchedMediaKeysWebkit.onWebkitNeedKey_', event);
goog.asserts.assert(this.media_, 'media_ not set in onWebkitNeedKey_');

var event2 = new shaka.util.FakeEvent('encrypted', {
initDataType: 'webm', // not used by v0.1b EME, but given a valid value
initData: event.initData
});
var event2 = document.createEvent('CustomEvent');
event2.initCustomEvent('encrypted', false, false, null);

// not used by v0.1b EME, but given a valid value
event2.initDataType = 'webm';
event2.initData = event.initData;

this.media_.dispatchEvent(event2);
};
Expand Down Expand Up @@ -702,8 +734,11 @@ shaka.polyfill.PatchedMediaKeysWebkit.MediaKeySession.prototype.generate_ =
// GKR can throw an exception. If this occurs, wait 10 ms and try again at
// most once. This situation should only occur when init data is available
// ahead of the 'needkey' event.

var prefixApi = shaka.polyfill.PatchedMediaKeysWebkit.prefixApi_;
var generateKeyRequestName = prefixApi('generateKeyRequest');
try {
this.media_.webkitGenerateKeyRequest(this.keySystem_, mangledInitData);
this.media_[generateKeyRequestName](this.keySystem_, mangledInitData);
} catch (exception) {
if (exception.name != 'InvalidStateError') {
this.generatePromise_ = null;
Expand All @@ -712,7 +747,7 @@ shaka.polyfill.PatchedMediaKeysWebkit.MediaKeySession.prototype.generate_ =

setTimeout(function() {
try {
this.media_.webkitGenerateKeyRequest(this.keySystem_, mangledInitData);
this.media_[generateKeyRequestName](this.keySystem_, mangledInitData);
} catch (exception) {
this.generatePromise_.reject(exception);
this.generatePromise_ = null;
Expand Down Expand Up @@ -775,8 +810,10 @@ shaka.polyfill.PatchedMediaKeysWebkit.MediaKeySession.prototype.update_ =
keyId = null;
}

var prefixApi = shaka.polyfill.PatchedMediaKeysWebkit.prefixApi_;
var addKeyName = prefixApi('addKey');
try {
this.media_.webkitAddKey(this.keySystem_, key, keyId, this.sessionId);
this.media_[addKeyName](this.keySystem_, key, keyId, this.sessionId);
} catch (exception) {
// Reject the promise.
this.updatePromise_.reject(exception);
Expand Down Expand Up @@ -852,8 +889,10 @@ shaka.polyfill.PatchedMediaKeysWebkit.MediaKeySession.prototype.close =
// it to clean up resources in v0.1b. We still consider the session closed.
// We can't let the exception propagate because MediaKeySession.close()
// should not throw.
var prefixApi = shaka.polyfill.PatchedMediaKeysWebkit.prefixApi_;
var cancelKeyRequestName = prefixApi('cancelKeyRequest');
try {
this.media_.webkitCancelKeyRequest(this.keySystem_, this.sessionId);
this.media_[cancelKeyRequestName](this.keySystem_, this.sessionId);
} catch (exception) {}
}

Expand Down
3 changes: 2 additions & 1 deletion lib/util/fake_event.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ shaka.util.FakeEvent = function(type, opt_dict) {
* @const {number}
* @see https://developer.mozilla.org/en-US/docs/Web/API/Event/timeStamp
*/
this.timeStamp = window.performance ? window.performance.now() : Date.now();
this.timeStamp = window.performance && window.performance.now ?
window.performance.now() : Date.now();

/** @const {string} */
this.type = type;
Expand Down