unoffical-sonos-controller-for-linux
unoffical-sonos-controller-for-linux copied to clipboard
Play local music files
Already under development, the ability to play music from "this device", i.e. the ~/Music folder
Can we checkout where this is under development?
How do you plan on integrating this specific function? I just created a java program indexing my music files and upon request hosting the file in a shared network folder to be able to play them back on sonos devices. While working this seems like a lot of hassle though and I look for a better solution.
@KilianB i would suggest not indexing, but simply listing the folder structure. The user could then just play a single file, a folder, or add a file or folder to the playlist?
@eitch I indexed the music files in order to be able to search for artists, album names, title etc. (Info taken from the id3 tags). I haven't taken a look at how this specific library plays back files but as for the dependency I currently am using https://github.com/vmichalak/sonos-controller music files have to be supplied as URI which sonos speakers have access to (a shared resource on the network or internet). Therefor playing back files wasn't as trivial as I first though. I haven't taken a look at this repository though. Maybe node or electron is doing the entire work already.
Ahh, ok, that makes it a bit more interesting. A first thought would be to simply start a simple HTTP server locally (this is trivial in Node, no?). Then create an URI which points to this local server and the server knows then how to handle the URI request to stream a local file. I'm not familiar with the streaming specifics, so i'm not sure if just passing the file to the client as a FileStream would suffice.
@KilianB I was investigating indexing as well ... problem I hit was that the available node packages were slow. Then I haven't looked at it in forever as well ... Maybe I could bundle your java service or at least have a look at it? Is it on github?
It's in a private repository at the moment. The first index run for 8235 files on a network drive takes roughly 5 minutes. The information is saved into an embedded SQL database. Subsequent runs, just looking at the delta, take roughly 15 seconds. I can upload it later this week if you wish but I am not sure if you can easily integrate it into node though.
Node maybe not, but we could investigate if it's something we could bundle with electron. AFAIK it can include other binaries.
Hi, it's been a while. How's progress?
Recently Sonos has been requiring that people update their Sonos to the latest version which has the code for implementing (the dreaded) Alexa. I refuse to update my perfectly working Sonos with this (in my opinion) malicious software. Really hoping to see something develop with local music library playback. Right now I can only use my Sonos with Spotify. I appeciate this unofficial controler though! Thanks for all the work on this!
I don't know how I forgot about this issue. I am really sorry. Hopefully this weekend I'll upload a small sample application showing how we can playback local music files. I threw together a small demo player to demonstrate the procedure. (just need to populate the table with the indexed files and it's ready to be uploaded here (maybe later today more likely tomorrow).
The overall procedure:
- Crawl the directories and build a searchable index based on title, album name (id3 tags) (to allow partial or approximate matching using edit distances e.g. levenshtein distance).
- Save the index persistently e.g. an SQL database
- Make the files available to network devices. (If they are already on a NAS this step can be skipped). Start a fileserver and map all indexed folders to a fixed ip address. by cross referencing the index and the file location we can tell the sonos player to play back files located at the server.
- enjoy and listen to your local music.
Took a bit longer than expected but here you go:
Here is a small example how to play back text to speech on any speakers. Which basically plays back a local file but leaves out all the gui parts as well as indexing. Probably a good way to start. https://github.com/KilianB/Java-Sonos-Controller/tree/master/src/main/java/com/github/kilianB/example/voiceToTextPlayback
Maybe time to roll a release?
@davidpgil A release with no proper pull request?
@KilianB Great work. I did have a look through that, but right now have no time to integrate it into the player. I'd be keen to not mix JS and Java tbh, but most of it makes sense from a conceptual POV. Interesting that you use a SQL DB ...
I just noticed that the sonos controller allows to add local folders to the music library. Not sure how this is managed but maybe sending the correct upnp events and hosting the files is all that is needed. Maybe we don't need the indexing?
Take a look at the mdns and http requests, especially the content directory event.
Someone would need to investigate what exactly is going on there, I on my part do not have time to do this anytime soon.
Maybe time to roll a release? To be honest the code I have posted is a big mess and would take at least a few days to integrate into this project. Different language, just partially created so it "works".
I am not sure if I really like the SQL database. Indexing music files, the way it's currently done is pretty expensive and should not be done multiple times if not necessary. A persistent storage is a must. On the other hand SQL queries in the source code look tedious. It is great to map relationships between interprets album and tracks, but a database works well if you hit it to request data, in my case most of it is kept in memory all the time and just used to store it between the runtime instances. It is a design decision which shouldn't be taken lightly.
@pascalopitz nevermind, i didnt realize this was not done yet.
Was there any progress on this one?
Thanks!
I didn't do any additional follow up on this so far.
Why not use an integrated express webserver (or even the standard node http server), hosting the mp3 dynamically? Then you can add the local url like http://ip_of_local_computer:8000/music/mp3_filename.mp3
as long as it end with .mp3
Sonos will just allow you to add it to any playlist, no indexing required and no messing around with some file share.
@svrooij The serving of the file isn't the problem here, but the generating an index and displaying that so that it integrates well with the browser panel, displays album arte etc.
That said, having played with Electron for a bit now, another measure we could take is a system file browser, select file, play. That would be very easy to achieve.
The other thing I would be concerned about is making sure to only serve music files and info about them, as this is a bit of an attack vector onto the local machine otherwise.
Ok guys n gals. I have implemented a version without indexing, which basically just serves up folder contents. Still pondering what to do about the search. Anyone want to check this out locally and give it a quick test for feedback?
https://github.com/pascalopitz/unoffical-sonos-controller-for-linux/tree/local-music-server
I'm getting a 404 upon clicking on your link.
Yes, sorry, the branch was removed, as this is now rolled into the new alpha releases. v0.2.1-alpha1 implemented a local music server and a local smapi compatible service visible in the browser panel. In v0.2.1-alpha2 I have added a local file indexer and a text search.
https://github.com/pascalopitz/unoffical-sonos-controller-for-linux/releases/tag/v0.2.1-alpha2
I just installed it and pointed it to my massive folder of music. So far it does not seem to work for finding my local music.
- I go to "On this Deviceu" > "Set Local Music Folder"
- I select my music folder which is in "/home/username/Audio/Music"
- I go to "On this Device" > "Enable Local Files"
- I go to "Library" >"Start Indexing" and wait
- I go to "Select a Music Source" and click on "On this device"
- Nothing happens
Ok, so "Library"->"Start indexing" issues an indexing request to the music library connected to your Sonos devices, i.e. a network share.
Selecting your music folder does fork a local indexing process inside the electron app.
Even without that you should be able to browse the folder structure of your music folder via the "On this device" source. If that doesn't work for you, I am not sure what could be amiss.
How have you installed the app? What OS etc are you running? Can you fire up the process via command line and see if there's any meaningful output like error messages?
Can anyone else give this a try and report back please?
I am moving this weekend, so my network is in pieces currently. I'll try it out early to mid next week and report back!
How have you installed the app? Deb file installation.
What OS etc are you running? I'm using Trisquel 9 -- based off of Ubuntu 18.04
Can you fire up the process via command line and see if there's any meaningful output like error messages?
username@mycomputer:~$ sonos-controller-unofficial
Gtk-Message: 19:23:20.016: Failed to load module "canberra-gtk-module"
Gtk-Message: 19:23:20.016: Failed to load module "canberra-gtk-module"
Gtk-Message: 19:23:20.016: Failed to load module "topmenu-gtk-module"
Handle new path /home/username/Audio/Music
Server starting
events.js:200
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE: address already in use :::13453
at Server.setupListenHandle [as _listen2] (net.js:1306:16)
at listenInCluster (net.js:1354:12)
at Server.listen (net.js:1442:7)
at Application.listen (/opt/sonos-controller-unofficial/resources/app.asar/node_modules/koa/lib/application.js:82:19)
at startServer (/opt/sonos-controller-unofficial/resources/app.asar/localMusic/server.js:610:16)
at process.<anonymous> (/opt/sonos-controller-unofficial/resources/app.asar/localMusic/server.js:638:7)
at process.emit (events.js:223:5)
at emit (internal/child_process.js:876:12)
at processTicksAndRejections (internal/process/task_queues.js:82:21)
Emitted 'error' event on Server instance at:
at emitErrorNT (net.js:1333:8)
at processTicksAndRejections (internal/process/task_queues.js:81:21) {
code: 'EADDRINUSE',
errno: 'EADDRINUSE',
syscall: 'listen',
address: '::',
port: 13453
}
Okay, that looks like the port for the local server is taken by another process.
Can you do lsof -i :13453
That'll tell us what process. I might either make it configurable or alternatively select another port.
On Fri, 10 Jul 2020, 08:57 davidpgil, [email protected] wrote:
How have you installed the app? Deb file installation.
What OS etc are you running? I'm using Trisquel 9 -- based off of Ubuntu 18.04
Can you fire up the process via command line and see if there's any meaningful output like error messages?
username@mycomputer:~$ sonos-controller-unofficial Gtk-Message: 19:23:20.016: Failed to load module "canberra-gtk-module" Gtk-Message: 19:23:20.016: Failed to load module "canberra-gtk-module" Gtk-Message: 19:23:20.016: Failed to load module "topmenu-gtk-module" Handle new path /home/username/Audio/Music Server starting events.js:200 throw er; // Unhandled 'error' event ^
Error: listen EADDRINUSE: address already in use :::13453 at Server.setupListenHandle [as _listen2] (net.js:1306:16) at listenInCluster (net.js:1354:12) at Server.listen (net.js:1442:7) at Application.listen (/opt/sonos-controller-unofficial/resources/app.asar/node_modules/koa/lib/application.js:82:19) at startServer (/opt/sonos-controller-unofficial/resources/app.asar/localMusic/server.js:610:16) at process.
(/opt/sonos-controller-unofficial/resources/app.asar/localMusic/server.js:638:7) at process.emit (events.js:223:5) at emit (internal/child_process.js:876:12) at processTicksAndRejections (internal/process/task_queues.js:82:21) Emitted 'error' event on Server instance at: at emitErrorNT (net.js:1333:8) at processTicksAndRejections (internal/process/task_queues.js:81:21) { code: 'EADDRINUSE', errno: 'EADDRINUSE', syscall: 'listen', address: '::', port: 13453 } — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pascalopitz/unoffical-sonos-controller-for-linux/issues/14#issuecomment-656398797, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACCK7FXU36V7HKKEGJ45R3R2ZG5NANCNFSM4C2O47OA .
username@mycomputer:~$ lsof -i :13453
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sonos-con 30174 username 42u IPv6 27698157 0t0 TCP *:13453 (LISTEN)