~ser/gompris

An MPRIS2 server library for Go
Initial commit; builds, but completely untested and incomplete

refs

v0.0.1
browse  log 

clone

read-only
https://git.sr.ht/~ser/gompris
read/write
git@git.sr.ht:~ser/gompris

You can also use your local clone with git send-email.

#gompris

gompris is a Go MPRIS Server library.

#Using

Import ser1.net/gompris as usual. Implement:

  • gompris.MediaPlayer2
  • gompris.Player

and optionally:

  • gompris.TrackList
  • gompris.Playlists

Call gompris.New() to get an MPRIS2 server, and then call gompris.Register* with your structs to get them hooked up to the dbus.

In the example directory is a dummy server which is used for testing, and copied as a template for your server.

There are a number of bookkeeping things you have to make sure you do in your implementation. Most of them are self-evident in the callback watcher API signatures, but the Seeked() one is a bit weird.

Per the MPRIS2 spec, players do not get signals about Player state changes unless the state change is unusual. This means that, if the server is playing a song, the client is supposed to assume that the position is ticking along at a regular rate... the server is not emitting position updates, unless for some reason the track is seeked, or stops unexpectedly, for example. The relevant section is:

Seeked

Indicates that the track position has changed in a way that is inconsistant with the current playing state.

When this signal is not received, clients should assume that:

  • When playing, the position progresses according to the rate property.
  • When paused, it remains constant.

This signal does not need to be emitted when playback starts or when the track changes, unless the track is starting at an unexpected position. An expected position would be the last known one when going from Paused to Playing, and 0 when going from Stopped to Playing.

What this means for you, the server author, is that you don't call Seeked() as you stream the music; you only do it if there's an unusual situation, like the stream starts in the middle, or ends abruptly, or starts unexpectedly. However, should one of those situations occur, you must call the watcher.

All of the servers have watchers; it's important to call them when events happen, even if in response to the API functions being called. They're what trigger dbus property changes, which are important for MPRIS2 player controllers -- the thing triggering your API call may not be the same as the thing watching and showing the user.

#Development

#Help needed

The current version has no tests, demo programs, and little documentation. These all need to get done, eventually.

The current code is incomplete.

The API design follows the MPRIS2 spec pretty closely; there may be a better, more idiomatic, approach. I'm accepting input on this before the library starts being used and the API calcifies.

The MPRIS2 documentation is pretty unreadable, IMO; the comments themselves are good, but whatever tool is used to generate the docs leaves much to be desired. The distinction between dbus Properties, Signals, and Functions is unclear, there are no examples, and there's a heavy assumption that the reader is familiar with dbus (this last is reasonable, but challenging). Contributions that better explain the dbus interaction or fix incorrect use are appreciated.

#Style, tooling, etc

I tend to put a lot of information in the code comments. Use a tool like Legume to get reports, eg:

$ leg
  1 BUG this API doesn't cover the entire xesam, e.g. YEAR, DISCNUMBER
        http://wiki.xmms2.xmms.se/wiki/MPRIS_Metadata
        Dates passed as ISO-8601 ("2006-01-02T03:04:05") or RFC3339
  2 BUG implement: setProperty()...
  3 BUG copy all of that verbosity here *sigh*
        org.freedesktop.DBus.Properties
  4 BUG all of these EmitTrues need helpers to set properties when the Player changes
  5 BUG OpenUri should fire track list events
  6 BUG -- apparently, all these emits should be doing this instead

That said, code comments are only useful for developers of the library, so the project has a tracker associated for Users. I'd prefer to keep it that way: contributors working within code comment TODO and FIXMEs, and end-users posting tickets.

I may keep a Changelog. I tend to in other projects, but it hasn't yet become a "must" for me.

This is a Go modules project, so it (necessarily) adheres to Semantic Versioning

The repo is git, but I use jututsu. I don't think it makes much difference for collaboration, but there might be some reflog peculiarities as a result.

I won't accept those patches that add linters to the build automation.

Do not follow this link