eme-encryption-scheme-polyfill
Advanced tools
Comparing version 1.0.3 to 2.0.0
@@ -0,1 +1,8 @@ | ||
## 2.0.0 (2019-12-12) | ||
Features: | ||
- Added support for polyfilling MediaCapabilities, too | ||
- https://github.com/w3c/media-capabilities/issues/100 | ||
## 1.0.3 (2019-12-05) | ||
@@ -2,0 +9,0 @@ |
@@ -8,2 +8,2 @@ /*! | ||
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).EmeEncryptionSchemePolyfill=e()}}(function(){var e={exports:{}};function i(e,i,t){return t?i?i(e):e:(e&&e.then||(e=Promise.resolve(e)),i?e.then(i):e)}var t=function(){function e(){}return e.install=function(){e.originalRMKSA_||navigator.requestMediaKeySystemAccess&&MediaKeySystemAccess.prototype.getConfiguration&&(e.originalRMKSA_=navigator.requestMediaKeySystemAccess,navigator.requestMediaKeySystemAccess=e.probeRMKSA_)},e.guessSupportedScheme_=function(e){return e.startsWith("com.widevine")?"cenc":e.startsWith("com.microsoft")?"cenc":e.startsWith("com.adobe")?"cenc":e.startsWith("org.w3")?"cenc":e.startsWith("com.apple")?"cbcs-1-9":(console.warn("EmeEncryptionSchemePolyfill: Unknown key system:",e,"Please contribute!"),null)},e.probeRMKSA_=function(t,r){try{var n=this;return i(e.originalRMKSA_.call(n,t,r),function(i){var a=i.getConfiguration(),o=a.videoCapabilities&&a.videoCapabilities[0],s=a.audioCapabilities&&a.audioCapabilities[0];return void 0!==(o||s).encryptionScheme?(navigator.requestMediaKeySystemAccess=e.originalRMKSA_,i):(navigator.requestMediaKeySystemAccess=e.polyfillRMKSA_,e.polyfillRMKSA_.call(n,t,r))})}catch(a){return Promise.reject(a)}},e.polyfillRMKSA_=function(t,n){try{var a=e.guessSupportedScheme_(t),o=[],s=n,l=Array.isArray(s),c=0;for(s=l?s:s[Symbol.iterator]();;){var u;if(l){if(c>=s.length)break;u=s[c++]}else{if((c=s.next()).done)break;u=c.value}var f=u,p=e.filterCapabilities_(f.videoCapabilities,a),y=e.filterCapabilities_(f.audioCapabilities,a);if(f.videoCapabilities&&f.videoCapabilities.length&&!p.length);else if(f.audioCapabilities&&f.audioCapabilities.length&&!y.length);else{var d=Object.assign({},f);d.videoCapabilities=p,d.audioCapabilities=y,o.push(d)}}if(!o.length){var m=new Error("Unsupported keySystem or supportedConfigurations.");throw m.name="NotSupportedError",m.code=DOMException.NOT_SUPPORTED_ERR,m}return i(e.originalRMKSA_.call(this,t,o),function(e){return new r(e,a)})}catch(h){return Promise.reject(h)}},e.filterCapabilities_=function(e,i){return e?e.filter(function(e){return!e.encryptionScheme||e.encryptionScheme==i}):e},e}(),r=function(){function e(e,i){this.mksa_=e,this.scheme_=i,this.keySystem=e.keySystem}var i=e.prototype;return i.getConfiguration=function(){var e=this.mksa_.getConfiguration();if(e.videoCapabilities){var i=e.videoCapabilities,t=Array.isArray(i),r=0;for(i=t?i:i[Symbol.iterator]();;){var n;if(t){if(r>=i.length)break;n=i[r++]}else{if((r=i.next()).done)break;n=r.value}n.encryptionScheme=this.scheme_}}if(e.audioCapabilities){var a=e.audioCapabilities,o=Array.isArray(a),s=0;for(a=o?a:a[Symbol.iterator]();;){var l;if(o){if(s>=a.length)break;l=a[s++]}else{if((s=a.next()).done)break;l=s.value}l.encryptionScheme=this.scheme_}}return e},i.createMediaKeys=function(){return this.mksa_.createMediaKeys()},e}();return t.originalRMKSA_,e.exports&&(e.exports=t),e=e.exports}); | ||
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).EncryptionSchemePolyfills=e()}}(function(){var e={exports:{}};function i(e,i,t){return t?i?i(e):e:(e&&e.then||(e=Promise.resolve(e)),i?e.then(i):e)}var t=function(){function e(){}return e.install=function(){e.originalRMKSA_||navigator.requestMediaKeySystemAccess&&MediaKeySystemAccess.prototype.getConfiguration&&(e.originalRMKSA_=navigator.requestMediaKeySystemAccess,navigator.requestMediaKeySystemAccess=e.probeRMKSA_)},e.probeRMKSA_=function(t,n){try{var o=this;return i(e.originalRMKSA_.call(o,t,n),function(i){return a(i)?(navigator.requestMediaKeySystemAccess=e.originalRMKSA_,i):(navigator.requestMediaKeySystemAccess=e.polyfillRMKSA_,e.polyfillRMKSA_.call(o,t,n))})}catch(r){return Promise.reject(r)}},e.polyfillRMKSA_=function(t,n){try{var a=r(t),s=[],c=n,l=Array.isArray(c),f=0;for(c=l?c:c[Symbol.iterator]();;){var u;if(l){if(f>=c.length)break;u=c[f++]}else{if((f=c.next()).done)break;u=f.value}var d=u,y=e.filterCapabilities_(d.videoCapabilities,a),p=e.filterCapabilities_(d.audioCapabilities,a);if(d.videoCapabilities&&d.videoCapabilities.length&&!y.length);else if(d.audioCapabilities&&d.audioCapabilities.length&&!p.length);else{var g=Object.assign({},d);g.videoCapabilities=y,g.audioCapabilities=p,s.push(g)}}if(!s.length){var m=new Error("Unsupported keySystem or supportedConfigurations.");throw m.name="NotSupportedError",m.code=DOMException.NOT_SUPPORTED_ERR,m}return i(e.originalRMKSA_.call(this,t,s),function(e){return new o(e,a)})}catch(h){return Promise.reject(h)}},e.filterCapabilities_=function(e,i){return e?e.filter(function(e){return!e.encryptionScheme||e.encryptionScheme==i}):e},e}(),n=function(){function e(){}return e.install=function(){navigator.mediaCapabilities&&(e.originalDecodingInfo_=navigator.mediaCapabilities.decodingInfo,navigator.mediaCapabilities.decodingInfo=e.probeDecodingInfo_)},e.probeDecodingInfo_=function(t){try{var n=this;return i(e.originalDecodingInfo_.call(n,t),function(i){return t.keySystemConfiguration?a(i.keySystemAccess)?(navigator.mediaCapabilities.decodingInfo=e.originalDecodingInfo_,i):(navigator.mediaCapabilities.decodingInfo=e.polyfillDecodingInfo_,e.polyfillDecodingInfo_.call(n,t)):i})}catch(o){return Promise.reject(o)}},e.polyfillDecodingInfo_=function(t){try{var n=null;if(t.keySystemConfiguration){var a=t.keySystemConfiguration,s=a.keySystem,c=a.audio&&a.audio.encryptionScheme,l=a.video&&a.video.encryptionScheme;n=r(s);var f={powerEfficient:!1,smooth:!1,supported:!1,keySystemAccess:null,configuration:t};if(c&&c!=n)return f;if(l&&l!=n)return f}return i(e.originalDecodingInfo_.call(this,t),function(e){return e.keySystemAccess&&(e.keySystemAccess=new o(e.keySystemAccess,n)),e})}catch(u){return Promise.reject(u)}},e}(),o=function(){function e(e,i){this.mksa_=e,this.scheme_=i,this.keySystem=e.keySystem}var i=e.prototype;return i.getConfiguration=function(){var e=this.mksa_.getConfiguration();if(e.videoCapabilities){var i=e.videoCapabilities,t=Array.isArray(i),n=0;for(i=t?i:i[Symbol.iterator]();;){var o;if(t){if(n>=i.length)break;o=i[n++]}else{if((n=i.next()).done)break;o=n.value}o.encryptionScheme=this.scheme_}}if(e.audioCapabilities){var r=e.audioCapabilities,a=Array.isArray(r),s=0;for(r=a?r:r[Symbol.iterator]();;){var c;if(a){if(s>=r.length)break;c=r[s++]}else{if((s=r.next()).done)break;c=s.value}c.encryptionScheme=this.scheme_}}return e},i.createMediaKeys=function(){return this.mksa_.createMediaKeys()},e}();function r(e){return e.startsWith("com.widevine")?"cenc":e.startsWith("com.microsoft")?"cenc":e.startsWith("com.adobe")?"cenc":e.startsWith("org.w3")?"cenc":e.startsWith("com.apple")?"cbcs-1-9":(console.warn("EmeEncryptionSchemePolyfill: Unknown key system:",e,"Please contribute!"),null)}function a(e){var i=e.getConfiguration(),t=i.videoCapabilities&&i.videoCapabilities[0],n=i.audioCapabilities&&i.audioCapabilities[0];return void 0!==(t||n).encryptionScheme}t.originalRMKSA_,n.originalDecodingInfo_;var s=function(){function e(){}return e.install=function(){t.install(),n.install()},e}();return e.exports&&(e.exports=s),e=e.exports}); |
306
index.js
@@ -59,34 +59,2 @@ /*! | ||
/** | ||
* Guess the supported encryption scheme for the key system. | ||
* | ||
* @param {string} keySystem The key system ID. | ||
* @return {?string} A guess at the encryption scheme this key system | ||
* supports. | ||
* @private | ||
*/ | ||
static guessSupportedScheme_(keySystem) { | ||
if (keySystem.startsWith('com.widevine')) { | ||
return 'cenc'; | ||
} else if (keySystem.startsWith('com.microsoft')) { | ||
return 'cenc'; | ||
} else if (keySystem.startsWith('com.adobe')) { | ||
return 'cenc'; | ||
} else if (keySystem.startsWith('org.w3')) { | ||
return 'cenc'; | ||
} else if (keySystem.startsWith('com.apple')) { | ||
return 'cbcs-1-9'; | ||
} | ||
// We don't have this key system in our map! | ||
// Log a warning. The only way the request will succeed now is if the | ||
// app doesn't specify an encryption scheme in their own configs. | ||
// Use bracket notation to keep this from being stripped from the build. | ||
console['warn']('EmeEncryptionSchemePolyfill: Unknown key system:', | ||
keySystem, 'Please contribute!'); | ||
return null; | ||
} | ||
/** | ||
* A shim for navigator.requestMediaKeySystemAccess to check for | ||
@@ -114,16 +82,3 @@ * encryptionScheme support. Only used until we know if the browser has | ||
const configuration = mediaKeySystemAccess.getConfiguration(); | ||
// It doesn't matter which capability we look at. For this check, they | ||
// should all produce the same result. | ||
const firstVideoCapability = | ||
configuration.videoCapabilities && configuration.videoCapabilities[0]; | ||
const firstAudioCapability = | ||
configuration.audioCapabilities && configuration.audioCapabilities[0]; | ||
const firstCapability = firstVideoCapability || firstAudioCapability; | ||
// If supported by the browser, the encryptionScheme field must appear in | ||
// the returned configuration, regardless of whether or not it was | ||
// specified in the supportedConfigurations given by the application. | ||
if (firstCapability['encryptionScheme'] !== undefined) { | ||
if (hasEncryptionScheme(mediaKeySystemAccess)) { | ||
// The browser supports the encryptionScheme field! | ||
@@ -175,4 +130,3 @@ // No need for a patch. Revert back to the original implementation. | ||
const supportedScheme = EmeEncryptionSchemePolyfill.guessSupportedScheme_( | ||
keySystem); | ||
const supportedScheme = guessSupportedScheme(keySystem); | ||
@@ -263,2 +217,171 @@ // Filter the application's configurations based on our guess of what | ||
/** | ||
* A polyfill to add support for EncryptionScheme queries in MediaCapabilities. | ||
* | ||
* Because this polyfill can't know what schemes the UA or CDM actually support, | ||
* it assumes support for the historically-supported schemes of each well-known | ||
* key system. | ||
* | ||
* In source form, this is compatible with the Closure Compiler, CommonJS, and | ||
* AMD module formats. It can also be directly included via a script tag. | ||
* | ||
* The minified bundle is a standalone module compatible with the CommonJS and | ||
* AMD module formats, and can also be directly included via a script tag. | ||
* | ||
* @see https://wicg.github.io/encrypted-media-encryption-scheme/ | ||
* @see https://github.com/w3c/encrypted-media/pull/457 | ||
* @export | ||
*/ | ||
class McEncryptionSchemePolyfill { | ||
/** | ||
* Installs the polyfill. To avoid the possibility of extra user prompts, | ||
* this will shim MC so long as it exists, without checking support for | ||
* encryptionScheme upfront. The support check will happen on-demand the | ||
* first time MC is used. | ||
* | ||
* @export | ||
*/ | ||
static install() { | ||
if (!navigator.mediaCapabilities) { | ||
console.debug('McEncryptionSchemePolyfill: MediaCapabilities not found'); | ||
// No MediaCapabilities. | ||
return; | ||
} | ||
// Save the original. | ||
McEncryptionSchemePolyfill.originalDecodingInfo_ = | ||
navigator.mediaCapabilities.decodingInfo; | ||
// Patch in a method which will check for support on the first call. | ||
console.debug('McEncryptionSchemePolyfill: ' + | ||
'Waiting to detect encryptionScheme support.'); | ||
navigator.mediaCapabilities.decodingInfo = | ||
McEncryptionSchemePolyfill.probeDecodingInfo_; | ||
} | ||
/** | ||
* A shim for mediaCapabilities.decodingInfo to check for encryptionScheme | ||
* support. Only used until we know if the browser has native support for the | ||
* encryptionScheme field. | ||
* | ||
* @this {MediaCapabilities} | ||
* @param {!MediaDecodingConfiguration} requestedConfiguration The requested | ||
* decoding configuration. | ||
* @return {!Promise.<!MediaCapabilitiesDecodingInfo>} A Promise to a result | ||
* describing the capabilities of the browser in the request configuration. | ||
* @private | ||
*/ | ||
static async probeDecodingInfo_(requestedConfiguration) { | ||
console.assert(this == navigator.mediaCapabilities, | ||
'bad "this" for decodingInfo'); | ||
// Call the original version. If the call succeeds, we look at the result | ||
// to decide if the encryptionScheme field is supported or not. | ||
const capabilities = | ||
await McEncryptionSchemePolyfill.originalDecodingInfo_.call( | ||
this, requestedConfiguration); | ||
if (!requestedConfiguration.keySystemConfiguration) { | ||
// This was not a query regarding encrypted content. The results are | ||
// valid, but won't tell us anything about native support for | ||
// encryptionScheme. Just return the results. | ||
return capabilities; | ||
} | ||
const mediaKeySystemAccess = capabilities.keySystemAccess; | ||
if (hasEncryptionScheme(mediaKeySystemAccess)) { | ||
// The browser supports the encryptionScheme field! | ||
// No need for a patch. Revert back to the original implementation. | ||
console.debug('McEncryptionSchemePolyfill: ' + | ||
'Native encryptionScheme support found.'); | ||
// eslint-disable-next-line require-atomic-updates | ||
navigator.mediaCapabilities.decodingInfo = | ||
McEncryptionSchemePolyfill.originalDecodingInfo_; | ||
// Return the results, which are completely valid. | ||
return capabilities; | ||
} | ||
// If we land here, the browser does _not_ support the encryptionScheme | ||
// field. So we install another patch to check the encryptionScheme field | ||
// in future calls. | ||
console.debug('McEncryptionSchemePolyfill: ' + | ||
'No native encryptionScheme support found. '+ | ||
'Patching encryptionScheme support.'); | ||
// eslint-disable-next-line require-atomic-updates | ||
navigator.mediaCapabilities.decodingInfo = | ||
McEncryptionSchemePolyfill.polyfillDecodingInfo_; | ||
// The results we have may not be valid. Run the query again through our | ||
// polyfill. | ||
return McEncryptionSchemePolyfill.polyfillDecodingInfo_.call( | ||
this, requestedConfiguration); | ||
} | ||
/** | ||
* A polyfill for mediaCapabilities.decodingInfo to handle the | ||
* encryptionScheme field in browsers that don't support it. It uses the | ||
* user-agent string to guess what encryption schemes are supported, then | ||
* those guesses are used to reject unsupported schemes. | ||
* | ||
* @this {MediaCapabilities} | ||
* @param {!MediaDecodingConfiguration} requestedConfiguration The requested | ||
* decoding configuration. | ||
* @return {!Promise.<!MediaCapabilitiesDecodingInfo>} A Promise to a result | ||
* describing the capabilities of the browser in the request configuration. | ||
* @private | ||
*/ | ||
static async polyfillDecodingInfo_(requestedConfiguration) { | ||
console.assert(this == navigator.mediaCapabilities, | ||
'bad "this" for decodingInfo'); | ||
let supportedScheme = null; | ||
if (requestedConfiguration.keySystemConfiguration) { | ||
const keySystemConfig = requestedConfiguration.keySystemConfiguration; | ||
const keySystem = keySystemConfig.keySystem; | ||
const audioScheme = keySystemConfig.audio && | ||
keySystemConfig.audio.encryptionScheme; | ||
const videoScheme = keySystemConfig.video && | ||
keySystemConfig.video.encryptionScheme; | ||
supportedScheme = guessSupportedScheme(keySystem); | ||
const notSupportedResult = { | ||
powerEfficient: false, | ||
smooth: false, | ||
supported: false, | ||
keySystemAccess: null, | ||
configuration: requestedConfiguration, | ||
}; | ||
if (audioScheme && audioScheme != supportedScheme) { | ||
return notSupportedResult; | ||
} | ||
if (videoScheme && videoScheme != supportedScheme) { | ||
return notSupportedResult; | ||
} | ||
} | ||
// At this point, either it's unencrypted or we assume the encryption scheme | ||
// is supported. So delegate to the original decodingInfo() method. | ||
const capabilities = | ||
await McEncryptionSchemePolyfill.originalDecodingInfo_.call( | ||
this, requestedConfiguration); | ||
if (capabilities.keySystemAccess) { | ||
// If the result is supported and encrypted, this will be a | ||
// MediaKeySystemAccess instance. Wrap the MKSA object in ours to provide | ||
// the missing field in the returned configuration. | ||
capabilities.keySystemAccess = | ||
new EmeEncryptionSchemePolyfillMediaKeySystemAccess( | ||
capabilities.keySystemAccess, supportedScheme); | ||
} | ||
return capabilities; | ||
} | ||
} | ||
/** | ||
* A wrapper around MediaKeySystemAccess that adds encryptionScheme | ||
@@ -323,2 +446,58 @@ * fields to the configuration, to emulate what a browser with native support | ||
/** | ||
* Guess the supported encryption scheme for the key system. | ||
* | ||
* @param {string} keySystem The key system ID. | ||
* @return {?string} A guess at the encryption scheme this key system | ||
* supports. | ||
*/ | ||
function guessSupportedScheme(keySystem) { | ||
if (keySystem.startsWith('com.widevine')) { | ||
return 'cenc'; | ||
} else if (keySystem.startsWith('com.microsoft')) { | ||
return 'cenc'; | ||
} else if (keySystem.startsWith('com.adobe')) { | ||
return 'cenc'; | ||
} else if (keySystem.startsWith('org.w3')) { | ||
return 'cenc'; | ||
} else if (keySystem.startsWith('com.apple')) { | ||
return 'cbcs-1-9'; | ||
} | ||
// We don't have this key system in our map! | ||
// Log a warning. The only way the request will succeed now is if the | ||
// app doesn't specify an encryption scheme in their own configs. | ||
// Use bracket notation to keep this from being stripped from the build. | ||
console['warn']('EmeEncryptionSchemePolyfill: Unknown key system:', | ||
keySystem, 'Please contribute!'); | ||
return null; | ||
} | ||
/** | ||
* @param {?MediaKeySystemAccess} mediaKeySystemAccess A native | ||
* MediaKeySystemAccess instance from the browser. | ||
* @return {boolean} True if browser natively supports encryptionScheme. | ||
*/ | ||
function hasEncryptionScheme(mediaKeySystemAccess) { | ||
const configuration = mediaKeySystemAccess.getConfiguration(); | ||
// It doesn't matter which capability we look at. For this check, they | ||
// should all produce the same result. | ||
const firstVideoCapability = | ||
configuration.videoCapabilities && configuration.videoCapabilities[0]; | ||
const firstAudioCapability = | ||
configuration.audioCapabilities && configuration.audioCapabilities[0]; | ||
const firstCapability = firstVideoCapability || firstAudioCapability; | ||
// If supported by the browser, the encryptionScheme field must appear in | ||
// the returned configuration, regardless of whether or not it was | ||
// specified in the supportedConfigurations given by the application. | ||
if (firstCapability['encryptionScheme'] !== undefined) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
/** | ||
* The original requestMediaKeySystemAccess, before we patched it. | ||
@@ -336,2 +515,31 @@ * | ||
/** | ||
* The original decodingInfo, before we patched it. | ||
* | ||
* @type { | ||
* function(this:MediaCapabilities, | ||
* !MediaDecodingConfiguration | ||
* ):!Promise.<!MediaCapabilitiesDecodingInfo> | ||
* } | ||
* @private | ||
*/ | ||
McEncryptionSchemePolyfill.originalDecodingInfo_; | ||
/** | ||
* A single entry point for both polyfills (EME & MC). | ||
* | ||
* @export | ||
*/ | ||
class EncryptionSchemePolyfills { | ||
/** | ||
* Installs both polyfills (EME & MC). | ||
* | ||
* @export | ||
*/ | ||
static install() { | ||
EmeEncryptionSchemePolyfill.install(); | ||
McEncryptionSchemePolyfill.install(); | ||
} | ||
} | ||
// Support for CommonJS and AMD module formats. | ||
@@ -341,4 +549,4 @@ /** @suppress {undefinedVars} */ | ||
if (typeof module !== 'undefined' && module.exports) { | ||
module.exports = EmeEncryptionSchemePolyfill; | ||
module.exports = EncryptionSchemePolyfills; | ||
} | ||
})(); |
{ | ||
"name": "eme-encryption-scheme-polyfill", | ||
"description": "A polyfill for the encryptionScheme field in EME", | ||
"version": "1.0.3", | ||
"version": "2.0.0", | ||
"license": "Apache-2.0", | ||
@@ -20,3 +20,3 @@ "author": "Google", | ||
"closure-compiler-check": "google-closure-compiler -O ADVANCED --generate_exports --js_output_file /dev/null --jscomp_error '*' closure-compiler-check/* index.js", | ||
"build": "browserify index.js -s EmeEncryptionSchemePolyfill -t babelify -t stripify -p tinyify -p browserify-header -o dist/eme-encryption-scheme-polyfill.js", | ||
"build": "browserify index.js -s EncryptionSchemePolyfills -t babelify -t stripify -p tinyify -p browserify-header -o dist/eme-encryption-scheme-polyfill.js", | ||
"prepublishOnly": "npm run-script lint && npm run-script closure-compiler-check && npm run-script build" | ||
@@ -23,0 +23,0 @@ }, |
@@ -1,4 +0,5 @@ | ||
# EME Encryption Scheme Polyfill | ||
# EME & MediaCapabilities Encryption Scheme Polyfill | ||
A polyfill to add support for EncryptionScheme queries in EME. | ||
A polyfill to add support for EncryptionScheme queries in EME and | ||
MediaCapabilities. | ||
@@ -8,2 +9,3 @@ - https://wicg.github.io/encrypted-media-encryption-scheme/ | ||
- https://github.com/WICG/encrypted-media-encryption-scheme/issues/13 | ||
- https://github.com/w3c/media-capabilities/issues/100 | ||
@@ -19,8 +21,8 @@ Because this polyfill can't know what schemes the UA or CDM actually support, | ||
module compatible with the CommonJS and AMD module formats, and can also be | ||
directly included via a script tag. It is about 3.1kB uncompressed, and gzips | ||
to about 1.2kB. | ||
directly included via a script tag. It is about 4.4kB uncompressed, and gzips | ||
to about 1.5kB. | ||
To avoid the possibility of extra user prompts, this will shim EME so long as | ||
it exists, without checking support for `encryptionScheme` upfront. The | ||
support check will happen on-demand the first time EME is used. | ||
To avoid the possibility of extra user prompts, this will shim EME & MC so long | ||
as they exist, without checking support for `encryptionScheme` upfront. The | ||
support check will happen on-demand the first time EME/MC are used. | ||
@@ -39,3 +41,8 @@ | ||
```js | ||
// Install both EME & MC polyfills at once: | ||
EncryptionSchemePolyfills.install(); | ||
// Install each one separately (unminified source only): | ||
EmeEncryptionSchemePolyfill.install(); | ||
McEncryptionSchemePolyfill.install(); | ||
``` |
39870
494
46