Closed trilame closed 7 months ago
Thanks for the thank you 😄
Now, to your issue... well, UPnP is probably the biggest cluster f... you can ever see in term of standardization and lack of compliance and most company do whatever they do, especially device vendors who think that software happens magically (end of rant).
What you likely experience is something that I've seen a few times with faulty devices: UPnP uses HTTP to grab the audio data doing a classical "GET". Now, in HTTP if you know the content length of your file, you can put it in your answer, but it's optional and you might not know it. In fact, HTTP 1.1 has a special mode to handle unknown length (chunked-encoding). In my case, because I recode the audio, I don't know in advance the length so I'm silent about it.
Now, not knowing length might also means it is a live stream and UPnP adds special flags in addition to HTTP to inform the player of what it is receiving. The reason (yes, I'm getting there) is that pausing alive stream might not make sense and this let players decide if they want to allow that or not.
Now, when you combine these options together, many players are a mess and can't handle these properly. They think that no content length means live and don't pause. That does not mean that I don't have bugs or I missed something in my own app, but from experience the lack of pause is often a player issue.
So you can try different things.
1- change HTTP modes between -3, -2, -1 or 0. Try -3 first (chunked encoding). Then try 0 where I will always add a length, even if it is fake. It sometimes works. -2 adds length if known and -1 never adds length, so these are not for you
2- play with these DLNA flags that express server's capabilities and sometimes this makes the difference. You can have your own in the xml config file you'd create. The syntax is the following
/* DLNA.ORG_FLAGS, padded with 24 trailing 0s
* 8000 0000 31 senderPaced
* 4000 0000 30 lsopTimeBasedSeekSupported
* 2000 0000 29 lsopByteBasedSeekSupported
* 1000 0000 28 playcontainerSupported
* 800 0000 27 s0IncreasingSupported
* 400 0000 26 sNIncreasingSupported
* 200 0000 25 rtspPauseSupported
* 100 0000 24 streamingTransferModeSupported
* 80 0000 23 interactiveTransferModeSupported
* 40 0000 22 backgroundTransferModeSupported
* 20 0000 21 connectionStallingSupported
* 10 0000 20 dlnaVersion15Supported
*
* Example: (1 << 24) | (1 << 22) | (1 << 21) | (1 << 20)
* DLNA.ORG_FLAGS=0170 0000[0000 0000 0000 0000 0000 0000] // [] show padding
*/
There is the "flow" version and the regular version, I assume you don' t use flow mode. To better understand these, Google and ChatGPT are your friends. I'm sorry I can't tell you more, but it's really a jungle here. Now, if you can make it work, I'd be interested because it gives me opportunity to figure out either my own mistakes or find a better compatibility.
Just you can see that in the "flow" mode, I use "c7..." which means I set that the beginning of the stream and end of the stream are moving which means a live stream (flow is a single continuing stream for all tracks). In regular (non-flow) mode, I'm not setting these bits "17..." so the player should know that the stream can be paused... Especially, you can remove the "streamingTransferModeSupported" flags (set value to 07...) to see what happens (although your player explicitly asks for streaming, so we'll see).
Thanks for the detailed reply, I'm learning a lot here!
I've tried the following and would like to share with you, in order to ensure that I ran the right commands/config file updates:
./spotupnp-macos -g -3
./spotupnp-macos -g 0
./spotupnp-macos -g -2
But unfortunately I got the same results, pause takes some time to be effective (still around 30 seconds).
I also tried through the config file as I wasn't sure of my previous commands:
./spotupnp-macos -i config.xml
to generate a new config filehttp_content_length
to -3, 0 and -2, but still no success. For example, <http_content_length>-2</http_content_length>
A comment on this one: in your readme, you mention <http_length>
but in the default config.xml, I found </http_content_length>
. I suppose the one from the config.xml is the right one?
I will now look at playing with those flags, but this is totally new for me, I'm not familiar with C++.
You mentioned the flow mode, I kept the default value in the config file, <flow>0</flow>
Yes, indeed I corrected the README. Regarding changing the flag, you don't need to worry about C/C++, just binary / hexadecimal encoding.
Hello Philippe44, I spent some time on this and start to get the concept.
However, I'm not sure to get what you mean with trying to remove streamingTransferModeSupported.
In both default values we have in config.xml default file:
`
No, you have the example above
* Example: (1 << 24) | (1 << 22) | (1 << 21) | (1 << 20)
* DLNA.ORG_FLAGS=0170 0000[0000 0000 0000 0000 0000 0000] // [] show padding
You can concentrate on the 0170 0000 number which is a 32 bits hexadecimal and represent bits 31 to 0, and each digit is 4 bits,
0 = 0000 = b31..b28 1 = 0001 = b27..b24 = streamingTransferMode supported 7 = 0111 = b23..b20 = backgroundTransferModeSupported, connectionStallingSupported, dlnaVersion15Supported 0 = 0000 = b19..b16
(we don't care about the rest)
Ok thanks. Now I got it :)
I tried the followings. First one is the suggested, so removing streamingTransferModeSupported.
<DLNA_FLAGS>00700000000000000000000000000000</DLNA_FLAGS>
<DLNA_FLAGS>FFF00000000000000000000000000000</DLNA_FLAGS>
<DLNA_FLAGS>00000000000000000000000000000000</DLNA_FLAGS>
In the 3 tests, results are the same as before (everything works well except pause). I will keep doing some others.
Just in case, my config file looks like:
<?xml version="1.0"?>
<spotupnp>
<common>
<protocolInfo>
<pcm>http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=%s;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=%s</pcm>
<wav>http-get:*:audio/wav:DLNA.ORG_OP=%s;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=%s</wav>
<flac>http-get:*:audio/flac:DLNA.ORG_OP=%s;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=%s</flac>
<mp3>http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=%s;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=%s</mp3>
<DLNA_OP>01</DLNA_OP>
<DLNA_FLAGS>00700000000000000000000000000000</DLNA_FLAGS>
<DLNA_OP_flow>00</DLNA_OP_flow>
<DLNA_FLAGS_flow>0c700000000000000000000000000000</DLNA_FLAGS_flow>
</protocolInfo>
<enabled>1</enabled>
<max_volume>100</max_volume>
<http_content_length>-1</http_content_length>
<upnp_max>1</upnp_max>
<codec>flac</codec>
<vorbis_rate>160</vorbis_rate>
<flow>0</flow>
<gapless>1</gapless>
<artwork></artwork>
</common>
<main_log>info</main_log>
<upnp_log>info</upnp_log>
<util_log>warn</util_log>
<log_limit>-1</log_limit>
<max_players>32</max_players>
<interface>?</interface>
<credentials_path></credentials_path>
<credentials>0</credentials>
<ports>0:0</ports>
<device>
<udn>uuid:211a5de6-5f80-4b6b-9923-b91039fd12ae</udn>
<credentials></credentials>
<name>Samsung AU8005 43 TV+</name>
<mac>bb:bb:3d:ef:0a:ca</mac>
<enabled>0</enabled>
</device>
<device>
<udn>uuid:5f9ec1b3-ed59-1900-4530-9c645e01d9bd</udn>
<credentials></credentials>
<name>JBL OnBeat Air01D9BD+</name>
<mac>bb:bb:5e:01:d9:bd</mac>
<enabled>1</enabled>
</device>
<device>
<udn>uuid:92f32e53-f430-bf1d-1fcc-74eb2046f1b3</udn>
<credentials></credentials>
<name>Sound+</name>
<mac>bb:bb:d2:da:1a:da</mac>
<enabled>0</enabled>
</device>
</spotupnp>
And I run ./spotupnp-macos -x config.xml
Something else I just noticed, but I don't know if it is directly related to this issue: if I start a track, when it ends, the following track doesn't start. It stays at the end of the track just played. I tried from multiple Spotify apps (MacOS, iPhone).
Something else I just noticed, but I don't know if it is directly related to this issue: if I start a track, when it ends, the following track doesn't start. It stays at the end of the track just played. I tried from multiple Spotify apps (MacOS, iPhone).
This is a different issue. It's likely due to the capability of the player to go gapless. In the config file, set "gapless" to 0 to disable the use of the gapless feature. Some (many) players claim they can, but they don't.
BTW, with your other tests, it would be interesting to get the logs
Something else I just noticed, but I don't know if it is directly related to this issue: if I start a track, when it ends, the following track doesn't start. It stays at the end of the track just played. I tried from multiple Spotify apps (MacOS, iPhone).
This is a different issue. It's likely due to the capability of the player to go gapless. In the config file, set "gapless" to 0 to disable the use of the gapless feature. Some (many) players claim they can, but they don't.
Hello, I just tried but no success, the track ends and nothing happens:
```
```
[21:30:12.699] main:1546 Starting stopupnp version: v0.5.0 (Nov 10 2023 @ 17:47:26)
[21:30:12.702] Start:1259 Binding to iface en0@192.168.1.18:0
[21:30:12.702] Start:1273 Binding to 192.168.1.18:49152
[21:30:14.989] AddMRDevice:1185 [0x128028000]: adding renderer (JBL OnBeat Air01D9BD) with mac BBBBBDD9015E
[21:30:14.997] I BellHTTPServer.cpp:191: Server listening on port 0
[21:30:14.997] I spotify.cpp:556: ZeroConf mode (port 64197)
[21:30:15.001] MasterHandler:788 [0x128028000]: subscribe success
[21:30:15.025] ProcessEvent:515 [0x128028000]: UPnP Volume local change 22:-1 (master)
[21:30:39.479] I spotify.cpp:599: Spotify client launched for JBL OnBeat Air01D9BD+
[21:30:39.543] D Session.cpp:67: Connecting with AP
I will perform some tests and provide logs, with the DLNA flags.
It's a very strange log... Can you do me a favor and take a fresh log? Be very strict with the following
1- starts spotupnp 2- using a spotify controller (PC or smartphone), connect to one of the created player 3- playback should start immediately 4- don't do anything, touch anything on the controller. Let the track play and wait at least 30 s after track's end before exiting spotupnp. Do **notùù stop or pause spotify, nothing. Just type "exit" at the spotupnp prompt, it will exit the program (whether the log is on the screen or in a file) 5- post that log
I did run spotupnp-macos, without taking into account any config file (I hope that's what you meant).
Simply running ./spotupnp-macos
I'm sharing two outputs with you:
On the first try, I connect Spotify to the created player: on the Spotify interface, it shows it's connected and that the track plays, but no sound is coming out of the speaker. This happened multiple time during my other tests, but I also noticed it happened with a speaker I have at home, that has Spotify Connect integrated (and not using SpotConnect at all, it was before) _Edit: it seems I'm not alone_. If this happens, in both case (SpotConnect or not), I launch another track and it works immediately. Anyway, on this try, I did nothing else (so, no sound), let the track finish (as I could see on the interface), waited at least 30 seconds, and typed exit. Here is the log:
```
[23:19:08.987] main:1546 Starting stopupnp version: v0.5.0 (Nov 10 2023 @ 17:47:26)
[23:19:08.988] main:1553 no config file, using defaults
[23:19:08.988] Start:1259 Binding to iface en0@192.168.1.18:0
[23:19:08.988] Start:1273 Binding to 192.168.1.18:49152
[23:19:10.335] AddMRDevice:1185 [0x148008000]: adding renderer (Cat Sound) with mac BBBBDA1ADAD2
[23:19:10.344] I BellHTTPServer.cpp:191: Server listening on port 0
[23:19:10.344] I spotify.cpp:556: ZeroConf mode (port 57366)
[23:19:10.356] MasterHandler:788 [0x148008000]: subscribe success
[23:19:13.272] AddMRDevice:1185 [0x14800b0f0]: adding renderer (JBL OnBeat Air01D9BD) with mac BBBBBDD9015E
[23:19:13.280] I BellHTTPServer.cpp:191: Server listening on port 0
[23:19:13.280] I spotify.cpp:556: ZeroConf mode (port 57372)
[23:19:13.282] MasterHandler:788 [0x14800b0f0]: subscribe success
[23:19:13.303] ProcessEvent:515 [0x14800b0f0]: UPnP Volume local change 22:-1 (master)
[23:19:31.345] I spotify.cpp:599: Spotify client launched for JBL OnBeat Air01D9BD+
[23:19:31.394] D Session.cpp:67: Connecting with AP
On a second try, I did the same and the previously mentioned "bug" did not occur, the speaker was immediately playing as expected. I also waited for the end of the track, plus 30 seconds, and typed exit. Here is the log:
```
[23:23:36.277] main:1546 Starting stopupnp version: v0.5.0 (Nov 10 2023 @ 17:47:26)
[23:23:36.278] main:1553 no config file, using defaults
[23:23:36.279] Start:1259 Binding to iface en0@192.168.1.18:0
[23:23:36.279] Start:1273 Binding to 192.168.1.18:49152
[23:23:37.077] AddMRDevice:1185 [0x120008000]: adding renderer (JBL OnBeat Air01D9BD) with mac BBBBBDD9015E
[23:23:37.088] I BellHTTPServer.cpp:191: Server listening on port 0
[23:23:37.088] I spotify.cpp:556: ZeroConf mode (port 57504)
[23:23:37.091] MasterHandler:788 [0x120008000]: subscribe success
[23:23:37.144] ProcessEvent:515 [0x120008000]: UPnP Volume local change 22:-1 (master)
[23:23:47.857] I spotify.cpp:599: Spotify client launched for JBL OnBeat Air01D9BD+
[23:23:47.916] D Session.cpp:67: Connecting with AP
I hope it helps, let me know if I need to do other tests or differently!
The second log is clear, thanks. So, is the JBL device that guy https://www.pcmag.com/reviews/jbl-onbeat-air? If it is, it's funny because I have one and it has been causing me troubles forever, it was one of my first UPnP "fights".
If you look at the UPnP protocol, controller set the URI where to grab the audio, then send a "PLAY" command. Players have a status request command where they can be mainly PLAYING, PAUSED, STOPPED and ... TRANSITIONING. The last one means "I'm busy, but ask me later and I'll tell you where I am". My UPnP clients wait to detect the "PLAYING" state before moving one, and in our case, sending the next track. That JBL device enters "transitioning" state when you ask it to play and ... never exits it. I've never figured out why but I confirmed that other UPnP controller had the same issue, they are able to play one track and then stopped because that JBL never "plays".
Now, you might have some luck because I created a mode named "flow" in spotupnp where all the spotify tracks are sent as a single stream, like a webradio. There are some pros and cons and it's a pretty difficult mode to implement when the Spotify controller uses pause and seeking, and I've not run test for that mode in a long while, but that might work for you. The player will never exit the "transition" mode.
Now, this issue likely explains why it refused to pause. As it never plays, it does not pause. I'll run some tests and report because I should have that player somewhere.
All right, found the speaker. So, the UPnP will not work, I remember why now. Even in flow mode, staying in "transitioning" mode is not enough. Now, because that JBL does AirPlay (and better than UPnP), you can still use it with my apps, you just have to use spotraop instead of spotupnp and it will work!
Now, because it's AirPlay and if you use Spotify from an iPhone (AFAIU), then why not using AirPlay natively?
Yes, that's the one!! Thanks again for the explanations. And I'm glad you found it back, you allowed me to avoid some tests ;)
You are right, I'm surrounded by Apple devices at home, I could use the AirPlay integrated with this JBL. The reason is that I do like Spotify Connect versus Airplay: with Airplay, I always have this 2-3 seconds delay (which is really annoying when I skip tracks for example), it stops the music if accidentally I there is something else on the phone (like a video on Twitter), etc. And overall, I like the Spotify Connect way of working.
So, my initial motivation was to give a new life to this old speaker and enjoy it more with Spotify Connect.
I will give a try with spotraop anyway. For the moment I'm stuck with the error is loading libcrypto in an unsafe way
but I will find out.
oh, yes that one issue with macOS... Use the -static version of spotraop-macos that I just added
Big thanks for the -static version. I just tried it, and so far everything works great!
There is still a little delay, but way shorter than with the regular AirPlay. So, it looks more convenient for my usage.
I will keep testing it and let you know if I find any other issue ;)
Apart from that, I noticed something else. For some reason, since I started all those tests, the highest volume of my JBL is lower than before. It's the case whether I use SpotConnect or not. Not sure why. Maybe I'll try to reset it.
Edit: not sure how I did it, but volume now came back to a normal behavior. I'm now enjoying spotraop, launched automatically, with the right config file! It's really what I was looking for in the end, so thanks a lot.
A big target for me would be to do this, but directly in the JBL... No idea how to do it, but if it supports AirPlay, why not hack it so it supports Spotify Connect...
Hello, I'm running SpotConnect, on MacOS 13.5.1, simply with the command
./spotupnp-macos
.It correctly discovers locally my player. I then go to another device (an iPhone) to launch Spotify, choose the player (JBL OnBeat Air01D9BD+) and starts playing. If I choose another track, it changes instantly.
But if I press pause on the device controlling Spotify (in my example, the iPhone), on the iPhone screen the state of the button is pause, but the music keeps playing on the JBL OnBeat Air01D9BD+. I do nothing and wait, for about 30 seconds, and it eventually pauses the music. If I press play again, it starts again directly.
Below is a log of such scenario. I'm not sure what's wrong: I also tried with the credentials (
./spotupnp-macos -x config.xml -j -I
), but the result is the same.Also taking the opportunity to say thank you for all the work!