Skip to content

bpd: support MPD 0.16 protocol and more clients - #3214

Merged
arcresu merged 14 commits into
beetbox:masterfrom
arcresu:bpd-mpd16
Jun 3, 2019
Merged

bpd: support MPD 0.16 protocol and more clients#3214
arcresu merged 14 commits into
beetbox:masterfrom
arcresu:bpd-mpd16

Conversation

@arcresu

@arcresu arcresu commented Apr 13, 2019

Copy link
Copy Markdown
Member

Now that idle has been implemented, we're almost all the way to MPD 0.16 support. There are a couple of small commands that need adding, but most of what we need is already in place. More importantly, claiming to support the newer protocol version means that more clients will talk to us; fixes #800.

  • nextsong and nextsongid fields in status output.
  • playlist range support in playlistinfo.
  • playlist range support in move.
  • stickers (which are basically flexible attrs). Moved to bpd: support MPD stickers #3290

I've expanded my local tests to include ncmpcpp and two Android clients (MPDroid and MALP). So far bpd breaks all three of these clients. Known compatibility issues are listed below.

ncmpcpp (Linux, libmpdclient)

  • ncmpcpp sends noidle when bpd doesn't expect it to be in the idle state.
  • ncmpcpp uses the deprecated volume command to change the volume and we ignore it.
  • ncmpcpp sometimes causes an error with errno 104 ECONNRESET when quitting.
  • ncmpcpp issues the unimplemented command decoders (fixed in bpd: support decoders command #3222).
  • It notices when playback is paused, but doesn't notice when it's resumed again, even if it was resumed using ncmpcpp itself! Issuing a different command (e.g. changing the volume) will prompt it to refresh the status and update the playback state. This doesn't seem to happen any more. I'm not sure what fixed it.
  • ncmpcpp expects stored playlists to be supported and when bpd sends an error it gets stuck in an infinite loop and the UI freezes. Moved to BPD: Persistent playlist #176.
  • When it receives a playlist event and tries to update its playlist using plchanges it doesn't like the response returned by bpd and ncmpcpp's playlist becomes blank.

M.A.L.P. (Android)

MPDroid (Android)

  • MPDroid uses extra idle events that we don't support yet (idle "database" "mixer" "options" "output" "player" "playlist" "sticker" "update").
  • MPDroid crashes at startup although there is no MPD error sent over the protocol. We must be giving it wrong output in the successful commands somehow.

mpDris2 (Linux)

  • mpDris2 seeks using fractional seconds and crashes when bpd doesn't accept that.
  • mpDris2 (and another client but I've forgotten which) crash sometimes with an error that implies that bpd forgot the state field in a response to the status command. This doesn't seem to be possible though. Its backtrace starts with KeyError: 'state'

mpdscribble (Linux, libmpdclient)

  • mpdscribble tries to register a client channel. It doesn't mind that it fails, but it would be nice to support it. Moved to bpd: support client channels #3291
  • I noticed it stopped scrobbling and there was an error in the log: mpd error (7): expected more list_OK's. I didn't manage to correlate it to the protocol log in bpd though so I'm not sure what happened.

Other clients

@arcresu
arcresu marked this pull request as ready for review June 2, 2019 13:24
@arcresu

arcresu commented Jun 2, 2019

Copy link
Copy Markdown
Member Author

I've been using this branch myself for some time now and it's mostly working OK. The main issues are because of parts of the MPD protocol we're missing, but I'd prefer to handle those additions separately.

The other issue I've seen is that after running fine for some time, clients connected to bpd will sometimes crash. I caught mpDris2 and ncmpcpp crashing at the same time with log output that suggested a malformed response from bpd. This is rare enough that I haven't been able to correlate it with the specific output in bpd's protocol traffic dump. Whenever this has happened I've only needed to restart the clients to get things back to normal, without having to restart bpd.

In the course of implementing this PR I encountered issues that went away when I implemented support for apparently unrelated protocol features. I guess the clients aren't robust to unexpected server behaviour since there's normally only one server implementation to test against. I'm hopeful that the issue I mentioned above will solve itself in the same way.

So I think I'd like to merge this now and keep working on the unchecked todo items during the release cycle. This should hopefully encourage some other people to test the changes too :)

arcresu added 14 commits June 2, 2019 23:37
When ncmpcpp quits after an error it causes a "connection reset by peer"
exception, also known as ECONNRESET (104) in errno terms. In Python
2 this is mapped to a `socket.error` and in Python 3 this is
  `ConnectionResetError` which is thankfully a subclass of the
  `socket.error` exception class.
The playlistid command is supposed to list the whole playlist if no
argument is provided, but we were accidentally trying to look up an
impossible negative id in that case causing an error to always be
returned.
The documented type is float, not integer, and clients like mpDris2 send
fractional seconds, causing them to crash if these values ar enot
accepted.
The real MPD ignores `noidle` when the client is not idle. It doesn't
even send a successful response, just ignores the command. Although
I don't understand why a client would fail to keep track of its own
state, it seems that this is necessary to get ncmpcpp working.

@sampsyo sampsyo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Everything looks good to me, so let's go for it. I agree that getting more "eyes" on your new features will be the right way to shake out any bugs.

@arcresu arcresu added this to the Modern MPD support milestone Jun 3, 2019
@arcresu

arcresu commented Jun 3, 2019

Copy link
Copy Markdown
Member Author

Alright, I've opened a bunch of issues to keep track of missing features, and collected them in a new milestone. Let's get this in 🎉

@arcresu
arcresu merged commit be1daa9 into beetbox:master Jun 3, 2019
@arcresu
arcresu deleted the bpd-mpd16 branch June 3, 2019 00:40
snorkelopstesting3-bot pushed a commit to snorkel-marlin-repos/beetbox_beets_pr_3214_0dcd9583-f135-4397-b745-4bd16d6d3ecd that referenced this pull request Oct 22, 2025
snorkelopstesting4-web added a commit to snorkel-marlin-repos/beetbox_beets_pr_3214_0dcd9583-f135-4397-b745-4bd16d6d3ecd that referenced this pull request Oct 22, 2025
@snejus snejus added the bpd bpd plugin label Apr 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bpd bpd plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BPD: Update to newer MPD protocol version

3 participants