Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Sonos support #165

Closed
Ch00k opened this issue Apr 11, 2020 · 24 comments
Closed

Sonos support #165

Ch00k opened this issue Apr 11, 2020 · 24 comments

Comments

@Ch00k
Copy link

Ch00k commented Apr 11, 2020

Is there a plan to support Sonos integration, like Subsonic does?

@deluan
Copy link
Member

deluan commented Apr 11, 2020

That would be great, but I don't have plans for that right now. Contributions are welcome :)

@patsaindon
Copy link

Sonos use Subsonic API to access the music library. Look at the link http://www.subsonic.org/pages/sonos.jsp.

@SteveDinn
Copy link

Sonos use Subsonic API to access the music library. Look at the link http://www.subsonic.org/pages/sonos.jsp.

I don't think that's what that link implies. I believe Subsonic is especially supporting Sonos speakers. Otherwise, the configuration would be on Sonos' end, not Subsonic's.

@deluan
Copy link
Member

deluan commented Sep 15, 2020

@SteveDinn , that's my understanding too, but I didn't spent too much time figuring this out yet.

@patsaindon
Copy link

@deluan You can find the info here. https://musicpartners.sonos.com/node/72

@JannesMeyer
Copy link

JannesMeyer commented Nov 20, 2020

I would be curious about this, too. On the Sonos devices you can register yourself as a "music service" which will be shown in the Sonos app.

The latest documentation is available here: https://developer.sonos.com/build/content-service-get-started/test-your-content-service/

To register the service you have to fill out a form on any of your Sonos devices: http://<ip>:1400/customsd.htm where <ip> is the IP address of one of your Sonos speakers. You only have to fill it out once. The settings automatically propagate to other speakers and to the app.

Subsonic automatically submit this form (HTTP POST) with the correct values to register itself, but sometimes you have to do it manually, as they mention in the docs: http://www.subsonic.org/pages/sonos.jsp

Of course, it's a different API from the Subsonic API, so it's probably a lot of work to implement.

@MoralCode
Copy link
Contributor

MoralCode commented Mar 24, 2021

would a library like https://github.com/ianr0bkny/go-sonos help make this easier? (documentation at https://pkg.go.dev/github.com/ianr0bkny/go-sonos and https://github.com/ianr0bkny/go-sonos/tree/master/examples). creator's profile seems inactive, but its got quite a few forks that might work

are there any docs going over Navidrome architecture that I could potentially look at to understand how something like this might be integrated with sonos?

@deluan
Copy link
Member

deluan commented Mar 25, 2021

Hey @MoralCode, we don't have any development specific documentation, but I'd be glad to answer any questions and provide any needed guidance over Discord.

@MoralCode
Copy link
Contributor

MoralCode commented Mar 25, 2021

To summarize from the discord conversation:

It seems like the consensus is that this fits in really well as part of a broader "playback services" milestone with other issues like #364 (jukebox), Alexa integration (from GSOC page), #682 (google home) .etc.

It also seems like the current working idea for the best way to implement this for all of the various external playback mechanisms is for the navidrome server to act as a kind of the main hub/controller for all playback to "external" sources (i.e. all the ones that arent going through a subsonic client). In this model the server would have one or more queues for the currently playing songs on each of the various external services (sonos/google home/whatever) and sends commands to these services/devices. Since the server is pretty much always online, this allows the server to instruct these devices to play the next song in the queue as the last one ends without the client device's presence being required to instruct it to do so (helpful in cases where the phone goes to sleep).

The jukebox aspect of this seems to have API support using the /rest/jukeboxControl endpoint, but it is meant to be used only for the jukebox (server's audio device). Since the subsonic UI controls playqueues in a different way, not using this API call, this functionality will likely need to be re-implemented in a similar way in Navidrome's UI/API. This could even allow ND to implement the MPD protocol, and leverage MPD clients

It seems as though alexa, Google home, Sonos, .etc all operate in a similar way in that theres some component that issues a command to the device to tell it to play a particular piece of media, and then the device itself requests the content directly from the server at the path identified by the url/identifier provided in the initial command

as it relates to sonos specfically:

In the sonos model/architecture, the controller is - i believe- anything that implements the sonos controller API. This controller essentially just tells sonos player to "play this stream", "pause" .etc. Examples of this include the sonos app, the soco-cli python package i was using for a previous sonos project.

Since there is a library (that I linked above) that might implement this controller API in go, the first order of business on this is figuring out how to create a stream/endpoint that is Sonos-friendly (in terms of required parameters, authentication, supported formats etc), and registering it in the device (using the internal form as per the Subsonic docs) so it can be played by a player when it receives the instruction from the controller.

here are some additional useful pages form the sonos developer docs with some diagrams on how things work:

the sonos reference page on the authorization API may be helpful in figuring out what to do in terms of auth, although in my experience with soco-clii was able to get an mp3 stream to play without having to provide any auth information to sonos so this may not be necessary and may depend on which of the sonos API's from that reference page are used

@MoralCode
Copy link
Contributor

MoralCode commented Mar 26, 2021

upon some further messing around testing, sonos is able to play an mp3 stream just by grabbing the stream URL from inspect element in the web UI, setting the format (see docs here) to mp3 and instructing the sonos to play that stream url using soco-cli.

It seems like this method only supports mp3, WMA,and AAC/HE-AAC (per the sonos supported formats list). This audio playback may also break if the auth information provided in the URL gets refreshed/reset.

I'm pretty confident that if Navidrome were to present/set itself up as a sonos music service (like subsonic does, presumably using the Sonos Music API) then that would most likely allow navidrome to be able to utilize the larger set of supported formats and avoid transcoding

looks like airsonic (another subsonic-like tool, written in java) seems to have gone through this already at airsonic/airsonic#1738 (docs here)

@legobuild
Copy link

While I can't offer any help, count me as another user interested in Sonos integration. I currently have home audio set up through several airport expresses and use Logitech Media Server to access my Navidrome library and serve it to different rooms. I'm considering migrating to Sonos and would look at access my library directly from the Sonos app.

@simojenki
Copy link

I wrote the following project -> https://github.com/simojenki/bonob to integrate sonos with navidrome via the subsonic api.
I don't have the bandwidth rewrite it in golang within navidrome itself, however if someone else would like to embark on that bonob would serve as a reasonable working example, there are plenty of tests that demonstrate how sonos -> 'service' integrate, and I'm happy to answer any questions based on my understanding of what needs to be done.

@deluan
Copy link
Member

deluan commented Apr 10, 2021

This is awesome @simojenki, thanks for sharing! This will be definitely helpful when implementing Sonos support!

@MoralCode
Copy link
Contributor

@simojenki wow this is awesome! I'll see if I can spend some time turning this into a standalone go library/module that could be used by Navidrome and other go apps

@legobuild
Copy link

This is great @simojenki. I was able to set up your project this afternoon with no issues. Navidrome serving up to my Sonos Five now. Still need playlist support, but so far this works great.

@simojenki
Copy link

@legobuild playing of playlists has been added (to bonob), so try now. Editing playlists will require some time as that is a different usage of the sonos smapi api.

@legobuild
Copy link

@legobuild playing of playlists has been added (to bonob), so try now. Editing playlists will require some time as that is a different usage of the sonos smapi api.

I just updated and it works perfectly. Thanks!

@deluan
Copy link
Member

deluan commented May 11, 2021

Thanks @simojenki It works like a charm! By the way, are you in our Discord? I have some questions regarding the implementation. Ex: Is it possible to host bonob in a server outside your local network? In that case how bonob will register with the speaker?

EDIT: What encodings does Sonos support? Even though I set transcoding to mp3, and I see the files being transcoded in Navidrome's log, Sonos does not seem to be able to play non-MP3 files, giving "the song is not encoded correctly" error

@simojenki
Copy link

Just joined discord.

@MoralCode
Copy link
Contributor

MoralCode commented May 11, 2021

@deluan supported encodings are here.it should be able to handle MP3, MP4 WMA, AAC/HE-AAC/OGG at 320kbps as well as FLAC, ALAC, AIFF and WAV at 16-bit-depth

@certuna
Copy link
Contributor

certuna commented May 12, 2021

Ah no Opus then.

@simojenki
Copy link

You would need to transcode into something else

@deluan
Copy link
Member

deluan commented Nov 1, 2021

Closing this as it is now well supported by bonob, and I don't have plans to incorporate the functionality in Navidrome for now.

@deluan deluan closed this as completed Nov 1, 2021
@github-actions
Copy link

github-actions bot commented Mar 9, 2023

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 9, 2023
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Projects
None yet
Development

No branches or pull requests

9 participants