Improved time upkeep for playing and pausing.
This commit is contained in:
parent
5100d18ac6
commit
0bfbc36952
@ -2,7 +2,8 @@ class Session {
|
||||
#id = null;
|
||||
#started = null;
|
||||
#current = null;
|
||||
#lastScrobble = null;
|
||||
lastScrobbleTimestamp = 0;
|
||||
lastUpdateTimestamp = 0;
|
||||
pauseDuration = 0;
|
||||
playDuration = 0;
|
||||
|
||||
@ -26,14 +27,6 @@ class Session {
|
||||
get started() {
|
||||
return this.#started;
|
||||
}
|
||||
|
||||
get lastScrobbleTimestamp() {
|
||||
return this.#lastScrobble;
|
||||
}
|
||||
|
||||
set lastScrobbleTimestamp(value) {
|
||||
this.#lastScrobble = value;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Session;
|
@ -8,7 +8,6 @@ class Recorder {
|
||||
#scrobblers = [];
|
||||
#config = null;
|
||||
#logger = null;
|
||||
#lastTick = null;
|
||||
|
||||
constructor(sessions, trackers, scrobblers, config, logger) {
|
||||
this.#sessions = sessions;
|
||||
@ -17,12 +16,10 @@ class Recorder {
|
||||
this.#scrobblers = scrobblers;
|
||||
this.#config = config;
|
||||
this.#logger = logger;
|
||||
this.#lastTick = Date.now();
|
||||
}
|
||||
|
||||
async record() {
|
||||
const now = Date.now();
|
||||
const timeDiff = now - this.#lastTick;
|
||||
const media = await this.#trackers.poll();
|
||||
const contexts = media.map(m => this.#fetchContext(m));
|
||||
|
||||
@ -31,25 +28,30 @@ class Recorder {
|
||||
const stopped = sessionIds.filter(sessionId => !contexts.some(context => sessionId == context.session.id))
|
||||
.map(sessionId => this.#sessions.get(sessionId))
|
||||
.map(session => this.#fetchContext(session.playing));
|
||||
const contextEnded = stopped.filter(context => this.#canScrobble(context.session, null, context.session.playing, now));
|
||||
const contextEnded = stopped.filter(context => this.#canScrobble(context.session, null, context.session.playing));
|
||||
|
||||
for (let context of contextEnded)
|
||||
context.session.playDuration = now - (context.session.lastScrobbleTimestamp || context.session.started) - context.session.pauseDuration;
|
||||
|
||||
// Find ongoing sessions that have moved on to the next song.
|
||||
const finishedPlaying = contexts.filter(context => this.#listen(context, now, timeDiff));
|
||||
const finishedPlaying = contexts.filter(context => this.#listen(context, now));
|
||||
|
||||
// Scrobble
|
||||
const scrobbling = finishedPlaying.concat(contextEnded);
|
||||
for (let context of scrobbling)
|
||||
for (let context of scrobbling) {
|
||||
await this.#scrobble(context);
|
||||
|
||||
if (context.session.playing == null)
|
||||
continue;
|
||||
|
||||
context.session.playDuration = context.extraDuration;
|
||||
context.session.pauseDuration = 0;
|
||||
}
|
||||
|
||||
// Remove dead sessions.
|
||||
for (let context of stopped) {
|
||||
this.#sessions.remove(context.session.id);
|
||||
}
|
||||
|
||||
this.#lastTick = now;
|
||||
}
|
||||
|
||||
#fetchContext(media) {
|
||||
@ -60,39 +62,41 @@ class Recorder {
|
||||
this.#sessions.add(session);
|
||||
}
|
||||
|
||||
return { session, media, tracker }
|
||||
return { session, media, tracker, extraDuration: 0 }
|
||||
}
|
||||
|
||||
#listen(context, timestamp, timeDiff) {
|
||||
#listen(context, timestamp) {
|
||||
const session = context.session;
|
||||
const current = context.media;
|
||||
const previous = context.session.playing;
|
||||
session.playing = current;
|
||||
session.playDuration = timestamp - (session.lastScrobbleTimestamp || session.started) - session.pauseDuration;
|
||||
|
||||
if (!previous) {
|
||||
this.#logger.info(current, "A new session has started.");
|
||||
session.lastUpdateTimestamp = timestamp;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (session.playing.state == "paused" || previous.state == "paused")
|
||||
session.pauseDuration += timeDiff - (session.playing.progress - previous.progress);
|
||||
const updated = current.progress != previous.progress || current.id != previous.id || current.state != previous.state;
|
||||
if (!updated)
|
||||
return false;
|
||||
|
||||
if (this.#canScrobble(session, current, previous, timestamp)) {
|
||||
session.pauseDuration = 0;
|
||||
session.lastScrobbleTimestamp = timestamp - (timeDiff - (previous.duration - previous.progress));
|
||||
return true;
|
||||
} else if (current.progress < previous.progress && session.playing.id != previous.id) {
|
||||
session.pauseDuration = 0;
|
||||
if (current.progress < timeDiff)
|
||||
session.lastScrobbleTimestamp = timestamp - session.playing.progress;
|
||||
else
|
||||
const timeDiff = timestamp - session.lastUpdateTimestamp;
|
||||
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));
|
||||
session.lastScrobbleTimestamp = timestamp;
|
||||
}
|
||||
return false;
|
||||
|
||||
session.lastUpdateTimestamp = timestamp;
|
||||
return canScrobble;
|
||||
}
|
||||
|
||||
#canScrobble(session, current, previous, timestamp) {
|
||||
#canScrobble(session, current, previous) {
|
||||
if (previous == null)
|
||||
return false;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user