75 lines
2.2 KiB
JavaScript
75 lines
2.2 KiB
JavaScript
|
const plex = require("./plex");
|
||
|
const logger = require("./logging")
|
||
|
const config = require("../config/configuration");
|
||
|
|
||
|
const lastPlaying = {};
|
||
|
const lastScrobbleTimes = {};
|
||
|
|
||
|
async function poll() {
|
||
|
const now = Date.now();
|
||
|
const playing = [];
|
||
|
|
||
|
try {
|
||
|
const data = await plex.getCurrentlyPlaying();
|
||
|
playing.push.apply(playing, data);
|
||
|
} catch (ex) {
|
||
|
logger.error(ex, "Could not fetch currently playing data from Plex.");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (let media of playing) {
|
||
|
if (!lastScrobbleTimes[media.mediaKey]) {
|
||
|
lastScrobbleTimes[media.mediaKey] = 1;
|
||
|
}
|
||
|
|
||
|
const lastTrack = lastPlaying[media.sessionKey];
|
||
|
if (!lastTrack) {
|
||
|
logger.info(media, "A new session has started.");
|
||
|
} else {
|
||
|
if (checkIfCanScrobble(media, lastTrack, now)) {
|
||
|
logger.info(lastTrack, "Scrobble");
|
||
|
lastScrobbleTimes[lastTrack.mediaKey] = now;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
lastPlaying[media.sessionKey] = media;
|
||
|
}
|
||
|
|
||
|
// Scrobble then remove lingering sessions
|
||
|
for (let key in lastPlaying) {
|
||
|
if (!playing.some(p => p.sessionKey == key)) {
|
||
|
const track = lastPlaying[key];
|
||
|
if (checkIfCanScrobble(null, track, now)) {
|
||
|
logger.info(track, "Scrobble");
|
||
|
lastScrobbleTimes[track.mediaKey] = now;
|
||
|
}
|
||
|
delete lastPlaying[key];
|
||
|
logger.debug("Deleted old session.", key);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function checkIfCanScrobble(current, last, now) {
|
||
|
const scrobbleDuration = isInt(config.scrobble.duration) ? Number(config.scrobble.duration) : 30;
|
||
|
const scrobblePercent = isInt(config.scrobble.percent) ? Number(config.scrobble.percent) : 30;
|
||
|
|
||
|
if (last) {
|
||
|
const newPlayback = current == null || current.playtime < last.playtime;
|
||
|
const canBeScrobbled = last.playtime > scrobbleDuration * 1000 || last.playtime / last.duration > scrobblePercent;
|
||
|
|
||
|
if (newPlayback && canBeScrobbled) {
|
||
|
const sameSong = current != null && current.mediaKey == last.mediaKey;
|
||
|
const lastTime = lastScrobbleTimes[last.mediaKey];
|
||
|
return !sameSong || !lastTime || now - lastTime > scrobbleDuration;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
function isInt(value) {
|
||
|
return !isNaN(value) &&
|
||
|
parseInt(Number(value)) == value &&
|
||
|
!isNaN(parseInt(value, 10));
|
||
|
}
|
||
|
|
||
|
module.exports = poll;
|