diff --git a/services/recorder.js b/services/recorder.js index 798b0af..11dd8a6 100644 --- a/services/recorder.js +++ b/services/recorder.js @@ -62,7 +62,7 @@ class Recorder { this.#sessions.add(session); } - return { session, media, tracker, extraDuration: 0 } + return { session, media, tracker, extraDuration: 0, scrobble: null } } #listen(context, timestamp) { @@ -85,11 +85,15 @@ class Recorder { const progressDiff = Math.max(0, Math.min(current.progress - previous.progress, timeDiff)); session.playDuration += progressDiff; session.pauseDuration += timeDiff - progressDiff; - + const canScrobble = this.#canScrobble(session, current, previous); if (canScrobble || current.id != previous.id) { - context.extraDuration = Math.min(current.progress, timeDiff - (previous.duration - previous.progress)); + context.extraDuration = Math.max(Math.min(current.progress, timeDiff - (previous.duration - previous.progress)), 0); + context.extraDuration += Math.max(0, session.playDuration - previous.duration); session.lastScrobbleTimestamp = timestamp; + + if (canScrobble) + context.scrobble = previous; } session.lastUpdateTimestamp = timestamp; @@ -106,11 +110,11 @@ class Recorder { const newPlayback = current == null || current.progress < previous.progress; const canBeScrobbled = session.playDuration > scrobbleDuration * 1000 || session.playDuration / previous.duration > scrobblePercent / 100.0; - return newPlayback && canBeScrobbled; + return newPlayback && canBeScrobbled || session.playDuration >= previous.duration; } async #scrobble(context) { - this.#logger.info(context, "Scrobble"); + this.#logger.info(context.scrobble, "Scrobble"); for (var scrobblerName of context.tracker.scrobblerNames) { const scrobbler = this.#scrobblers.find(s => s.name == scrobblerName); @@ -120,7 +124,9 @@ class Recorder { } try { - await scrobbler.scrobble(context.media, Date.now() - Math.min(context.media.duration, context.session.playDuration)); + const duration = context.session.playDuration; + const start = Date.now() - context.session.playDuration - context.session.pauseDuration; + await scrobbler.scrobble(context.scrobble, duration, start); } catch (ex) { this.#logger.error(ex, "Could not send to maloja."); } diff --git a/services/scrobblers/maloja-scrobbler.js b/services/scrobblers/maloja-scrobbler.js index 24c9675..763759d 100644 --- a/services/scrobblers/maloja-scrobbler.js +++ b/services/scrobblers/maloja-scrobbler.js @@ -23,7 +23,7 @@ class MalojaScrobbler { return this.#config.name; } - async scrobble(song, progress, start) { + async scrobble(song, duration, start) { const url = new URL(this.#config.url); url.pathname += "/apis/mlj_1/newscrobble"; url.search = "?key=" + this.#config.token; @@ -31,9 +31,9 @@ class MalojaScrobbler { title: song.name, album: song.album, artists: song.artists, - duration: Math.round(progress / 1000), + duration: Math.round(duration / 1000), length: Math.round(song.duration / 1000), - //time: start + time: Math.round(start / 1000) }); this.#counter++;