From aa79c72fdab050d98c682fee2b0b1d2bcdeb47d6 Mon Sep 17 00:00:00 2001 From: Joey Parrish Date: Tue, 14 May 2024 07:30:37 -0700 Subject: [PATCH] fix: Populate requested scheme into output, not default scheme (#69) Now that the polyfill will respond with more than one scheme on Firefox and Chromecast devices, we must populate the _requested_ scheme into the output, not the _default_ scheme. Back when the polyfill assumed that only the default was possible, these were the same, so this distinction didn't matter. --- index.js | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/index.js b/index.js index f2c4d6b..020e75c 100644 --- a/index.js +++ b/index.js @@ -178,10 +178,15 @@ class EmeEncryptionSchemePolyfill { const mediaKeySystemAccess = await EmeEncryptionSchemePolyfill.originalRMKSA_.call( this, keySystem, filteredSupportedConfigurations); + // Wrap the MKSA object in ours to provide the missing field in the // returned configuration. + const videoScheme = filteredSupportedConfigurations[0] + .videoCapabilities[0].encryptionScheme; + const audioScheme = filteredSupportedConfigurations[0] + .audioCapabilities[0].encryptionScheme; return new EmeEncryptionSchemePolyfillMediaKeySystemAccess( - mediaKeySystemAccess, supportedScheme); + mediaKeySystemAccess, videoScheme, audioScheme); } /** @@ -345,19 +350,20 @@ class McEncryptionSchemePolyfill { console.assert(this == navigator.mediaCapabilities, 'bad "this" for decodingInfo'); - let supportedScheme = null; + let videoScheme = null; + let audioScheme = null; if (requestedConfiguration.keySystemConfiguration) { const keySystemConfig = requestedConfiguration.keySystemConfiguration; const keySystem = keySystemConfig.keySystem; - const audioScheme = keySystemConfig.audio && + audioScheme = keySystemConfig.audio && keySystemConfig.audio.encryptionScheme; - const videoScheme = keySystemConfig.video && + videoScheme = keySystemConfig.video && keySystemConfig.video.encryptionScheme; - supportedScheme = guessSupportedScheme(keySystem); + const supportedScheme = guessSupportedScheme(keySystem); const notSupportedResult = { powerEfficient: false, @@ -387,7 +393,7 @@ class McEncryptionSchemePolyfill { // the missing field in the returned configuration. capabilities.keySystemAccess = new EmeEncryptionSchemePolyfillMediaKeySystemAccess( - capabilities.keySystemAccess, supportedScheme); + capabilities.keySystemAccess, videoScheme, audioScheme); } else if (requestedConfiguration.keySystemConfiguration) { // If the result is supported and the content is encrypted, we should have // a MediaKeySystemAccess instance as part of the result. If we land @@ -439,6 +445,7 @@ class McEncryptionSchemePolyfill { const capability = { robustness: mediaCapKeySystemConfig.audio.robustness || '', contentType: decodingConfig.audio.contentType, + encryptionScheme: mediaCapKeySystemConfig.audio.encryptionScheme, }; audioCapabilities.push(capability); } @@ -447,6 +454,7 @@ class McEncryptionSchemePolyfill { const capability = { robustness: mediaCapKeySystemConfig.video.robustness || '', contentType: decodingConfig.video.contentType, + encryptionScheme: mediaCapKeySystemConfig.video.encryptionScheme, }; videoCapabilities.push(capability); } @@ -487,9 +495,12 @@ class EmeEncryptionSchemePolyfillMediaKeySystemAccess { /** * @param {!MediaKeySystemAccess} mksa A native MediaKeySystemAccess instance * to wrap. - * @param {?string} scheme The encryption scheme to add to the configuration. + * @param {?string|undefined} videoScheme The encryption scheme to add to the + * configuration for video. + * @param {?string|undefined} audioScheme The encryption scheme to add to the + * configuration for audio. */ - constructor(mksa, scheme) { + constructor(mksa, videoScheme, audioScheme) { /** * @const {!MediaKeySystemAccess} * @private @@ -500,7 +511,13 @@ class EmeEncryptionSchemePolyfillMediaKeySystemAccess { * @const {?string} * @private */ - this.scheme_ = scheme; + this.videoScheme_ = videoScheme || null; + + /** + * @const {?string} + * @private + */ + this.audioScheme_ = audioScheme || null; /** @const {string} */ this.keySystem = mksa.keySystem; @@ -518,13 +535,13 @@ class EmeEncryptionSchemePolyfillMediaKeySystemAccess { if (configuration.videoCapabilities) { for (const capability of configuration.videoCapabilities) { - capability['encryptionScheme'] = this.scheme_; + capability['encryptionScheme'] = this.videoScheme_; } } if (configuration.audioCapabilities) { for (const capability of configuration.audioCapabilities) { - capability['encryptionScheme'] = this.scheme_; + capability['encryptionScheme'] = this.audioScheme_; } } @@ -599,7 +616,7 @@ function hasEncryptionScheme(mediaKeySystemAccess) { } /** - * @param {(string|undefined)} scheme Encryption scheme to check + * @param {(string|undefined|null)} scheme Encryption scheme to check * @param {?string} supportedScheme A guess at the encryption scheme this * supports. * @return {boolean} True if the scheme is compatible.