Spotifyd / spotifyd

A spotify daemon
https://spotifyd.rs
GNU General Public License v3.0
9.79k stars 447 forks source link

MPRIS commands are a bit slow #891

Open Ape opened 3 years ago

Ape commented 3 years ago

Description MPRIS commands to spotifyd usually take aroud half a second, sometimes longer. I'd expect it to react almost instantaneously.

To Reproduce For example with playerctl status

Versions

matbme commented 3 years ago

Also worth noting that (at least for me) spotifyd jumps to 100% CPU usage during the delay and then returns to normal usage.

image

robinvd commented 3 years ago

i think every mpris command does a network request to the spotify api to get the info, so it makes sense it is slow. A better method should be made for this, either caching or preemptively fetch the info on song change.

@matbme Thats weird and definitly a bug!

georgefst commented 3 years ago

FWIW, it seems not to be all commands. I've found that Play and PlayPause (when it works: see #940) are virtually instant, but I'm seeing the half-second delay for others.

bbergeron0 commented 1 year ago

Turns out playerctl might be at fault here.

MPRIS commands sent with dbus-send are instantaneous, but the same commands sent with playerctl are uncomfortably slow.

playerctl sends a DBus GetAll request before dispatching the actual MPRIS command, which queries all the properties exposed by the DBus interface (In this case, org.mpris.MediaPlayer2.Player), which spotifyd resolves with an obscene amount of HTTP requests.

Maybe spotifyd should implement a workaround for GetAll, maybe playerctl should stop dispatching useless requests, you decide ¯\_(ツ)_/¯.

In the meantime, users can substitute playerctl with dbus-send (Don't forget to replace $PID and $COMMAND):

dbus-send --print-reply --dest="org.mpris.MediaPlayer2.spotifyd.instance$PID" /org/mpris/MediaPlayer2 "org.mpris.MediaPlayer2.Player.$COMMAND"
eladyn commented 1 year ago

Thank you for the investigations! I did a small write-up about the current state of things in spotifyd, which might shed some additional light on what is happening behind the scenes here. Nothing that will solve your problems, unfortunately. ;)

bbergeron0 commented 1 year ago

I have to correct myself; playerctl's GetAll requests are actually necessary and serve the purpose of finding which DBUS applications are MediaPlayer2 instances.

elken commented 1 year ago

In the meantime, users can substitute playerctl with dbus-send (Don't forget to replace $PID and $COMMAND):

dbus-send --print-reply --dest="org.mpris.MediaPlayer2.spotifyd.instance$PID" /org/mpris/MediaPlayer2 "org.mpris.MediaPlayer2.Player.$COMMAND"

I can also confirm this behavior, so for now I've done the same using the below as a template:

dbus-send --print-reply --dest="org.mpris.MediaPlayer2.spotifyd.instance$(pgrep spotifyd)" /org/mpris/MediaPlayer2 "org.mpris.MediaPlayer2.Player.PlayPause"

DaitiDay commented 10 months ago

I have the same problem, but the delay is around 4s (yes, it's really annoying). Even using dbus-senddo not solve the problem. Any update on this?

Edit: I should have mentioned that I'm on arch and I'm using the spotifydpackage from the extra repository (v 0.3.5)

eladyn commented 10 months ago

We're mainly waiting for a librespot release here, since then we'll get access to all necessary information to dispatch commands locally.