Bug 469617 - MPRIS receivers/controllers are ignoring playback rate to extrapolate current play position
Summary: MPRIS receivers/controllers are ignoring playback rate to extrapolate current...
Status: REPORTED
Alias: None
Product: kdeconnect
Classification: Applications
Component: common (show other bugs)
Version: unspecified
Platform: Other All
: NOR normal
Target Milestone: ---
Assignee: Albert Vaca Cintora
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-05-11 12:35 UTC by bart
Modified: 2024-06-03 17:16 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description bart 2023-05-11 12:35:05 UTC
SUMMARY
The MPRIS receiver/send implementation is ignoring the playback rate settings.  This is at least the case in the linux and android implementations.
As a result, if a user is using a media application with a playback rate setting other than 1, the kdeconnect media controller applet is showing an incorrect position since it simply adds 1 second to the play position every second.  Hence, the playback position starts to run out-of-sync with the real media player.
Note that the MPRIS2 DBus specification says to only to update the Position property if playback does not proceed at the currently set playback rate value.  Hence, it is implied that the extrapolated playback position should take into account the playback rate.
I checked the source code of both the linux and android app, and there are simply no handlers for the MPRIS2 Rate property.

STEPS TO REPRODUCE
1. Start up a media application with variable playback speed control (on e.g. linux).  Start playing back something and change the playback rate != 1.
2. Open the kdeconnect-android media controller and keep an eye on the play position wrt the play position on the originating application on linux.

OBSERVED RESULT
Watch the playback position drift out-of-syn.

EXPECTED RESULT
The extrapolated playback position should take into account the Rate property value.

ADDITIONAL INFORMATION
The MRPIS2 Rate property should be implemented and the extrapolated playback position should take this value into account.
Comment 1 Andy Holmes 2023-05-11 21:51:46 UTC
I'd like to put in my two cents here, having struggled with many players claiming MPRIS compliance. The reality is that there 1-2 players at any given time that correctly implement the full interface, especially when it comes to the playback position.

It would very much preferable to just have clients update the position property more frequently in this case, rather than try to support more of the MPRIS interface explicitly. Playback rates other than 1.0 are pretty uncommon, usually only occur for short periods of time (i.e. seeking), and re-using the `pos` field would be backwards compatible.
Comment 2 bart 2023-05-12 07:26:11 UTC
(In reply to Andy Holmes from comment #1)
> ...
> It would very much preferable to just have clients update the position
> property more frequently in this case, rather than try to support more of
> the MPRIS interface explicitly. Playback rates other than 1.0 are pretty
> uncommon, usually only occur for short periods of time (i.e. seeking), and
> re-using the `pos` field would be backwards compatible.

Well, I'm the developer of Kasts, and non-standard playback rate is among the top 5 requirements for podcast players.  That's also why I noticed this problem and started investigating this.
So far, Kasts was simply relaying the position-changed signals coming from the audio backend, which leads to such signals being sent 1 to 4 times per second, depending on the backend.  However, that approach will make kdeconnect drain the battery at 10% per hour on my android device: see https://bugs.kde.org/show_bug.cgi?id=442782 .
Then, while re-implementing MPRIS position properly, I ran into this playback rate bug.

So, while I recognize that many players do not implement MPRIS properly (including Kasts up to now), that doesn't mean that kdeconnect should not do so.  As a matter of fact, these kinds of bugs are actually holding back players implementing the intended standard properly.

Anyway, I was looking at the kdeconnect source code, and it doesn't look very complicated(*) to implement.  It's just a matter of sending the rate reported through DBus and using it in the one line of code that does the extrapolated play position.  I was actually planning on making MRs for this.

(*) Not very complicated in the sense that the basic principle is very simple, but it does seem to require a lot of boilerplate code to send/receive and store the value.  And I would also need to figure out how to build the android app locally.
Comment 3 Andy Holmes 2023-05-23 23:14:35 UTC
Fair enough, I don't do a lot of podcasting so I hadn't considered that.

In that case I would suggest a slightly simplified way of communicating this, in the form of a triplet like `[rate, min, max]`. If the field is missing (older clients), it can be assumed `[1.0, 1.0, 1.0]`. The min/max would be required since if this is a useful feature, we will certainly want to be able to control it as well.

If the value is, or falls back to `[1.0, 1.0, 1.0]` we can assume it's unsupported or not controllable and hide any UI in remote controls.