Git Product home page Git Product logo

Comments (41)

billsq avatar billsq commented on May 23, 2024 4

Full forked-daapd metadata pipe support added:

billsq@77c644d

from librespot.

allquixotic avatar allquixotic commented on May 23, 2024 3

stdout support would provide file writing support "for free" because of the lovely concept of pipes (which work on both UNIX-likes and Windows cmd, AFAIK). I'd advocate implementing this for stdout first, making sure to move any current stdout prints during normal operation into stderr so the stream is free of non-metadata noise.

This feature would enable me to use librespot where I can't use it currently.

from librespot.

billsq avatar billsq commented on May 23, 2024 3

For anyone who is interested, I added the ability to bypass the internal soft volume control and export the volume via a metadata pipe which is compatible with forked-daapd.

billsq@74e3209

Use arguments --linear-volume --mixer pipe --metadata-pipe </srv/music/librespot.metadata> to properly send the volume.

I am new to Rust... It would be appreciated if someone could help to review the code.

from librespot.

sashahilton00 avatar sashahilton00 commented on May 23, 2024 2

Fair enough. To be honest, compiling librespot is really not very difficult. One simply installs rustup, installs the latest rust version, makes sure portaudio is installed and runs cargo build. I would rather keep librespot fairly vanilla, and have the various features such as dns-sd over mdns, etc. that frankly most users are not going to care about as compile time flags, then have a separate project as you suggested which is the bells and whistles daemon. That way, the daemon repo can handle which features it wants when compiling librespot, and the daemon/standalone binary can have all of the metadata/webserver/etc stuff built in and toggleable by runtime flags. The daemon/standalone project could then be binary that gets distributed via PPAs and such, whilst librespot is kept thin for people using it as a library.

from librespot.

sashahilton00 avatar sashahilton00 commented on May 23, 2024 1

I think that was Paul's intention, that all the websocket server, piped metadata, etc. go in a separate project, and librespot is simply for core functionality.

from librespot.

ComlOnline avatar ComlOnline commented on May 23, 2024 1

I like this a lot, so just to check?

librespot librespotd?
Releases No releases, the master is just the latest Have a steady release cycle (monthly?)
Compiling Barebones (if we release binaries at all) All options on by default at compile time
Locations Only on github Create a ppa in addition?

from librespot.

allquixotic avatar allquixotic commented on May 23, 2024 1

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.

michaelherger avatar michaelherger commented on May 23, 2024 1

...unless its name is not lib-respot, but libre-spot ;-)

from librespot.

frafall avatar frafall commented on May 23, 2024 1

I really like the organization with separate 'base' library and a bells-and-whistles daemon, keeps the separation of duties clean, this also enables writing the daemon in other languages against a stable API.

As for the piping, separating stdout for audio data and stderr for metadata is an option, easy to handle in both controlling daemons and scripts.

My main issue with a lot of media players is that they tend to add on metadata as an afterthought instead of offering it in the audio channel implementation, ex. Pulseaudio output implementations often do not set the metadata properties even though is is somewhat defined, even album art can be pushed there as a binary blob or url (although not well defined).

So, for pulseaudio set the properties, for process control use stdout/stderr, for alsa we probably need to put it somewhere but there the picture gets messy. (at least in my head)

As for presenting album art an image web service is probably a nice way to go, a controlling daemon could subscribe to the service and push it wherever we (like a Kodi addon). But, for the Linux desktop, playing librespot on a pulseaudio interface could offer metadata like the Mopidy player does which would display but, again, the album art part is not well defined.

My input for goals on metadata are:

  • Integrate into Linux desktop environment, ie something like Mopidy/Pulseaudio (dbus can of worms)
  • Enable integration to media centers or multi room solutions, ie stream metadata to controlling daemon
  • Offer 'the rest' some consistent way to get hold of the metadata, probably audio output adapter dependent, ie push metadata to the audio output adapter in daemon.

I.E. Command line flags select audio output devices with metadata. Then an option to start the web service.

So, for me this leaves the question, should we modify the audio output adapter interface in the base library? Open it for the bells-and-whistles daemon to extend it with metadata or move the functionality there?

Nice work setting up the org πŸ‘

Almost forgot, json, encoding (album art), tag standards (Vorbis?)... probably more to think about here.
But, standardize on something open and language/protocol independent...

Ops, almost forgot more, as we can not possibly push everything Spotify provides or any1 could possibly want we should add a tag for song Spotify reference, enables lookup for further info. Also, if librespot http service is enabled a reference to this.

from librespot.

ComlOnline avatar ComlOnline commented on May 23, 2024

Hi @frafall I agree, I'm doing some research on it now.

This is a good read as you know.

More for reference this is the web API track object. I feel this may be easier to use if there is an easy way to authenticate with the API (So far I've found it a pain)

As in the above issue I would also say that writing to file may be the best way as it is somewhat easy to get information from. Of course other ways could be added but I would say that write to file should be the first focus.

from librespot.

frafall avatar frafall commented on May 23, 2024

Some issues with file writes, u never know if the data is current or some leftover from earlier runs, it's localized inside a docker image or VM (unless exported explicitly) and pushing new data is a hassle as u either have to add new data at end or re-write file and leave it to the client to poll this. I like push options.

My ideal solution would be opening a socket to libreelec where it pushed data, kinda similar to listening to stderr or a pipe if you have control of the process. I kinda dislike pipes due to the locality (single machine) and single reader things.

But, for now I've been happy reading the stdout output, rather that than a file.

from librespot.

ComlOnline avatar ComlOnline commented on May 23, 2024

I see where you're coming from with writing to file, however its sometimes the only way to feed from other programs the information. Usually by polling said file, containing only now playing metadata. (I don't like it either).

I think like you some sort of push service were other devices listen would be best, but I feel that should be as a secondary objective.

Also not everyone will want metadata so I think it should be an option, views?

I think stout should be a priority as it would be one of the easiest get a proof as concept.

from librespot.

sashahilton00 avatar sashahilton00 commented on May 23, 2024

I did implement a (dodgy) websockets server a little while back in an earlier version of librespot that pumped out metadata to clients on various changes, though it wasn't merged as Paul wanted to keep librespot relatively minimal. With regards to metadata format, do we think JSON would be suitable? I only suggest that so that those who choose to interact with the Web API as well don't have to think about multiple data formats.

Also, I agree that the metadata output should be optional, some people just dont need it if they integrate with librespot directly. Perhaps a compile time flag if people want metadata output?

from librespot.

snizzleorg avatar snizzleorg commented on May 23, 2024

I would prefer a meta-data pipe. That would be compatible with forked-daapd.

from librespot.

snizzleorg avatar snizzleorg commented on May 23, 2024

See here: owntone/owntone-server#278

from librespot.

allquixotic avatar allquixotic commented on May 23, 2024

Well, maybe it's just because I'm curmudgeonly, but I'd prefer not to have to write any code in Rust. What I'd like is for the example Spotify Connect daemon that comes with librespot to offer a metadata to stdout flag. You could implement similar backends for other protocols too, even HTTP. With the new librespot-org we don't have to worry about if Paul wants to keep the thing minimal if the current maintainers don't feel that way ;)

Since librespot has PulseAudio output, you can kinda see where I'm going with my design if you look at what Tribblify can do... Keeping in mind that all sinks have a source named sinkname.monitor in PulseAudio... ;)

As far as data format, any of the following would work for my purposes:

  • JSON
  • XML
  • CSV
  • URL encoded param string (like artist=foo&song=Benny &amp; the Jets)

What probably wouldn't work is having the format be Artist - Song Title, because then how would you parse a string like: Andrea Bocelli - Live - Phantom of the Opera - Venice? Where is the delimiter between artist and song title? I have this current limitation with my parsing of the Spotify window title, so switching to librespot would be a marked improvement there. Plus it'd be headless.

from librespot.

sashahilton00 avatar sashahilton00 commented on May 23, 2024

I get where you're coming from, I'm not a huge fan of rust either. However, in the interests of maintainability, I do think he was right not to allow things like a websockets server to be baked in to librespot with no way to turn it off. However, compile-time feature flags are our friend here, to a certain extent, in that any pipe/websocket/etc. solution can be selectively enabled at compile time. I.e. those who don't want a bigger executable can just build without the features they don't need. I do agree with you though, in that whilst librespot is technically a library, I get the feeling that most people are using it as a daemon/standalone program, thus not having metadata easily available in daemon mode is a pain.

from librespot.

allquixotic avatar allquixotic commented on May 23, 2024

Perhaps a separate GH project entirely for the daemon that's actually featureful? That would be amazing! :) It could go under librespot-org, too...

from librespot.

allquixotic avatar allquixotic commented on May 23, 2024

The only reason I get a little nervous about compile-time flags is that, if actually compiling the thing is a nightmare (which could happen if we keep super up to date with the latest Rust stuff and you're running, say, Ubuntu 16.04 with 2 year old Rust), and binaries happen to be conveniently available from distro packages or a PPA, then we'd want to make sure that distros ship with all possible options enabled at compile-time, and just have them be runtime flags.

I agree with you that having a web server enabled by default is way overkill, but I think all the possible features of the daemon should be there in a default compile, and encourage anyone packaging binaries, whether it be Ubuntu or a PPA maintainer or some other distro, to enable all options. Everything that's a compile-time flag should also be disabled by default in the daemon if you just run it with only the minimum required arguments to establish a Spotify connection; to get extra features like metadata, it's fine to expect the user to have to pass a command-line argument.

I don't think code size is an issue even on a Raspberry Pi, because the storage capacity of MicroSD cards is ridiculous these days. Compiling in Rust code for a web server may add a megabyte to the code; it may add five megabytes... I can't bring myself to care at all on any platforms that would have the cycles to run librespot in the first place.

from librespot.

allquixotic avatar allquixotic commented on May 23, 2024

That way, the daemon repo can handle which features it wants when compiling librespot, and the daemon/standalone binary can have all of the metadata/webserver/etc stuff built in and toggleable by runtime flags. The daemon/standalone project could then be binary that gets distributed via PPAs and such, whilst librespot is kept thin for people using it as a library.

Yeah, that sounds like a great plan.

from librespot.

sashahilton00 avatar sashahilton00 commented on May 23, 2024

Yeah, that sounds about right.

from librespot.

michaelherger avatar michaelherger commented on May 23, 2024

As for piping out metadata to stdout: this would become difficult if librespot was set up to pipe the audio data to stdout. Which is part of the options now, and which I do indeed use in my case.

from librespot.

ComlOnline avatar ComlOnline commented on May 23, 2024

Just so as to not clutter this issue continued discussion of librespotd (or whatever we call it) should continue here: #20

from librespot.

sashahilton00 avatar sashahilton00 commented on May 23, 2024

For reference, #25 is semi-related.

from librespot.

sashahilton00 avatar sashahilton00 commented on May 23, 2024

Search functionality: #23

from librespot.

snizzleorg avatar snizzleorg commented on May 23, 2024

Any chance this gets merged?

from librespot.

sashahilton00 avatar sashahilton00 commented on May 23, 2024

If he opens a PR and then once it's reviewed, sure.

from librespot.

billsq avatar billsq commented on May 23, 2024

#214 PR created.

from librespot.

chimpy avatar chimpy commented on May 23, 2024

This is brilliant. I'll give your repo a clone while we wait for the daemon. Thanks @billsq !

from librespot.

chimpy avatar chimpy commented on May 23, 2024

So I cloned the rep to get this fix. Compiling was successful and the client runs.
The pipe.metadata file has the same name as the pipe and is in the same dir. It is readable and writable.
However forked-daapd is not picking up any metadata. It plays the source fine, but volume changes do not work.
No other metadata about the sourve is displayed.

from librespot.

billsq avatar billsq commented on May 23, 2024

@chimpy Does your pipe.metadata have the same permission as your pipe file? Did you run librespot with the arguments I mentioned above? Did you restart your forked-daapd?

from librespot.

chimpy avatar chimpy commented on May 23, 2024

Hi @billsq ! Thanks for the reply. Details below:

chimpy@hassbox:/opt/music$ ls -lh
total 4.0K
prw-r--r-- 1 root root 0 Aug 1 21:24 spotify
-rw-r--r-- 1 root root 135 Aug 1 21:24 spotify.metadata

librespot -n "House Speakers" -b 320 -c /var/cache/spotify --initial-volume 30 --device-type avr -u chimpy -p "redacted" --backend pipe --device /opt/music/spotify --linear-volume --mixer pipe --metadata-pipe /opt/music/spotify.metadata

I have restarted forked-daapd before using your fork, no change. If I do a tail -f on the metadata file when adjusting volume, playing and changing a song I see it updating, but no change on forked-daapd's side.

Ah, this gets mentioned in forked-daapd's log:
forked-daapd[19611]: [ LOG] player: Source type is pipe, but path is not a fifo: /opt/music/spotify.metadata

OK, so I realised that maybe spotify.metadata should be a pipe as well. I did a mkfifo /opt/music/spotify.metadata and restarted forked-daapd but now librespot authenticates and then hangs. It does not appear in the client list.

from librespot.

billsq avatar billsq commented on May 23, 2024

Try restarting librespot. spotify.metadata
should be a pipe.

from librespot.

chimpy avatar chimpy commented on May 23, 2024

Hey bill, not sure if you saw my edited comment, but I did that. I did mkfifo spotify.metadata. When I restart librespot it hangs after authenticating my user but before showing the country code.

from librespot.

billsq avatar billsq commented on May 23, 2024

It happens to me with stock librespot sometimes. Just try to restart it. I don’t think it has anything to do with the pipe code.

from librespot.

chimpy avatar chimpy commented on May 23, 2024

from librespot.

chimpy avatar chimpy commented on May 23, 2024

@billsq Everything still working for you? The problem above has back for me with a vengeance. After a about 40 start/stops, it's still hanging before getting the country code.

from librespot.

billsq avatar billsq commented on May 23, 2024

It is working as usual.

from librespot.

mensoh avatar mensoh commented on May 23, 2024

Has this been merged? Using --mixer pipe --metadata-pipe /srv/music/spotify.metadata gives me error: Unrecognized option: 'metadata-pipe' on what I built from source yesterday

from librespot.

chimpy avatar chimpy commented on May 23, 2024

from librespot.

billsq avatar billsq commented on May 23, 2024

@chimpy Finally found the root cause or your issue. It is due to forked-daapd doesn't open metadata pipe by default. Now should be working fine.

from librespot.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.