The DurationMatcher (src/dash/parser/matchers/DurationMatcher.js) has a very basic implementation to convert ISO8601 Periods (duration) using hardcoded values :
const SECONDS_IN_YEAR = 365 * 24 * 60 * 60;
const SECONDS_IN_MONTH = 30 * 24 * 60 * 60;
const SECONDS_IN_DAY = 24 * 60 * 60;
const SECONDS_IN_HOUR = 60 * 60;
const SECONDS_IN_MIN = 60;
It works fine with smalll periods, however one year is not really 365 days and one month is not really 30 days so the current implementation is not working with long periods.
In my case I have streams with
<Period id="p0" start="P48Y2M29DT08H40M16S">
The duration returned by the DurationMatcher when parsing "P48Y2M29DT08H40M16S" is totally wrong.
I tried to update the SECONDS_IN_YEAR to 365.24 days and SECONDS_IN_MONTH to 30.44 days (based on https://www.epochconverter.com/) but its not fixing the problem.
The duration "P48Y2M29DT08H40M16S" can be parsed using moment.js (http://momentjs.com/, MIT licence). I'm still testing but so far following implementation seems ok :
https://github.com/Dash-Industry-Forum/dash.js/pull/2510
Do you think it's acceptable to add moment.js as a new required module?
The problem is that using calendar times (years, months) in durations requires some reference to make sense of these values. Even moment can't make sense of this sort of duration without combining it with a reference as suggested in the PR.
The ISO spec is very clear that months have varying lengths (with a note stating some applications simply regarding a month as thirty days), and a year is simply a time-unit of twelve months, so it seems to me that it'd be better not to use calendar times at all and stick to absolute times (seconds, minutes, hours and days) for durations.
All that said, clearly DurationMatcher is naive right now and could be improved.
I don't think the calculation done with moment.js is more correct than the simplified one in dash.js. Dash.js is simplifying calculations assuming every month has 30 days and taking as own the note in ISO 8601 spec mentioned by @bbcrddave ("some" apps can take 1 month as 30 days); in your implementation with moment.js you are taking as the reference start time unix epoch which is neither correct (at least your stream start time is unix epoch or your packager assumes unix epoch as the reference time to generate duration values). So, IMHO, I think neither of resulting numbers will be accurate for long durations.
As an alternative, I have seen some implementations, like Exoplayer one, that use average values for representing seconds_per_year and seconds_per_month (ex: avg year duration for the last 400 years is 365.2425 days, https://en.wikipedia.org/wiki/Year). However I don't think this itself implies more accuracy.
Furthermore, behavior should be different depending on the type of the stream. For Live streams we could use availabilityStartTime as the reference time for calculating periods duration; for VoD streams there is no any reference time.
What makes sense to me is MPEG-DASH packagers and clients share the same criteria regarding how xs:duration attributes must be translated to seconds. Probably makes sense adding this kind of information to the IOP guidelines (for example, specifying MPEG-DASH is one of those "apps" that takes a month equal to 30 days when translating duration attributes to seconds).
@sandersaares, what do you think? You are working on some IOP changes related with timing (leap seconds related) and I am pretty sure you have an opinion regarding this.
I agree that there are multiple potentially valid ways to view this, none necessarily more right than the others, leading to conflict. To avoid confusion, IOP should say that units bigger than 1 day (=24 hours) are not to be used. I will file an issue in the IOP tracker for this.
Most helpful comment
I agree that there are multiple potentially valid ways to view this, none necessarily more right than the others, leading to conflict. To avoid confusion, IOP should say that units bigger than 1 day (=24 hours) are not to be used. I will file an issue in the IOP tracker for this.