Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions src/streaming/ManifestLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,10 @@ function ManifestLoader(config) {
settings.get().streaming.enableManifestDurationMismatchFix &&
manifest.mediaPresentationDuration &&
manifest.Period.length > 1) {
const sumPeriodDurations = manifest.Period.reduce((totalDuration, period) => totalDuration + period.duration, 0);
if (!isNaN(sumPeriodDurations) && manifest.mediaPresentationDuration > sumPeriodDurations) {
const safeDuration = _getSafeDuration(manifest.Period);
if (!isNaN(safeDuration) && manifest.mediaPresentationDuration > safeDuration) {
logger.warn('Media presentation duration greater than duration of all periods. Setting duration to total period duration');
manifest.mediaPresentationDuration = sumPeriodDurations;
manifest.mediaPresentationDuration = safeDuration;
}
}

Expand Down Expand Up @@ -267,6 +267,31 @@ function ManifestLoader(config) {
}
}

function _getSegmentDuration(s) {
return (s.r ? s.d * (s.r + 1) : s.d);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not cover the case of negative r values, see TimelineSegmentsGetter.iterateSegments

}

function _getSafeDuration(periods) {
const sumPeriodDurations = periods.reduce((totalDuration, period) => totalDuration + period.duration, 0);
if (isNaN(sumPeriodDurations)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be !sNaN(sumPeriodDurations) to return the value in case it is not NaN

return sumPeriodDurations;
}

const lastPeriod = periods[periods.length - 1];
if (lastPeriod.duration) {
return lastPeriod.start + lastPeriod.duration;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a check to verify that lastPeriod.start is not undefined or null or NaN

}

const segmentTemplate = lastPeriod.AdaptationSet.filter((set) => set.mimeType === 'video/mp4')[0].Representation[0].SegmentTemplate;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will cause an issue if there is no AdaptationSet with mimeType set to video/mp4. Please add some checks if the attributes are accessible. Please also add a try...catch statement in the function and return NaN in the catch block.

For instance, in this manifest the mimeType is on Representation level: https://dash.akamaized.net/dash264/TestCases/5a/nomor/1.mpd

const segments = segmentTemplate.SegmentTimeline.S;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we cover the case in which SegmentTemplate is used without SegmentTimeline

if (Array.isArray(segments)){
return lastPeriod.start +
segments.reduce((segmentsDuration, s) => segmentsDuration + _getSegmentDuration(s), 0) / segmentTemplate.timescale;
} else {
return lastPeriod.start + _getSegmentDuration(segments) / segmentTemplate.timescale;
}
}

instance = {
load: load,
reset: reset
Expand Down