diff --git a/index.d.ts b/index.d.ts index 891cb8de79..0e31a15bc0 100644 --- a/index.d.ts +++ b/index.d.ts @@ -155,6 +155,7 @@ declare namespace dashjs { applyServiceDescription?: boolean, cacheInitSegments?: boolean, eventControllerRefreshDelay?: number, + enableManifestDurationMismatchFix?: boolean, capabilities?: { filterUnsupportedEssentialProperties?: boolean, useMediaCapabilitiesApi?: boolean diff --git a/src/core/Settings.js b/src/core/Settings.js index 055fa2416c..872022ae7d 100644 --- a/src/core/Settings.js +++ b/src/core/Settings.js @@ -66,6 +66,7 @@ import Events from './events/Events'; * applyServiceDescription: true, * applyProducerReferenceTime: true, * eventControllerRefreshDelay: 100, + * enableManifestDurationMismatchFix: true, * capabilities: { * filterUnsupportedEssentialProperties: true, * useMediaCapabilitiesApi: false @@ -665,6 +666,8 @@ import Events from './events/Events'; * @property {boolean} [applyProducerReferenceTime=true] * Set to true if dash.js should use the parameters defined in ProducerReferenceTime elements in combination with ServiceDescription elements. * @property {number} [eventControllerRefreshDelay=100] + * For multi-period streams, overwrite the manifest mediaPresentationDuration attribute with the sum of period durations if the manifest mediaPresentationDuration is greater than the sum of period durations + * @property {boolean} [enableManifestDurationMismatchFix=true] * Defines the delay in milliseconds between two consecutive checks for events to be fired. * @property {module:Settings~Metrics} metrics Metric settings * @property {module:Settings~LiveDelay} delay Live Delay settings @@ -768,6 +771,7 @@ function Settings() { applyServiceDescription: true, applyProducerReferenceTime: true, eventControllerRefreshDelay: 100, + enableManifestDurationMismatchFix: true, capabilities: { filterUnsupportedEssentialProperties: true, useMediaCapabilitiesApi: false diff --git a/src/streaming/ManifestLoader.js b/src/streaming/ManifestLoader.js index 981143ab60..27f92e4b48 100644 --- a/src/streaming/ManifestLoader.js +++ b/src/streaming/ManifestLoader.js @@ -47,6 +47,7 @@ function ManifestLoader(config) { config = config || {}; const context = this.context; const debug = config.debug; + const settings = config.settings; const eventBus = EventBus(context).getInstance(); const urlUtils = URLUtils(context).getInstance(); @@ -194,6 +195,20 @@ function ManifestLoader(config) { logger.debug('BaseURI set by Location to: ' + baseUri); } + // If there is a mismatch between the manifest's specified duration and the total duration of all periods, + // and the specified duration is greater than the total duration of all periods, + // overwrite the manifest's duration attribute. This is a patch for if a manifest is generated incorrectly. + if (settings && + settings.get().streaming.enableManifestDurationMismatchFix && + manifest.mediaPresentationDuration && + manifest.Period_asArray.length > 1) { + const sumPeriodDurations = manifest.Period_asArray.reduce((totalDuration, period) => totalDuration + period.duration, 0); + if (manifest.mediaPresentationDuration > sumPeriodDurations) { + logger.warn('Media presentation duration greater than duration of all periods. Setting duration to total period duration'); + manifest.mediaPresentationDuration = sumPeriodDurations; + } + } + manifest.baseUri = baseUri; manifest.loadedTime = new Date(); xlinkController.resolveManifestOnLoad(manifest);