Comments (14)
In addition to all the above (sorry for the spam and multiple edits!), it just feels wrong to me to have any output code (like pulseaudio/portaudio support) baked into librespot. In my humble opinion, librespot's tasks should just be:
- Talk to Spotify and Spotify Connect using the proprietary protocols.
- Authenticate the user / API key / device as necessary.
- Accept commands to play songs and such, as librespot APIs (not even from stdin or I/O sources or anything, just pure code).
- Search and playlist support, if available.
- Basic controls like shuffle and repeat, again available as APIs only.
- When asked to play songs, provide APIs for getting the raw PCM data via a Rust API, as well as notification of metadata changes.
Basically, for good separation of concerns, the daemon should do all I/O except for communication with the Spotify servers. All data interactions baked into core librespot other than talking to Spotify should be through APIs in the code. Just my opinion.
So that would mean that we should grab the playback code and put it in the daemon.
from librespot.
The lib not meaning a library but libre meaning free.
That's the correct interpretation. The daemon should be called librespotd, not respotd
from librespot.
I would ask to consider dropping the "lib" on "librespotd" to avoid confusion. "lib" always implies some kind of non-runnable component that software has to consume via code; the intent of "librespotd" is the opposite.
So, maybe respotd?
Or maybe not; now that I think about it, there's precedent for leaving the "lib" in there...
As far as package names, on Debian/Ubuntu at least, there's a reasonable precedent for having packages associated with the same project but with executables in a -bin package. So:
librespot-dev would provide the Rust libraries for building your own programs
librespot-bin would provide the daemon.
We could follow the model of libtool (libtool-bin) and libvirt (libvirt-bin) there. libtool keeps the lib on its main binary program; libvirt has libvirtd and virsh.
from librespot.
As you later stipulated I don't think the lib is an issue see libreoffice
I am very reluctant to change the name of librespot even to librespot-dev.
However saying that having the names librespot and librespotd does leave us open for a lot of confusion. Do you know if this is an issue for libvirt?
from librespot.
librespot should not be renamed. I would just drop the lib since the daemon won't be a library, so it'd be called respotd
from librespot.
The only thing I have against doing that (and its pedantic as all hell) is that I always read librespot as "libre" - "spot". The lib not meaning a library but libre meaning free.
But like I said that is rather pedantic so feel free to overrule me on that,
from librespot.
call it librespotd then? It shouldn't matter too much, since librespot won't be in a ppa
from librespot.
I still believe that the lib part doesn't come from library, but from libre (see https://wiki.snowdrift.coop/about/free-libre-open)
from librespot.
Call it whatever you want, I'm more interested in the functionality ;)
from librespot.
Agreed; the name of the daemon is less important... I think either respotd or librespotd is probably the most logical thing to call it. Now, a few things to consider (this is a sort of synthesis of some earlier thoughts, some new musings, and a sort of informal first cut at a design doc for the new daemon):
-
Who's planning to do most of the implementation? If this is something the community wants to try out and contribute to in the very near term, whoever takes the first stab at it will probably need to be able to dedicate quite some time to it over the next little while (few weeks to few months) to get the project off the ground. As these things usually go, and with the overall level of complexity I expect out of the daemon, it's probably something that will stabilize a bit by summer if we start now.
-
If the daemon maintainer will be someone other than Sasha, should they become a contributor to librespot-org?
-
What language will the daemon be written in? We could either stick with Rust, or try out Rust's famed foreign function interface, which should allow quite some languages to call into Rust.
-
Regarding language: I personally would be able to do a fair bit of work on this if it's written in C/C++, Ruby, Vala, C#, or Java (and friends; Groovy/Kotlin too). I know a bunch of other languages at a less advanced level, but probably not well enough to be able to follow best practices with the design and write good unit tests.
-
I'm willing to contribute some small features (especially if they're ones that only I, or only a few of us, seem to care about) even if the daemon is written in Rust. If it's in a language that's within my wheelhouse, I can contribute more.
-
If the daemon is written in Rust, the FFI is no longer needed, which is one less thing that can go wrong. It also forces anyone sufficiently motivated by this project but without any Rust knowledge to learn Rust, which could either be amazing or a nightmare (I personally haven't tried it much yet).
-
Also with Rust, we can snip out some of the existing Rust code in the librespot repo and use that as the foundations of the daemon. The amount of code we can rip isn't a whole lot, though, so it's not like this would give us weeks of effort to start off with.
-
-
As far as platform support: I personally am capable of producing working Ubuntu PPAs and doing all the prerequisite steps like generating the Debian packaging files. The result probably passes most Debian sniff tests (like lintian), but I'm sure a Debian packaging guru could critique my fairly minimalist packaging tendencies with some improvements. Still, I'd be willing to take a stab at it.
-
Platform support, continued: Windows? Is it even possible? I guess if we write the daemon in Rust and librespot works on Windows, then the daemon will too. But then we have to consider that in the design and think about packaging or doing GitHub "releases" with downloadable EXEs or installers.
-
Platform support, continued: MacOS? If someone knows how to generate Homebrew packages, we know that the current librespot code works on MacOS, so extending support to the Mac via installable packages should be pretty straightforward.
-
-
Design/features (some of these are my own ideas, some of them are from others):
- Ability to send metadata (song info tags) over various channels. "push" design is convenient for many, since folks want some sort of notification when the track changes so they can update their tags in the media player they're using.
- Ability to send the raw PCM data (using a common, well-known sample format like s16le 44.1kHz stereo, but without a WAV header) using stdout/stderr. One limitation of sending the raw data is it eats an entire output stream, which we only have two of per standards (stdout and stderr). We may have to mux the raw data and the metadata on the same output stream using some standard format, like JSON with base64 encoded PCM data. Just an idea.
- There was interest in JSON metadata format since that's what the Spotify Web API already uses, and folks would appreciate a degree of compatibility. JSON also has a fairly intuitive syntax and lowish protocol overhead (not that tags are big enough to impose a significant performance overhead anyway).
- This is the sort of software that people like to run on Raspberry Pis, so anything we design should be built with the RPi in mind and make sure it works on that platform (including taking into account the CPU, RAM and storage constraints of that platform).
- Compile-time flags to disable "extra" stuff beyond the most elemental features. (What features do we consider so essential that they're not disablable?)
- Runtime flags to change the behavior of stdout/stderr as the user desires.
- Possibly a web server (or an HTTP client, even) to send the metadata and/or the PCM data.
- Possibly the ability to encode the audio in Ogg/Vorbis, FLAC, or MP3 in-process with the daemon and send it using the Icecast2 streaming source protocol to an Icecast server. Not sure how happy the Spotify overlords would be about that. Are we worried about the spectre of a DMCA takedown?
- Possibly GStreamer integration of some sort. A "librespotsrc" element would make for extremely flexible integration into existing applications as well as construction of pipelines using
gst-launch
that do just about anything; this is the sort of thing I could possibly consider writing in Vala, and wouldn't actually be part of the daemon necessarily (although it could talk to the daemon, or just call librespot directly). Vala is a good choice here I think because of the great integration with the GLib platform, although there are some pretty good bindings in other languages too. - Alternatively, just let people specify a GStreamer processing pipeline on the daemon command line, like
--gst-pipeline="audioconvert ! audioresample ! lamemp3enc ! filesink location=oh_noes_im_capturing_spotify_to_disk.mp3"
-
License: Technically the daemon is a derivative work of librespot and thus should carry the same license, but the MIT License is nicely permissive so that we could actually pick a different license. Personally I'm a big fan of Apache 2.0, but if folks don't want to wade too deeply into the license wars, I'm also fine with sticking with MIT.
As far as the name, I've been just saying "the daemon". How about we just call it librespotd and call it a day?
Once folks active around this issue and the previous issue agree on a name, we can have Sasha at least create the repository for it in librespot-org.
from librespot.
Also FWIW I had already started breaking up librespot into multiple crates (librespot-protocol, librespot-core, librespot-audio, librespot-metadata). The idea was to be able to write applications which depend on parts of librespot without pulling unnecessary dependencies.
The librespot crate contains everything which hasn't been broken up. The discovery, player and spirc code should probably become a new crate (or two/three), keymaster could be moved into core since it is small and doesn't have any dependencies. Whatever is left (not much) and src/main.rs
forms the daemon.
I'm not really comfortable with putting the sink implementations in the daemon only, as it significantly raises the bar for other users of librespot Player. My pregerence would be to have them in librespot-player
, but behind flags and disabled by default. librespotd would by default enable librespot-player/portaudio
.
from librespot.
So, modify sink api to include metadata push, keep the sample sinks in library and export api to register new sinks? This would leave the library as-is, simple to start using, while enabling any new sink to be implemented.
from librespot.
I see no problem with leaving the existing audio logic in librespot, as it's already there, but I do think that we ought to implement the current audio logic in the daemon, and ensure that future sinks are added to the daemon, since we're just adding unnecessary bloat to librespot otherwise.
from librespot.
For anyone stumbling across this issue, https://github.com/Spotifyd/spotifyd is a good solution whilst librespot-daemon is non-existent.
from librespot.
Related Issues (20)
- High CPU usage and stutter for some songs HOT 1
- get_extended_metadata HOT 3
- Home screen empty HOT 1
- Unable to get client token HOT 2
- translation of lyrics HOT 1
- Librespot causing Spocon to pause/not work? HOT 2
- Support additionnal SpotifyUri types HOT 2
- Can't play new songs (released on current day). Automatically skipping. HOT 1
- Librespot playback won't work HOT 1
- sound volume issue librespot/snapserver HOT 2
- Segmentation fault when running static build with `with-dns-sd`
- librespot unable to play songs
- request a new release HOT 5
- regression: lyrics API no longer working HOT 2
- [question] Configuration file HOT 1
- Librespot starts spamming the new status of the song
- "Connection reset by peer" - possible solution HOT 4
- the trait bound `&url::Url: IntoClientRequest` is not satisfied HOT 3
- player.await_end_of_track exit with exit code: 1
- Tidal Connect HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from librespot.