[Enhancement] UPnP/DLNA Media Renderer Plugin: use HTTP/1.1 and always proxy thru LMS - #1615
Conversation
f74c2d2 to
f49a07d
Compare
f49a07d to
5cf54e3
Compare
|
@michaelherger Thanks for your input. Now, the change is strictly local to the Media renderer Plugin. |
|
Note: I'm currently only testing against pa-dlna. While this change addresses the primary issues of missing HTTP/1.1 chunked-transfer encoding support and the direct-streaming-related difference in connect source IP, there is at least another issue that may be harder to solve: By default, pa-dlna sends SetAVTransportURI messages on track changes to update track metadata and trigger a "re-connect". This currently causes the connection to break, because the Squeezebox' delayed reaction on this doesn't work well together with pa-dlna's internal connection handling. |
michaelherger
left a comment
There was a problem hiding this comment.
I understand this is to be able to stream from pa-dlna to a Squeezebox? I neither have any decent experience with the UPnP plugin (user or developer), nor with this level of networking code changes 😖. I must admit that I don't care too much about UPnP/DLNA, as I believe this addition to LMS really was a rushed thing to satisfy one specific commercial product requirement many, many years back. And it's never been a popular feature. Maybe I'm wrong.
Therefore I'd have to rely on you to put some extra effort into testing these changes. Could you please pick up some of the more popular choices (I'm not familiar with, but Google suggested eg. BubbleUPnP, Serviio, Minimserver) and give them a quick run-through?
I would also be happy if @philippe44 could give the _sysread a quick review, as he's the guy who introduced the canEnhanceHTTP mechanism.
|
I too am very interested in being able to stream to LMS from a DLNA server. I also tried and failed to use I'm travelling and away from my LMS server for another couple of weeks, but I look forward to testing this once I'm home. Would love to see this get fixed -- thanks to you both, and especially @stsichler for working on this :) |
Results of my tests:
AI-based effort estimate to get LPCM working: "Low to medium, no fundamental architectural issue – the infrastructure (proxy streaming, chunked-dechunking, sink protocol advertising) is already in place. Essentially, the following would be required: ... But that would be the subject of a different pull request. ;-) |
@simonwiles You're welcome! In order to get the Squeezeboxes properly working with pa-dlna, it is currently also required to switch off sending of track-metadata in pa-dlna, because pa-dlna re-uses the same media URI from track to track. This is incompatible with the way the Squeezeboxes handle track changes and causes the connection to break on a track change. Until then, it is necessary to switch that off, e.g. by using a config file |
…e proxy Some DLNA servers require the source connection to originate from the same IP address that was published for the player via UPnP. So, force the UPnP/DLNA MediaRenderer protocol handler to always use the server-side proxy path (canDirectStream => 0). Also change the request header to HTTP/1.1, allowing for the DLNA server to use chunked transfer-encoding and add support for translating it back to a contiguous raw data stream in _sysread(). Since canDirectStream is forced off, this handler's requestString(), response() and _sysread() are only ever exercised by the server's own outgoing connection to the source, never by player firmware, so they can safely be overridden per-plugin to add HTTP/1.1 + chunked support without touching Slim::Player::Protocols::HTTP: - requestString() rewrites the request line's protocol token to HTTP/1.1, leaving every other header untouched. - response() applies the same rewrite to the request string before delegating to the base class, so the HTTP::Request object kept for the persistent/reconnect session (if canEnhanceHTTP is set) also reports HTTP/1.1, and it arms a small dechunking state machine when the response header shows "Transfer-Encoding: chunked". - _sysread() transparently strips the chunk framing from the raw byte stream before it reaches the audio decoder, so DLNA sources that only offer chunked responses (no Content-Length) can be streamed correctly. The player-firmware-facing direct-stream request builder in Slim::Player::Protocols::HTTP is untouched and still defaults to HTTP/1.0, so no firmware changes are required. *note: this commit and message is created with the help of AI* Signed-off-by: Stefan Sichler <stsichler@web.de>
5cf54e3 to
fb070df
Compare
michaelherger
left a comment
There was a problem hiding this comment.
Now this looks "local" enough. Let's give it a try. Thanks!
|
Nice! |
This is a follow-up of my comment to #1121.
Testing inter-operation with pa-dlna revealed that LMS's UPnP/DLNA Media Renderer Plugin needs an update to support HTTP/1.1 with chunked transfer encoding to be compatible to up-to-date DLNA Streaming Servers like pa-dlna.
In order to limit the changes required to LMS's DLNA plugin itself and not requiring any changes to Squeezebox Device Firmwares, this implies to also disable direct streaming for DLNA streams in general, meaning always routing the data through LMS and do the translation from HTTP/1.1 chunked transfers to raw HTTP/1.0 there.
Currently, direct streaming is only used when streaming to a single Squeezebox (not a synchronized group).
This PR addresses this.
Note: this PR is generated with the help of AI, since I'm not capable of Perl and I know too little about LMS' internal structures, so please carefully review the code.
In my local tests, this PR seems to work correctly.
I have tested: pa-dlna as server, a single Squeezebox as renderer, a synchronized group of Squeezeboxes as renderer.