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

Support fallback manifest uris for Player.load() #1437

Closed
chrisfillmore opened this issue May 11, 2018 · 7 comments
Closed

Support fallback manifest uris for Player.load() #1437

chrisfillmore opened this issue May 11, 2018 · 7 comments
Labels
status: archived Archived and locked; will not be updated

Comments

@chrisfillmore
Copy link
Contributor

In order to deliver some ad-enabled content, we pass our manifest URI to a third-party ad service, which responds back with a new URI which we then pass to Shaka. If this new URI 404's, we would like to fall back to the original URI, so that we can play the content without the ads.

This seems straightforward to implement on the Player and ManifestParser side. (Pass an array of URI's to Player.load.) But the behaviour of NetworkingEngine is to cycle through URI's while retrying. We would like to exhaust all retries for the first URI, then try the second URI, and exhaust retries for that. This seems like a bigger change. Could such behaviour be provided with a general purpose configuration flag on shakaExtern.RetryParameters? Any other ideas?

@TheModMaker
Copy link
Contributor

First, NetworkingEngine should use every URI when doing retries. Meaning the first request will be for the first URI, then the second request will be to the second URI, third request to the third URI (or back to the first if there are only two), etc. If we aren't doing that, it is a bug (but I'm fairly sure it does work since we have a test).

Second, I think it would be easier to have you just catch the error from loading the manifest and do a second call to load with the other manifest. Although this could be a useful feature, I think it has some confusing semantics. DASH already supports fallback URIs, but they specify identical content, so it shouldn't matter which one we request. But your use case seems different because it sounds like different content.

Some questions about this design in general: How would it work with live (with later manifest requests)? If the user passes two URIs and the first manifest request responds with the second URI, should we only request the second URI or still try the first URI? How should this interact with 3XX redirects, which have been requested to keep to the redirect URI (#1367)?

@chrisfillmore
Copy link
Contributor Author

To be clear, this is a feature request, not a bug. There's nothing wrong with NetworkingEngine as far as I know, it behaves as expected.

You mention this:

DASH already supports fallback URIs, but they specify identical content, so it shouldn't matter which one we request. But your use case seems different because it sounds like different content.

I think this is an interesting scenario, because it makes me wonder what DASH means by "identical content". With dynamic ad insertion, two users watching the same stream will see the same "content", but potentially different ads. I would argue this is "identical content" since there is no way for us to know the composition of the ad breaks ahead of time, only the timing of them.

Our ads for live content are delivered via multi-period DASH. We expect to do the same for VOD in the future.

On reflection, I actually think that NetworkingEngine's current behaviour is fine for live, since we'll be fetching a new manifest every 6s anyway. If the user misses an ad break in some exceptional circumstances (i.e. they see some placeholder content during an ad break, instead of ads), this is not the end of the world. For VOD, we could just catch the manifest failure error and retry with the fallback URL. My only concern is if there would be some delay because of startup/teardown time. But this would also only happen under exceptional circumstances.

I'll close this since it appears we are probably fine with the current behaviour. Thanks!

@chrisfillmore
Copy link
Contributor Author

No, wait, reopening because we still want to be able to pass multiple URL's to Player.load().

@chrisfillmore chrisfillmore reopened this May 15, 2018
@chrisfillmore
Copy link
Contributor Author

The url passed to Player.load() is passed to a ManifestParser, which puts it in an array before passing it to NetworkingEngine anyway. Would Shaka accept a PR to allow Player.load() to accept an array of URLs?

@TheModMaker
Copy link
Contributor

I am concerned that this API could have some confusing semantics. It may appear, without reading the documentation, that we would play them sequentially. Also, should we use all the URIs forever (similar to DASH's logic) or should we stick to the first one that works?

DASH's support for fallback URIs is for media segments. By specifying multiple <BaseURL> elements, that means that a segment can be downloaded from more than one server. This allows fallbacks for down servers. This requires that each server hold the same segments so that it doesn't matter which server we query, we will still get the same media.

DASH also supports xlink elements, which means making another request to a different URI to get a piece of the manifest. For example, the first Period could contain regular content, but the second Period would be empty and contain an xlink that will be queried to get the real content. This allows dynamic ad-insertion with a mostly-static manifest. We support this case so long as it uses xlink:actuate=onLoad. We also will fall-back to the content that is already in the Period if the request for that piece fails. This could be used in your case. For example:

<Period duration="PT60S">
  <!-- Static content -->
</Period>
<Period duration="PT60S" xlink:href="ad.mpd">
  <!-- Content to load if ad.mpd fails to load -->
</Period>

@chrisfillmore
Copy link
Contributor Author

Thanks for the suggestion. I'm not very familiar with xlink so I'd have to take a closer look.

I actually think what might make the most sense is for our ad provider provider to respond with a redirect to the original URL if they aren't able to serve at the modified URL. I'll close this ticket for now. Thanks.

@chrisfillmore
Copy link
Contributor Author

I realized that I could achieve what I want by registering a request filter for manifests and pushing my fallback url into request.uris.

@shaka-project shaka-project locked and limited conversation to collaborators Jul 15, 2018
@shaka-bot shaka-bot added the status: archived Archived and locked; will not be updated label Apr 15, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status: archived Archived and locked; will not be updated
Projects
None yet
Development

No branches or pull requests

3 participants