diff --git a/lib/media/eme_manager.js b/lib/media/eme_manager.js index d6e2a17a3..3d0d46257 100644 --- a/lib/media/eme_manager.js +++ b/lib/media/eme_manager.js @@ -76,8 +76,8 @@ shaka.media.EmeManager = function(player, video, videoSource) { /** @private {!shaka.util.EventManager} */ this.eventManager_ = new shaka.util.EventManager(); - /** @private {Object.} */ - this.requestGenerated_ = {}; + /** @private {!Array.} */ + this.requestGenerated_ = []; /** @private {!Array.} */ this.sessions_ = []; @@ -535,10 +535,13 @@ shaka.media.EmeManager.prototype.onEncrypted_ = function(event) { shaka.log.info('onEncrypted_', initData, event); // Suppress duplicate init data. - var initDataKey = shaka.util.Uint8ArrayUtils.key(initData); - if (this.requestGenerated_[initDataKey]) { - shaka.log.debug('License request already generated!'); - return; + // Note that some init data are extremely large and can't portably be used as + // keys in a dictionary. + for (var i = 0; i < this.requestGenerated_.length; ++i) { + if (shaka.util.Uint8ArrayUtils.equal(initData, this.requestGenerated_[i])) { + shaka.log.debug('License request already generated!'); + return; + } } try { @@ -552,16 +555,22 @@ shaka.media.EmeManager.prototype.onEncrypted_ = function(event) { var p = session.generateRequest(event.initDataType, /** @type {!BufferSource} */(event.initData)); - this.requestGenerated_[initDataKey] = true; + this.requestGenerated_.push(initData); p.catch(shaka.util.TypedBind(this, /** @param {*} error */ function(error) { - if (!this.requestGenerated_) { + if (!this.video_) { // The EmeManager has already been destroyed. return; } - this.requestGenerated_[initDataKey] = false; + for (var i = 0; i < this.requestGenerated_.length; ++i) { + if (shaka.util.Uint8ArrayUtils.equal(initData, + this.requestGenerated_[i])) { + this.requestGenerated_.splice(i, 1); + break; + } + } var event = shaka.util.FakeEvent.createErrorEvent(error); this.dispatchEvent(event); this.allSessionsPresumedReady_.reject(error); diff --git a/lib/player/drm_info.js b/lib/player/drm_info.js index 5437cb4e3..9994ec98e 100644 --- a/lib/player/drm_info.js +++ b/lib/player/drm_info.js @@ -491,18 +491,21 @@ shaka.player.DrmInfo.prototype.addInitDatas = function( }; })); - /** - * @param {!shaka.player.DrmInfo.InitData} initData - * @return {string} - */ - var initDataKey = function(initData) { - // FIXME: initData.initData may be very large; on some browsers using such - // a large string as a key into an object may cause problems. - return shaka.util.Uint8ArrayUtils.key(initData.initData) + ',' + - initData.initDataType; - }; - this.initDatas = shaka.util.ArrayUtils.removeDuplicates( - unfilteredInitDatas, initDataKey); + unfilteredInitDatas, shaka.player.DrmInfo.compareInitDatas_); +}; + + +/** + * @param {!shaka.player.DrmInfo.InitData} initDataA + * @param {!shaka.player.DrmInfo.InitData} initDataB + * @return {boolean} + * @private + */ +shaka.player.DrmInfo.compareInitDatas_ = + function(initDataA, initDataB) { + return initDataA.initDataType == initDataB.initDataType && + shaka.util.Uint8ArrayUtils.equal(initDataA.initData, + initDataB.initData); }; diff --git a/lib/util/array_utils.js b/lib/util/array_utils.js index ac9c8999a..5ebdd681f 100644 --- a/lib/util/array_utils.js +++ b/lib/util/array_utils.js @@ -25,24 +25,25 @@ goog.provide('shaka.util.ArrayUtils'); /** - * Remove duplicate entries from an array. + * Remove duplicate entries from an array. Order N^2, so use with caution. * @param {!Array.} array - * @param {function(T): (string|number)=} opt_keyFn An optional function which - * takes an array item and converts it into a key. Use this if your array - * items cannot be used as an index into an Object. - * @return {!Array.} A sorted list of the keys. + * @param {function(T, T): boolean=} opt_compareFn An optional function which + * will be used to compare items in the array. + * @return {!Array.} * @template T */ -shaka.util.ArrayUtils.removeDuplicates = function(array, opt_keyFn) { - var set = {}; - for (var i = 0; i < array.length; ++i) { - var key = opt_keyFn ? opt_keyFn(array[i]) : array[i].toString(); - set[key] = array[i]; - } - +shaka.util.ArrayUtils.removeDuplicates = function(array, opt_compareFn) { var result = []; - for (var k in set) { - result.push(set[k]); + for (var i = 0; i < array.length; ++i) { + var matchFound = false; + for (var j = 0; j < result.length; ++j) { + matchFound = opt_compareFn ? opt_compareFn(array[i], result[j]) : + array[i] === result[j]; + if (matchFound) break; + } + if (!matchFound) { + result.push(array[i]); + } } return result; }; diff --git a/lib/util/uint8array_utils.js b/lib/util/uint8array_utils.js index 2b9e63053..c4917357a 100644 --- a/lib/util/uint8array_utils.js +++ b/lib/util/uint8array_utils.js @@ -129,13 +129,3 @@ shaka.util.Uint8ArrayUtils.equal = function(arr1, arr2) { return true; }; - -/** - * Convert a Uint8Array to a string which can be used as a key in a dictionary. - * @param {!Uint8Array} arr - * @return {string} - */ -shaka.util.Uint8ArrayUtils.key = function(arr) { - return Array.prototype.join.apply(arr); -}; -