-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support multi-period live DASH with changing periods #152
Conversation
In order to handle live DASH manifests where periods are changed, added, and removed, merging is used to ensure that the new manifest is a continuation of the last parsed manifest. In order to handle live cases, the last MPD must be provided via the `lastMpd` option. BREAKING CHANGE: period start time is now used as the timeline instead of period index
Codecov Report
@@ Coverage Diff @@
## main #152 +/- ##
==========================================
+ Coverage 93.17% 94.30% +1.12%
==========================================
Files 17 18 +1
Lines 674 772 +98
Branches 224 240 +16
==========================================
+ Hits 628 728 +100
+ Misses 46 44 -2
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preliminary review, still need to do a deeper one in some places.
playlist.discontinuitySequence = findIndex(timelineStarts, ({ timeline }) => timeline === playlist.timeline); | ||
|
||
if (!playlist.segments) { | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might as well add a test here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quick comments on the small files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some fairly minor comments.
README.md
Outdated
@@ -44,6 +44,17 @@ const manifest = await res.text(); | |||
var parsedManifest = mpdParser.parse(manifest, { manifestUri }); | |||
``` | |||
|
|||
If dealing with a live stream, then on subsequent calls to parse, the last parsed manifest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If dealing with a live stream, then on subsequent calls to parse, the last parsed manifest | |
If dealing with a live stream, then on subsequent calls to parse, the previously parsed manifest |
|
||
const SUPPORTED_MEDIA_TYPES = ['AUDIO', 'SUBTITLES']; | ||
// allow one 60fps frame as leniency (arbitrarily chosen) | ||
const TIME_FUDGE = 1 / 60; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delicious 🍫
src/playlist-merge.js
Outdated
return union(timelineStarts, ({ timeline }) => timeline).sort((a, b) => | ||
(a.timeline > b.timeline) ? 1 : -1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Splitting on the .sort
, I think, makes it a lot easier to understand that we call union and then sort on the response from union
. At first, I thought that we were passing a method and the sort as a second argument to union.
The linter should be fine with this, I checked.
return union(timelineStarts, ({ timeline }) => timeline).sort((a, b) => | |
(a.timeline > b.timeline) ? 1 : -1); | |
return union(timelineStarts, ({ timeline }) => timeline) | |
.sort((a, b) => (a.timeline > b.timeline) ? 1 : -1); |
playlist.segments.forEach((segment, index) => { | ||
segment.number = playlist.mediaSequence + index; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is part of the magic that makes thing whole thing work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Along with the passed-in media sequence calculations in updateSequenceNumber
below.
Multiperiod SIDX (in both live and VOD) and live SIDX where the SIDX properties change on refresh, are not yet supported in mpd-parser. To prevent exceptions, return early from merging logic on SIDX detection, and add a TODO comment for the future.
Updates old start references to periodStart, as periodStart should not be generated where the start attribute was missing. Fixes durationTimeParser segment time values by using the number rather than a 0 based index for calcuating time. Add comments in durationTimeParser to make logic clearer.
In order to support the new mpd-parser API, whenever a DASH manifest refreshes, the prior parsed manifest object needs to be passed in as `previousManifest`. This change adds support for that. NOTE: this is to support an upcoming feature in mpd-parser: videojs/mpd-parser#152
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code LGTM, haven't tested it yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just ran a bunch of tests and it works great!
In order to handle live DASH manifests where periods are changed, added, and removed,
merging is used to ensure that the new manifest is a continuation of the last parsed
manifest.
In order to handle live cases, the last MPD must be provided via the
lastMpd
option.BREAKING CHANGE: period start time is now used as the timeline instead of period index