feat: mpdstats: add config option for played ratio threshold to determine if a

track was played or skipped.
This commit is contained in:
54562474 2025-03-04 18:02:04 -07:00
parent 8a43133bbe
commit 48d45b4df7
3 changed files with 16 additions and 10 deletions

View file

@ -27,6 +27,7 @@ from beets.util import displayable_path
# much time should we wait between retries? # much time should we wait between retries?
RETRIES = 10 RETRIES = 10
RETRY_INTERVAL = 5 RETRY_INTERVAL = 5
DUPLICATE_PLAY_THRESHOLD = 10.0
mpd_config = config["mpd"] mpd_config = config["mpd"]
@ -143,7 +144,9 @@ class MPDStats:
self.do_rating = mpd_config["rating"].get(bool) self.do_rating = mpd_config["rating"].get(bool)
self.rating_mix = mpd_config["rating_mix"].get(float) self.rating_mix = mpd_config["rating_mix"].get(float)
self.time_threshold = 10.0 # TODO: maybe add config option? self.played_ratio_threshold = mpd_config["played_ratio_threshold"].get(
float
)
self.now_playing = None self.now_playing = None
self.mpd = MPDClientWrapper(log) self.mpd = MPDClientWrapper(log)
@ -216,10 +219,8 @@ class MPDStats:
Returns whether the change was manual (skipped previous song or not) Returns whether the change was manual (skipped previous song or not)
""" """
diff = abs(song["remaining"] - (time.time() - song["started"])) elapsed = song["elapsed_at_start"] + (time.time() - song["started"])
skipped = elapsed / song["duration"] < self.played_ratio_threshold
skipped = diff >= self.time_threshold
if skipped: if skipped:
self.handle_skipped(song) self.handle_skipped(song)
else: else:
@ -256,13 +257,10 @@ class MPDStats:
def on_play(self, status): def on_play(self, status):
path, songid = self.mpd.currentsong() path, songid = self.mpd.currentsong()
if not path: if not path:
return return
played, duration = map(int, status["time"].split(":", 1)) played, duration = map(int, status["time"].split(":", 1))
remaining = duration - played
if self.now_playing: if self.now_playing:
if self.now_playing["path"] != path: if self.now_playing["path"] != path:
self.handle_song_change(self.now_playing) self.handle_song_change(self.now_playing)
@ -273,7 +271,7 @@ class MPDStats:
# after natural song start. # after natural song start.
diff = abs(time.time() - self.now_playing["started"]) diff = abs(time.time() - self.now_playing["started"])
if diff <= self.time_threshold: if diff <= DUPLICATE_PLAY_THRESHOLD:
return return
if self.now_playing["path"] == path and played == 0: if self.now_playing["path"] == path and played == 0:
@ -288,7 +286,8 @@ class MPDStats:
self.now_playing = { self.now_playing = {
"started": time.time(), "started": time.time(),
"remaining": remaining, "elapsed_at_start": played,
"duration": duration,
"path": path, "path": path,
"id": songid, "id": songid,
"beets_item": self.get_item(path), "beets_item": self.get_item(path),
@ -337,6 +336,7 @@ class MPDStatsPlugin(plugins.BeetsPlugin):
"host": os.environ.get("MPD_HOST", "localhost"), "host": os.environ.get("MPD_HOST", "localhost"),
"port": int(os.environ.get("MPD_PORT", 6600)), "port": int(os.environ.get("MPD_PORT", 6600)),
"password": "", "password": "",
"played_ratio_threshold": 0.85,
} }
) )
mpd_config["password"].redact = True mpd_config["password"].redact = True

View file

@ -30,6 +30,9 @@ New features:
:bug:`5829` :bug:`5829`
* :doc:`plugins/mbcollection`: When getting the user collections, only consider * :doc:`plugins/mbcollection`: When getting the user collections, only consider
collections of releases, and ignore collections of other entity types. collections of releases, and ignore collections of other entity types.
* :doc:`plugins/mpdstats`: Add new configuration option,
``played_ratio_threshold``, to allow configuring the percentage the song must
be played for it to be counted as played instead of skipped.
Bug fixes: Bug fixes:

View file

@ -58,6 +58,9 @@ configuration file. The available options are:
Default: ``yes``. Default: ``yes``.
- **rating_mix**: Tune the way rating is calculated (see below). - **rating_mix**: Tune the way rating is calculated (see below).
Default: 0.75. Default: 0.75.
- **played_ratio_threshold**: If a song was played for less than this percentage
of its duration it will be considered a skip.
Default: 0.85
A Word on Ratings A Word on Ratings
----------------- -----------------