CustomSD service not able to play tracks - sonos

I’m currently developing a music service and testing it via customsd. The integration in the controller app is working (iOS App & Windows Desktop App) - so I can browse - but I can’t get a Player to play any track. I keep receiving ‘unable to connect’ errors once I hit the ‘Play’ button in the controller. I can see on the service side that the Player sends a getMetadata and a getMediaURI request, and the SOAP responses delivered by the service are identical to working examples from another source; however, the Player seems unable to process them. I am kind of stuck, and I guess what would help me are the Player logs. Is there any way to get them?
Or, does anyone have any other idea about the root cause of the issue?
EDIT: More or less accidentally, I came across the reason of my problem. Whereas in general, Sonos can handle arbitrary IDs, getMediaURI only seems to work when it requests the URI for an ID of the form track:something. I don‘t remember seeing this as a requirement on the developer pages.
Anyway, got it working now.

If you're getting a getMediaURI request and responding to it with a valid response, then most likely the player is failing to process the media file itself. Are you seeing the media file being downloaded? You could host the media file locally and include the URI to that in the getMediaURI response to check.
Note that the <mimeType> included in the metadata is used to inform the player of the type of media the URI in the getMediaURL response points to.
So if you were to return <mimeType>audio/ogg</mimeType> for track123, but getMediaURI's response contained the URI https://something.xyz/track123.mp3, playback would likely fail due to the mismatch.

Have you seen bonob? Someone made a music service emulator for navidrome (self-hosted music library, a la spotify). It should be a great resource to get you started.
He wrote that your music service has to be available at https for it to even start functioning.
Note, I'm the developer of sonos-ts a library to control sonos speakers from typescript and node. And the external music services are documented here

Related

How to obtain list of Music Sources from the Sonos household?

I am trying to get a list of music services to which the Sonos household has a subscription. Is it possible to obtain such information from HTTP API or from any other source? If yes, then under what conditions?
I have analyzed the traffic between the Sonos Connect and Windows Sonos Controller. I discover, that information about music services is transmitted from Connect to Controller inside the ThirdPartyMediaServersX tag of the NOTIFY HTTP request. But this content is encoded in the base64-like cipher.
<e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
<e:property>
<ThirdPartyMediaServersX>
2:oZoYgaU5pqEq6IauQ1hYVS0oCUJnqbCkJL1vXP/DoeijejEwUBQT8UG0CksUG9VcarvLhCyElhKTUjfhQt0SAcV2oBOyLJ5BCmjd7TcJfPrVuTGHczd5/AS2tgj85n0U9yU9EwwHROFb5uV09syZNLVaZuJnENCWRKatIq1SNMm1SE4tHneLG6ULQoDOR50nf7TwyRQbkit8Bvy+kZyNPlrgBZFGmizoRmYjW8COFvHJpZhREEGruhQ2J6A8gnQOWyFzstAyHNZeLqp2xcNGnts6f2DQ56r/ducstbibFH0SZOZC0XM/BB4DvOT8UalezPL0R9/s8Jibm5T6mS1FWk14GWg2RMmRBIVE5G/gG2c=
</ThirdPartyMediaServersX>
</e:property>
</e:propertyset>
I expect to obtain list of music services, but the actual list were hidden.
As you figured out, Sonos disabled this functionality some time ago.
I've spend a lot of time figuring out how it works, and I now have a "work-a-round". External music services describes what to do.
And sonos-ts has support for external music services. If you read my first link and check the code in this library you should probably be able to figure out how to do that in your programming language.
I know this is no access to the list that is kept by Sonos, but this work-a-round also saves the tokens on the device for every client application to use.
Recently I've found someone who build an music service emulator. So that are both sides of external music services.
This is not supported by the Sonos API.

Google API blocked my app ip address and returns CAPTCHA

My app uses Google API and it worked well for a long time but recently Google blocked the IP address of my server for about an hour and every response to the API was as follows: Our systems have detected unusual traffic from your computer network. This page checks to see if it's really you sending the requests, and not a robot... - they attached CAPTCHA form field as html.
My app is also an API so CAPTCHA can not be done because it is in json format (HTML in json cannot be rendered).
Only app users sends requests so I have a little control over it. Of course, I limit the number of requests per user, but it was not the case. Limits at google console are also fine.
I wonder how can I prevent this happening in the future? Is there any way I can ask them directly? Have you experienced this?

How do you detect changes in a user's Spotify playlist?

Scenario: Spotify user on the native desktop application is adding and removing songs from the currently playing playlist.
I'm curious if it's possible for me to detect when any addition/removal happens? Basically need a trigger to tell me the playlist has changed without having to continuously poll Spotify's API to see if anything changed. Looking for a solution that could be used either via the Spotify API or something hack-ish using spotilocal or listening on Spotify's 4070 port.
Looking for a solution that could be used either via the Spotify API
or something hack-ish using spotilocal or listening on Spotify's 4070
port.
I wouldn't recommend this approach since the mentioned APIs may change without notice. It's not publicly supported so there's no commitment from Spotify to avoid breaking changes. It also requires the user to have the Spotify desktop application installed.
As you've noticed, since there's currently no way to subscribe to changes in a playlist, e.g. by a Websocket or HTTP PubSub interface like PubSubHubbub, your application would be forced to poll for changes. If you go down this path, I strongly recommend that you make use of the ETags and snapshot_id provided in the Playlist response.
Declaring how ETags are implemented in the Web API deserves a longer response and should be on the developer site. There's however a useful Working With Playlists guide on there that explains snapshots and some other things related to playlists.
It's also worth mentioning that all applications are rate limited, so I urge anyone polling to be aware of this and poll less rather than more. Obviously only poll when the application is actively used by the user, and only poll the playlist if it's actively viewed. You know you're being rate limited if you retrieve a 429 Too Many Requests response.

Soundcloud API Download

I am asking this here because Soundcloud does not have support. I going to build a website that people can purchase audio files from using Soundcloud to download the files (and stream before buy). I want to be able to access the download file link in the Soundcloud API without the download link being enabled and showing on the Soundcloud UI. I can't seem to find this info in the Soundcloud API docs. I am going to have a Paypal redirect after the payment to the download link. I know this is a weird way of doing this but I have certain criteria I have to meet. I would host the audio files on my server but they are huge. Anyone have experience with this or can help?
im not sure its possible to do what you want. (very easily at least)
there would be no way for the purchaser to access the 'download' track on soundcloud directly unless downloads are specifically enabled for that track.
really the only way to not host the files and still be able to provide the download would be to use the api to download or proxy the track from soundcloud to your server, using your credentials (because you always have access to your own tracks, download or stream). mind you this would use 2x the bandwidth usage (the server getting the track from soundcloud, and the client downloading the track), and storage space would only be impacked on a temporary bases. but. this is a pretty hacky way and not really a good/proper solution.
you can:
-compress/re-encode the audio as to not use as much disk space
-pay for more storage space at your web host, its usually pretty cheap thse days.
So you want to charge on something free? Well, I think all the downloader out there are middleware where they stream the track from soundcloud and response to client as attachment upon request, one of many examples is http://wittysound.com. Cheapest way to get thing done is providing direct link to soundcloud server like what http://soundflush.com does

Communication between a Mac app & local website/server

I want to control a mac app via a local website. I think the best way is to create a webserver with my mac app and then to send (primarily) integer values from the website and vice versa.
I found already CocoaHTTPServer, but I'm not sure how to do it.
For start with I want to have a slider on the website, that updates a slider in my mac application (and vice versa)
You will initiate on a separate thread or operation the web server and always wait for incoming requests. Whenever you receive a request you will handle it accordingly.
Also, if you are using this: https://github.com/robbiehanson/CocoaHTTPServer/
then there are a few examples that show how to do it. Copy the code from there to begin with the web server handling requests. After that, think through what you want to send and what you want to do. Build a form or something for the web site and submit a request to the web server.
CocoaHTTPServer will let you embed the web server into your application, which is a fine solution for what you're trying to accomplish.
Some thoughts on how to engineer it:
You'll need to subclass HTTPConnection.
Model your solution on the PostHTTPServer example.
You could get the data you want to send into the URL. Something like POST http://localhost:12345/updateSlider/123. (You probably don't need an actual POST, but no reason it wouldn't work. Technically a PUT would be more correct.)
Start by handling that part – where the browser sends a value to your application. To generate POST/PUT requests for testing purposes, use curl, or else build a static page and open it in your browser.
When you get that working, then worry about presenting a web page to the user.