Skip to content

Commit

Permalink
Optimize MediaCapabilitiesAPI checks by saving the results and only r…
Browse files Browse the repository at this point in the history
…unning new checks when the configuration has not been tested before. (#4564)
  • Loading branch information
dsilhavy authored Sep 5, 2024
1 parent b3c61fc commit b1c0a4b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
52 changes: 49 additions & 3 deletions src/streaming/utils/Capabilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import FactoryMaker from '../../core/FactoryMaker.js';
import Constants from '../constants/Constants.js';
import ProtectionConstants from '../constants/ProtectionConstants.js';
import ObjectUtils from './ObjectUtils.js';

export function supportsMediaSource() {
let hasManagedMediaSource = ('ManagedMediaSource' in window)
Expand All @@ -44,10 +45,15 @@ function Capabilities() {

let instance,
settings,
testedCodecConfigurations,
encryptedMediaSupported;

const context = this.context;
const objectUtils = ObjectUtils(context).getInstance();

function setup() {
encryptedMediaSupported = false;
testedCodecConfigurations = [];
}

function setConfig(config) {
Expand Down Expand Up @@ -167,20 +173,60 @@ function Capabilities() {

const genericMediaCapabilitiesConfiguration = _getGenericMediaCapabilitiesConfig(inputConfig, type);
const configurationsToTest = _enhanceGenericConfigurationWithKeySystemConfiguration(genericMediaCapabilitiesConfiguration, inputConfig, type)

const promises = configurationsToTest.map((configuration) => {
return navigator.mediaCapabilities.decodingInfo(configuration)
return _checkSingleConfigurationWithMediaCapabilities(configuration);
})

Promise.allSettled(promises)
.then((results) => {
const isSupported = results.some((singleResult) => {
return singleResult.status === 'fulfilled' && singleResult.value && singleResult.value.supported
const isSupported = results.some((result) => {
return !!result.value
})
resolve(isSupported);
})
});
}

function _checkSingleConfigurationWithMediaCapabilities(configuration) {
return new Promise((resolve) => {
const alreadyTestedConfiguration = _getTestedCodecConfiguration(configuration);

if (alreadyTestedConfiguration) {
const isSupported = _isConfigSupported(alreadyTestedConfiguration.decodingInfo);
resolve(isSupported);
return
}

navigator.mediaCapabilities.decodingInfo(configuration)
.then((decodingInfo) => {
configuration.decodingInfo = decodingInfo;
testedCodecConfigurations.push(configuration);
const isSupported = _isConfigSupported(decodingInfo);
resolve(isSupported);
})
})
}

function _isConfigSupported(decodingInfo) {
return decodingInfo.supported
}

function _getTestedCodecConfiguration(configuration) {
if (!testedCodecConfigurations || testedCodecConfigurations.length === 0 || !configuration) {
return null
}

return testedCodecConfigurations.find((current) => {
const audioEqual = configuration && configuration.audio ? objectUtils.areEqual(configuration.audio, current.audio) : true;
const videoEqual = configuration && configuration.video ? objectUtils.areEqual(configuration.video, current.video) : true;
const keySystemEqual = configuration && configuration.keySystemConfiguration ? objectUtils.areEqual(configuration.keySystemConfiguration, current.keySystemConfiguration) : true;

return audioEqual && videoEqual && keySystemEqual
})

}

function _getGenericMediaCapabilitiesConfig(inputConfig, type) {
let configuration

Expand Down
2 changes: 1 addition & 1 deletion src/streaming/utils/ObjectUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function ObjectUtils() {
}

instance = {
areEqual: areEqual
areEqual
};

return instance;
Expand Down

0 comments on commit b1c0a4b

Please sign in to comment.