Skip to content

Commit 24dd40e

Browse files
authored
feat: mpdstats: adds config option for remaining time threshold to determine if track was played. (#5657)
Add new configuration option for mpdstats plugin, `played_ratio_threshold`, to allow configuring the percentage the song must be played for it to be counted as played instead of skipped.
2 parents 8a43133 + 48d45b4 commit 24dd40e

File tree

3 files changed

+16
-10
lines changed

3 files changed

+16
-10
lines changed

beetsplug/mpdstats.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
# much time should we wait between retries?
2828
RETRIES = 10
2929
RETRY_INTERVAL = 5
30+
DUPLICATE_PLAY_THRESHOLD = 10.0
3031

3132

3233
mpd_config = config["mpd"]
@@ -143,7 +144,9 @@ def __init__(self, lib, log):
143144

144145
self.do_rating = mpd_config["rating"].get(bool)
145146
self.rating_mix = mpd_config["rating_mix"].get(float)
146-
self.time_threshold = 10.0 # TODO: maybe add config option?
147+
self.played_ratio_threshold = mpd_config["played_ratio_threshold"].get(
148+
float
149+
)
147150

148151
self.now_playing = None
149152
self.mpd = MPDClientWrapper(log)
@@ -216,10 +219,8 @@ def handle_song_change(self, song):
216219
217220
Returns whether the change was manual (skipped previous song or not)
218221
"""
219-
diff = abs(song["remaining"] - (time.time() - song["started"]))
220-
221-
skipped = diff >= self.time_threshold
222-
222+
elapsed = song["elapsed_at_start"] + (time.time() - song["started"])
223+
skipped = elapsed / song["duration"] < self.played_ratio_threshold
223224
if skipped:
224225
self.handle_skipped(song)
225226
else:
@@ -256,13 +257,10 @@ def on_pause(self, status):
256257

257258
def on_play(self, status):
258259
path, songid = self.mpd.currentsong()
259-
260260
if not path:
261261
return
262262

263263
played, duration = map(int, status["time"].split(":", 1))
264-
remaining = duration - played
265-
266264
if self.now_playing:
267265
if self.now_playing["path"] != path:
268266
self.handle_song_change(self.now_playing)
@@ -273,7 +271,7 @@ def on_play(self, status):
273271
# after natural song start.
274272
diff = abs(time.time() - self.now_playing["started"])
275273

276-
if diff <= self.time_threshold:
274+
if diff <= DUPLICATE_PLAY_THRESHOLD:
277275
return
278276

279277
if self.now_playing["path"] == path and played == 0:
@@ -288,7 +286,8 @@ def on_play(self, status):
288286

289287
self.now_playing = {
290288
"started": time.time(),
291-
"remaining": remaining,
289+
"elapsed_at_start": played,
290+
"duration": duration,
292291
"path": path,
293292
"id": songid,
294293
"beets_item": self.get_item(path),
@@ -337,6 +336,7 @@ def __init__(self):
337336
"host": os.environ.get("MPD_HOST", "localhost"),
338337
"port": int(os.environ.get("MPD_PORT", 6600)),
339338
"password": "",
339+
"played_ratio_threshold": 0.85,
340340
}
341341
)
342342
mpd_config["password"].redact = True

docs/changelog.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ New features:
3030
:bug:`5829`
3131
* :doc:`plugins/mbcollection`: When getting the user collections, only consider
3232
collections of releases, and ignore collections of other entity types.
33+
* :doc:`plugins/mpdstats`: Add new configuration option,
34+
``played_ratio_threshold``, to allow configuring the percentage the song must
35+
be played for it to be counted as played instead of skipped.
3336

3437
Bug fixes:
3538

docs/plugins/mpdstats.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ configuration file. The available options are:
5858
Default: ``yes``.
5959
- **rating_mix**: Tune the way rating is calculated (see below).
6060
Default: 0.75.
61+
- **played_ratio_threshold**: If a song was played for less than this percentage
62+
of its duration it will be considered a skip.
63+
Default: 0.85
6164

6265
A Word on Ratings
6366
-----------------

0 commit comments

Comments
 (0)