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;