Skip to content
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: add support for dash manifests describing sidx boxes #455

Merged
merged 51 commits into from Apr 12, 2019

Conversation

ldayananda
Copy link
Contributor

Description

Attempt to fix #162.

Requires videojs/mpd-parser#41

Specific Changes proposed

Dash playlist loader requests the sidx after parsing the master manifest once for the sidx byte range information. Then, the master playlist is mutated.

Current Status

  • Need to investigate ended issue (known issue 1)

Sources:

{ 
  src: "https://dash.akamaized.net/dash264/TestCases/10a/1/iis_forest_short_poem_multi_lang_480p_single_adapt_aaclc_sidx.mpd",
  type: "application/dash+xml"
}

Known Issues

  1. there appears to be a bug where the ended event is not fired sometimes. This may be an existing issues with DASH.
    Repro by using https://dash.akamaized.net/dash264/TestCases/10a/1/iis_forest_short_poem_multi_lang_480p_single_adapt_aaclc_sidx.mpd, seeking to > 25s, changing audio selection, seeking near the end.
    The skipped playback test DASH sidx with alt audio should end should also reproduce the issue

  2. if sidx ranges change in between Periods in a live stream, we do not clean up sidxMapping.
    This will not be handled at this point as there is further multiperiod work that is required to be able to detect a period change. There is a TODO in the code for this, but no Github issues yet

Requirements Checklist

  • Feature implemented / Bug fixed
  • Unit Tests updated or fixed
  • Reviewed by Core Contributor(s)

ldayananda added 30 commits March 11, 2019 16:52
- start DashPlaylistLoader in HAVE_NOTHING state
- enter HAVE_METADATA in media() method
- set media automatically only for child playlist loader as masterPlaylistLoader is set from masterPlaylistController

update tests with desired behavior

ensure loadedmetadata is triggered after loadedplaylist

remove unnecessary media playlist selection for master loader
…urns and once when the initial media is selected
- delay triggering selectedinitialmedia event until the active audio playlist loader is finished setting media

- ensure that HLS playlists without alternate audio are not affected
- don't autoselect media for the masterPlaylistLoader as that is done by MasterPlaylistController
- ensure updateMaster returns null if there are no changes in the playlist
- trigger loadedmetadata as part of haveMetadata
- add some comments to explain why we trigger certain events and set media at points
- moving haveMetadata to a class-level method, more comments.

- remove setTimeouts as they were not performing a necessary function. XHR requests can return in any amount of time and HLS PlaylistLoader handles any requests within a callback, or returns if a request need not be made. DASH should do the same

- cleanup the minimumUpdatePeriod setup

- remove unnecessary clock.ticks from tests
- fix up a comment
- add idea for media groups refactor
…mention hasPendingRequest for fallback media selection
- correcting merge mistake
- moving check for sidx to correct place
- have parseMasterXml use previously downloaded sidxes when refreshing media
@gkatsev
Copy link
Member

gkatsev commented Apr 5, 2019

TODO:

  • review code
  • try it out
  • review tests
  • re-review code
  • have someone else look through the mpd-parser code
  • have someone else look through the code
  • release actual mpd-parser update
  • update the "current behavior" section of the DPL doc.

@gkatsev
Copy link
Member

gkatsev commented Apr 8, 2019

@gkatsev
Copy link
Member

gkatsev commented Apr 8, 2019

This one from the dash-mse-test is also working: http://yt-dash-mse-test.commondatastorage.googleapis.com/media/motion-20120802-manifest.mpd

@gkatsev
Copy link
Member

gkatsev commented Apr 8, 2019

gkatsev
gkatsev previously approved these changes Apr 8, 2019
gkatsev
gkatsev previously approved these changes Apr 8, 2019
Copy link
Contributor

@brandonocasey brandonocasey left a comment

Choose a reason for hiding this comment

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

Mostly looks good, just some style changes really. Side note. I find it extremely confusing that there are so many playlists objects (are some of them arrays?). Seems like we could use a small refactor just to be more descriptive with names where we can.

package.json Outdated Show resolved Hide resolved
const equivalentSidx = (a, b) => {
let equivalentMap = true;

if (a.map && b.map) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What if one of them has a map and the other does not? Doesn't that make them not equivalent?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, the map here is the init segment for the playlist

Copy link
Contributor

Choose a reason for hiding this comment

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

So should the check be (a.map || b.map) so that we check if either has a map?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I suppose the if condition is unnecessary as the value of equivalentMap would be falsy if either a or b did not have map

Copy link
Member

Choose a reason for hiding this comment

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

equivalentMap already checks that both have .map, so, I'm going to remove the if statement.

Copy link
Member

Choose a reason for hiding this comment

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

Improved

src/dash-playlist-loader.js Show resolved Hide resolved
@@ -178,7 +316,48 @@ export default class DashPlaylistLoader extends EventTarget {
this.trigger('mediachanging');
}

// TODO: check for sidx here
if (playlist.sidx) {
Copy link
Contributor

Choose a reason for hiding this comment

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

perhaps it would make more sense to more the mediaRequest below this if statement into if (!playlist.sidx) and then return inside of it? That would keep similar code together and get rid of a big if scope.

Copy link
Member

Choose a reason for hiding this comment

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

Makes sense to me

};

// exported for testing
export const filterSidxMapping = (masterXml, srcUrl, clientOffset, oldSidxMapping) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't quite understand what this function is filtering. It seems to be merging a new sidx mapping with an old one?

Copy link
Contributor Author

@ldayananda ldayananda Apr 8, 2019

Choose a reason for hiding this comment

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

it's removing sidx mappings that have changed (either url or indexRange) from the video and audio playlists

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe rename it to removeChangedMappings for clarity?

Copy link
Member

Choose a reason for hiding this comment

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

I think filter is fine there because it parallels Array#filter. However, a comment can be added to clarify.

Copy link
Member

Choose a reason for hiding this comment

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

Updated the name a bit as well.

@ldayananda
Copy link
Contributor Author

I find it extremely confusing that there are so many playlists objects (are some of them arrays?).

The playlist objects are mimicking HLS playlists, where we have an array of playlists, but also put keys on them (which I agree is confusing). Changing this would be a large refactor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Request sidx defined segments from DASH SegmentBase streams
3 participants