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

"No CDN to request" thrown when using templated MPD with relative paths #1190

Closed
alexg-axis opened this issue Dec 7, 2022 · 3 comments · Fixed by #1192
Closed

"No CDN to request" thrown when using templated MPD with relative paths #1190

alexg-axis opened this issue Dec 7, 2022 · 3 comments · Fixed by #1192

Comments

@alexg-axis
Copy link

With v3.29.0, I cannot load a DASH playlist. I get the No CDN to request error (PIPELINE_LOAD_ERROR). I assume this is due to the changes made to content steering in v3.29.0

The playlist looks like this:

<?xml version="1.0" encoding="utf-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="urn:mpeg:dash:schema:mpd:2011"
	xmlns:xlink="http://www.w3.org/1999/xlink"
	xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
	profiles="urn:mpeg:dash:profile:isoff-live:2011"
	type="dynamic"
	minimumUpdatePeriod="PT500S"
	suggestedPresentationDelay="PT1S"
	availabilityStartTime="2022-12-07T08:52:13.150Z"
	publishTime="2022-12-07T08:52:13.926Z"
	maxSegmentDuration="PT1.0S"
	minBufferTime="PT2.0S">
	<ProgramInformation>
	</ProgramInformation>
	<ServiceDescription id="0">
	</ServiceDescription>
	<Period id="0" start="PT0.0S">
		<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="25/1" maxWidth="768" maxHeight="576" par="4:3">
			<Representation id="0" mimeType="video/mp4" codecs="avc1.640028" bandwidth="176736" width="768" height="576" sar="1:1">
				<SegmentTemplate timescale="1000000" duration="1000000" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
				</SegmentTemplate>
			</Representation>
		</AdaptationSet>
		<AdaptationSet id="1" contentType="audio" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true">
			<Representation id="1" mimeType="audio/mp4" codecs="mp4a.40.2" bandwidth="69000" audioSamplingRate="44100">
				<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="1" />
				<SegmentTemplate timescale="1000000" duration="1000000" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
				</SegmentTemplate>
			</Representation>
		</AdaptationSet>
	</Period>
</MPD>

I use a custom segment loader to fetch the segments from a base path communicated via other means.

player.loadVideo({
  transport: 'dash',
  transportOptions: {
    initialManifest: manifest,
    segmentLoader: downloadSegment,
    manifestLoader: downloadManifest, // Just returns the manifest value immediately
  }
})

I've tried to find potential issues looking through #1165, but I didn't find anything concrete. I assume it could be due to the logic not being able to identify any CDN due to the use of relative paths.

@peaBerberian
Copy link
Collaborator

peaBerberian commented Dec 8, 2022

Hi,

You're right :/

The issue seems to happen only when there's no url communicated to the RxPlayer through the loadVideo API.
I don't know yet all the preconditions but I also reproduce with no url property and a manifestLoader returning your MPD (I guess it also only happens when the MPD has no BaseURL? Not that there is any technical problem with that).

That's definitely a RxPlayer issue and I'll start work on a fix very soon but thankfully, it seems easy to work-around: you can set a url on loadVideo, even an empty string, and the error should disappear.
Though this is not a clean long term solution.

Thanks for the report. I'll keep you updated through this issue.

@alexg-axis
Copy link
Author

Thanks for taking a look and proposing a workaround. It works!

I assume this is a good a time as any to sincerely thank you for your great work with this project. I think it's a stellar example of a well-managed project. Your in-depth release notes are always a fun read!

@peaBerberian
Copy link
Collaborator

Thanks a lot :), this is appreciated

peaBerberian added a commit that referenced this issue Dec 13, 2022
…rl and without BaseURL elements

Fixes #1190

We brought in the last v3.29.0 a regression which made it impossible to play a DASH content in very specific conditions.
Thankfully, the conditions to reproduce it are relatively rare and easy to work-around (as written in the issue). Basically it only happens when all following conditions are true:
  1. You're playing a DASH content
  2. You didn't communicate an `url` for the MPD (for now only works if you at least communicated either a `initialManifest` or a `manifestLoader`)
  3. You didn't communicate about the MPD URL in the `manifestLoader` if you used one
  4. The MPD does not contain any `<BaseURL>` element, or it does but only inside `<Representation>` elements (which means basically directly for each segments, e.g. in a `<SegmentList>` element).

When those conditions are met, you will receive a `PIPELINE_LOAD_ERROR` error with the message `"No CDN to request"` when the RxPlayer is trying to request its first segment.

---

This happens because since the RxPlayer v3.29.0, we try to identify one or multiple CDN through which segments may be requested. This is done at the `<Representation>` level.

Under the specific conditions written earlier, MPD parsers will indicate an empty array as the CDN that can be used to reach that Representation's segments, because it has no way of defining even one root URL.
In the corresponding `Manifest`'s structure documentation (the protocol-agnostic structure defined by the RxPlayer for a Manifest), an empty array is then documented as `An empty array means that no CDN are left to request the resource. As such, no resource can be loaded in that situation.`.

So an empty array is for explicitly telling that the segment should be reachable through a potential CDN, but that no CDN is usable, at least right now.
That's why the  `"No CDN to request"` error was sent: the logic performing segment requests just wanted to load a segment, but saw that right now no CDN can be requested for it.

To fix this situation, we could set that value to `null`, which exists, instead of an empty array. But this is how a `null` value is defined in the same `Manifest` structure: `null if there's no CDN involved here (e.g. resources are not requested through the network).`
In that specific issue, the segment may perfectly be reachable through the network, we just don't know the root URL. We also risk breaking functional use cases if a full URL was actually declared for each segment.

I thus hesitated between redefining the empty array and not throw in that case, redefining `null`, or to invent a third special case.
For now, I chose to explicitly allow a new way of telling that an URL may exist, but should be entirely associated to each segment: by setting the empty string instead.

This basically technically indicates - by following the logic already there - that all following URL are either absolute or relative to the page doing the requests, so it may imply a new strange behavior here when only relative segment URL are present (resulting in the browser considering the current page as the root URL), but I don't know how we should realistically act anyway in that specific case.
peaBerberian added a commit that referenced this issue Dec 14, 2022
…rl and without BaseURL elements

Fixes #1190

We brought in the last v3.29.0 a regression which made it impossible to play a DASH content in very specific conditions.
Thankfully, the conditions to reproduce it are relatively rare and easy to work-around (as written in the issue). Basically it only happens when all following conditions are true:
  1. You're playing a DASH content
  2. You didn't communicate an `url` for the MPD (for now only works if you at least communicated either a `initialManifest` or a `manifestLoader`)
  3. You didn't communicate about the MPD URL in the `manifestLoader` if you used one
  4. The MPD does not contain any `<BaseURL>` element, or it does but only inside `<Representation>` elements (which means basically directly for each segments, e.g. in a `<SegmentList>` element).

When those conditions are met, you will receive a `PIPELINE_LOAD_ERROR` error with the message `"No CDN to request"` when the RxPlayer is trying to request its first segment.

---

This happens because since the RxPlayer v3.29.0, we try to identify one or multiple CDN through which segments may be requested. This is done at the `<Representation>` level.

Under the specific conditions written earlier, MPD parsers will indicate an empty array as the CDN that can be used to reach that Representation's segments, because it has no way of defining even one root URL.
In the corresponding `Manifest`'s structure documentation (the protocol-agnostic structure defined by the RxPlayer for a Manifest), an empty array is then documented as `An empty array means that no CDN are left to request the resource. As such, no resource can be loaded in that situation.`.

So an empty array is for explicitly telling that the segment should be reachable through a potential CDN, but that no CDN is usable, at least right now.
That's why the  `"No CDN to request"` error was sent: the logic performing segment requests just wanted to load a segment, but saw that right now no CDN can be requested for it.

To fix this situation, we could set that value to `null`, which exists, instead of an empty array. But this is how a `null` value is defined in the same `Manifest` structure: `null if there's no CDN involved here (e.g. resources are not requested through the network).`
In that specific issue, the segment may perfectly be reachable through the network, we just don't know the root URL. We also risk breaking functional use cases if a full URL was actually declared for each segment.

I thus hesitated between redefining the empty array and not throw in that case, redefining `null`, or to invent a third special case.
For now, I chose to explicitly allow a new way of telling that an URL may exist, but should be entirely associated to each segment: by setting the empty string instead.

This basically technically indicates - by following the logic already there - that all following URL are either absolute or relative to the page doing the requests, so it may imply a new strange behavior here when only relative segment URL are present (resulting in the browser considering the current page as the root URL), but I don't know how we should realistically act anyway in that specific case.
peaBerberian added a commit that referenced this issue Dec 14, 2022
…rl and without BaseURL elements

Fixes #1190

We brought in the last v3.29.0 a regression which made it impossible to play a DASH content in very specific conditions.
Thankfully, the conditions to reproduce it are relatively rare and easy to work-around (as written in the issue). Basically it only happens when all following conditions are true:
  1. You're playing a DASH content
  2. You didn't communicate an `url` for the MPD (for now only works if you at least communicated either a `initialManifest` or a `manifestLoader`)
  3. You didn't communicate about the MPD URL in the `manifestLoader` if you used one
  4. The MPD does not contain any `<BaseURL>` element, or it does but only inside `<Representation>` elements (which means basically directly for each segments, e.g. in a `<SegmentList>` element).

When those conditions are met, you will receive a `PIPELINE_LOAD_ERROR` error with the message `"No CDN to request"` when the RxPlayer is trying to request its first segment.

---

This happens because since the RxPlayer v3.29.0, we try to identify one or multiple CDN through which segments may be requested. This is done at the `<Representation>` level.

Under the specific conditions written earlier, MPD parsers will indicate an empty array as the CDN that can be used to reach that Representation's segments, because it has no way of defining even one root URL.
In the corresponding `Manifest`'s structure documentation (the protocol-agnostic structure defined by the RxPlayer for a Manifest), an empty array is then documented as `An empty array means that no CDN are left to request the resource. As such, no resource can be loaded in that situation.`.

So an empty array is for explicitly telling that the segment should be reachable through a potential CDN, but that no CDN is usable, at least right now.
That's why the  `"No CDN to request"` error was sent: the logic performing segment requests just wanted to load a segment, but saw that right now no CDN can be requested for it.

To fix this situation, we could set that value to `null`, which exists, instead of an empty array. But this is how a `null` value is defined in the same `Manifest` structure: `null if there's no CDN involved here (e.g. resources are not requested through the network).`
In that specific issue, the segment may perfectly be reachable through the network, we just don't know the root URL. We also risk breaking functional use cases if a full URL was actually declared for each segment.

I thus hesitated between redefining the empty array and not throw in that case, redefining `null`, or to invent a third special case.
For now, I chose to explicitly allow a new way of telling that an URL may exist, but should be entirely associated to each segment: by setting the empty string instead.

This basically technically indicates - by following the logic already there - that all following URL are either absolute or relative to the page doing the requests, so it may imply a new strange behavior here when only relative segment URL are present (resulting in the browser considering the current page as the root URL), but I don't know how we should realistically act anyway in that specific case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants