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 playback on network streamer initiated from streamer app's (control point) #4256

Open
ik666 opened this issue Nov 20, 2023 · 9 comments
Open

Comments

@ik666
Copy link
Contributor

ik666 commented Nov 20, 2023

I've discovered a playback issue: If you browse UMS with a streamer app (usually UPnP control point) and want to play a selected resource on a network streamer (renderer) this fails.

Here's a small trace log. Looks like the resource the control point get's cannot played back by the renderer ...

I've tested with LUMIN app and LINN app having same results. None of them play anything.

TRACE 2023-11-18 10:18:07.275 [jupnp-netty-worker 4] Stripping preceding slash from: /ums/9561e873-6f5e-3b5b-a46d-3e1085902145/thumbnail/1696/JPEG_SM_18+-+Our+Darkness.flac.jpg
TRACE 2023-11-18 10:18:07.275 [jupnp-netty-worker 4] Matched media renderer "BubbleUPnP" based on address 192.168.114.171
TRACE 2023-11-18 10:18:07.275 [jupnp-netty-worker 4] Received a request from BubbleUPnP (192.168.114.171:56044):
================================== HTTPSERVER REQUEST BEGIN =====================================
GET /ums/9561e873-6f5e-3b5b-a46d-3e1085902145/thumbnail/1696/JPEG_SM_18+-+Our+Darkness.flac.jpg HTTP/1.1

HEADER:
  Host: 192.168.112.5:5001
  Accept: */*
  Accept-Language: de-DE,de;q=0.9
  Connection: keep-alive
  Accept-Encoding: gzip, deflate
  User-Agent: Linn/4.6.9.1 CFNetwork/1485 Darwin/23.1.0
================================== HTTPSERVER REQUEST END =======================================
Renderer UUID=9561e873-6f5e-3b5b-a46d-3e1085902145
TRACE 2023-11-18 10:18:07.275 [jupnp-netty-worker 2] Received a request from BubbleUPnP (192.168.114.171:56043):
================================== HTTPSERVER REQUEST BEGIN =====================================
GET /ums/9561e873-6f5e-3b5b-a46d-3e1085902145/thumbnail/1695/JPEG_SM_25+-+Our+Darkness.flac.jpg HTTP/1.1

[...]

TRACE 2023-11-18 10:18:43.975 [jupnp-netty-worker 4] Stripping preceding slash from: /ums/9561e873-6f5e-3b5b-a46d-3e1085902145/media/1695/25+-+Our+Darkness.flac
TRACE 2023-11-18 10:18:43.976 [jupnp-netty-worker 4] Matched media renderer "Wohnzimmer:LUMIN" based on address 192.168.112.31
TRACE 2023-11-18 10:18:43.976 [jupnp-netty-worker 4] Recognized media renderer "Wohnzimmer:LUMIN" is not matching UUID "9561e873-6f5e-3b5b-a46d-3e1085902145"

Edit : LUMIN is the network streamer (renderer), LINN is the iOS app (control point).

@SurfaceS
Copy link
Contributor

UMS itself is the UPnP Control Point.
That's why it adapt the MediaServer CDS to registred MediaRenderer, transcode if needed, and so on.

What I understood is that BubbleUPnP was registered as a MediaRenderer (9561e873-6f5e-3b5b-a46d-3e1085902145) that try to act as another UPnP Control Point to give an url created for itself to Wohnzimmer:LUMIN (another MediaRenderer).

It could not work like this.

For security purpose (access rights), transcoding engines, etc, the server will check that the asked url was from the MediaRenderer advertised.

@ik666
Copy link
Contributor Author

ik666 commented Nov 22, 2023

The setup is slightly different.

If you buy audio devices streamer like LINN, LUMIN, Naim, they are being controlled by their own control point APPs running on Android or iOS.

After starting the manufacturer's app, UMS show's up and can be selected as a media server device.
You can then browse or search the CDS. In UMS <14 you could also listen to songs. This doesn't work in current v14 branch.

The manufacturer network streamer (renderer) and their app (control point) do not share the same UUID (by design). The APP sends the URL from the <res> field to the renderer to play the resource. Looks like this fails, because the renderer has a different UUID.

Edit: I think UMS selects the BubbleUPnP profile, because there is no LINN-APP profile available yet. They look compatible so far, since I don't have any playback/transcoding issues with this profile in v13.

@SurfaceS
Copy link
Contributor

#4259

@ik666
Copy link
Contributor Author

ik666 commented Nov 23, 2023

I believe, this will not do it and I'm not sure, if we talk about the same thing. There is no "proxy CDS" on the network. It's more the standard UPnP setup described in UPnP-av-AVArchitecture, section 3 playback. The actual setup is according to the official UPnP tutorial page 37 a 2-3 box interactions model.

The mentioned apps (Control Points) follow the workflow described in UPnP-av-AVArchitecture section 3.3:

3.3. Control Point
Control Points coordinate the operation of the MediaServer and the MediaRenderer, usually in response to
user interaction with the Control Point’s UI. A Control Point is not a UPnP device, e.g. it is not visible as a
device on the network, since it does not provide any UPnP services. Conversely, the Control Point invokes
services on other UPnP devices in order to trigger some desired behavior of the remote device.
The following describes a generic Control Point algorithm that can be used to interact with a wide variety
of MediaServer and MediaRenderer implementations.
[STEP 1 to 10]

upnp_37

The reason why UMS has a control point is because UMS integrates all UPnP services (Media Server, Media Renderer and Control Point) in one piece of software, which usually reside on different devices, making UMS to a "1-box interactions" model. This is a very "special" setup.

If I quote the UMS webpage:

Universal Media Server is a free DLNA, UPnP and HTTP/S Media Server.

I agree with this claim. From my point of view the MediaServer CDS service is the core UMS service. If the MediaServer CDS services become UPnP non compliant, we probably lose a lot of people on the way. At least all people using control points in the 2-3 box interactions setup like manufacturer apps or popular apps like

I think there is a simple quick fix solution: If authorization is disabled, the "authorization check" should not be done. Then all control point start working again.

Another solution would be to implement authorization UPnP compliant via DeviceProtection services as described in UPnP CDS service v4:

5.2.25 Device Protection Option
The ContentDirectory service does not include any mechanism to restrict access to service actions/content based on Roles, Control Point Identities or User Identities. Due to this openness, content and services on MediaServers can be accessed by all control points/users in the UPnP network. This leads to violation of content privacy in MediaServers. Implementation of the ContentDirectory service CONTENT_PROTECTION feature addresses these limitations.
When a DeviceProtection service [36] is available on a device implementing a ContentDirectory service then a CONTENT_PROTECTION feature (see Annex F.10 and Annex G) can also be implemented. When implemented, specific actions and specific content can be restricted from specific control points. In other words, control points which are now identifiable to the service can be assigned specific permissions, that is the right to invoke an action on a per action basis (see Action level access) or per object (container or item) basis (see Object level access). In general, control points can be identified on an unrecognized (Public) or recognized (Control Point Identity or User Identity) basis. In each case, one or more Role(s) can be assigned to a Control Point Identity or User Identity. For control points that do not implement DeviceProtection or remain unregistered, a generic Role of (Public) is automatically assigned. Additional description of these and related terms can be found in the DeviceProtection service. Familiarization with these terms is encouraged.

@ik666 ik666 reopened this Nov 23, 2023
@SurfaceS
Copy link
Contributor

The fix doesn't work ?

It should allow Media Renderer to play the URL provided by the proxy control point (aka not running in the same device / in between Server and Renderer).

Implementation of the ContentDirectory service CONTENT_PROTECTION feature addresses these limitations.

Fill free to implement it (on the next version, as we are running out of time on this one).

Just remember CONTENT_PROTECTION is only on aspect of the "renderer" UMS point of view.
You also have transcoding for a specific renderer, playing status for a specific user, and so on.
It is not as easy.

@ik666
Copy link
Contributor Author

ik666 commented Nov 23, 2023

The fix doesn't work ?

Hmm, I'll check back if the fix works. Maybe I'd had a build issue jumping between branches. I'll close this if it works.

Fill free to implement it (on the next version, as we are running out of time on this one).

Actually, I have no personal ambitions on this feature, but more on getting "audio features" done. Just wanted to point out a UPnP like solution.

@ik666
Copy link
Contributor Author

ik666 commented Nov 24, 2023

@SurfaceS Playback on my renderer device still doesn't work yet. I'll check if I can do some debugging.

One side note: From a design point of view, identifying control points as renderer makes only in a "2 box interaction" sense, where the control point and the render lay on the same device (usually a TV).

One common "3 box interaction" use case is that a control point user can decide on which device a resource should be played. In example, I have 2 renderer devices at home. One is a Yamaha AV receiver, one is a LINN audio network player. I use the LINN app (Control Point) installed on my iPad for playing songs (on both renderer devices). The app is configured to use UMS as a media server (CDS service). While I do the browsing/searching, it's unknown to UMS on which renderer I'll finally play a resource (song). The LINN renderer has more native playback capabilities as the Yamaha. Therefore, it's undecidable in the browse/search phase (also for UMS) if a resource (song) has to be transcoded. UmsContentDirectoryService is actually not identifying a renderer, because renderer do no browsing/searching, but a control point that might be on the same device the renderer is (2 box interaction).

When the LINN app (control point) tells my renderer (Yamaha) to play a song, the resource URL provided by the previous browse/search is requested from UMS. The transcoding (yes / no) decision should be done here, since the renderer (LINN or Yamaha) can be identified (i.e. RequestV2.answer(...)).

I'm not sure how it's done yet, but would recommend to use the renderer discovered in the "resource request" phase as the right one in case the "renderer" does not match the "browsed renderer", since this is the real device.

@SurfaceS
Copy link
Contributor

You're right.
UMS is mixing CDS / control point / MediaServer (it is a control point by essence).

When the LINN app (control point) tells my renderer (Yamaha) to play a song, the resource URL provided by the previous browse/search is requested from UMS. The transcoding (yes / no) decision should be done here, since the renderer (LINN or Yamaha) can be identified (i.e. RequestV2.answer(...)).

One note on this is that the control point is responsible of giving a working URL (falling to a transcode URL if needed).
The media server (stream) should be a dumb device that take no decision.

For this, the CDS need to advise multiple with correct info on it, what is not the case for now.

On this PR, I had separated CDS from MediaServer (was mixed).
That's a first step.

@ik666
Copy link
Contributor Author

ik666 commented Nov 27, 2023

One note on this is that the control point is responsible of giving a working URL (falling to a transcode URL if needed).
The media server (stream) should be a dumb device that take no decision.

For this, the CDS need to advise multiple with correct info on it, what is not the case for now.

Yeah agree, to bad though in most cases Media Renderer are also dump devices, not even able to provide correct ProtocolInfo. I think UMS has two smart solution for that:

  1. providing a "transcode" folder so the user can do the decision instead of the control point.
  2. The Media Server (stream) identifies the render and does the conversion according to the renderer custom provided config file.

Step 2 could be optimized in the future to do the transcoding only on the Media Server part on the fly (by renderer config file), if possible. This would probably be a 3 box interactions support.

On this PR, I had separated CDS from MediaServer (was mixed).
That's a first step.

@SurfaceS I tell you. I was so pleased to see finally someone moving the software to a cleaner design, and stable objectIDs. I personally think: that is great work, done with probably a huge amount of personal effort. 👍 ❤️

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

No branches or pull requests

2 participants