Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/FoxxMD/multi-scrobbler. Scrobble plays from multiple sources to multiple clients docs.multi-scrobbler.app
deezer docker jellyfin koito lastfm listenbrainz maloja mopidy mpris music music-assistant plex scrobble self-hosted spotify subsonic tautulli youtube-music
Something went wrong. Try again.
2.4 kB · 87 lines
TypeScript
at playEdit
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687import dayjs, { type Dayjs } from "dayjs";import { SimpleIntervalJob, Task, ToadScheduler } from "toad-scheduler";
export const RT_TICK_DEFAULT = 500;let RT_TICK = 500;
export const setRtTick = (tick: number) => { RT_TICK = tick;}
export abstract class RealtimePlayer {
//logger: Logger; scheduler: ToadScheduler = new ToadScheduler();
protected position: number = 0; private clockTS: Dayjs = dayjs();
protected constructor(/* logger: Logger */) { this.position = 0; const job = new SimpleIntervalJob({ milliseconds: RT_TICK, runImmediately: true }, new Task('updatePos', () => { // in production RT_TICK and the diff between now and clockTS should always be the same // but in order to mock for testing (where we manipulate Date now()) the source of truth // needs to come from TS rather than simple TICK increase this.setPosition() //this.position += Math.abs(dayjs().diff(this.clockTS, 'ms')); // RT_TICK
}), { id: 'rt' }); this.scheduler.addSimpleIntervalJob(job); this.scheduler.stop(); }
[Symbol.dispose]() { this.scheduler.stop(); for(const job of this.scheduler.getAllJobs()) { if(job.id !== undefined) { this.scheduler.removeById(job.id); } } }
public play(position?: number) { if (position !== undefined) { this.position = position; } this.clockTS = dayjs(); this.scheduler.startById('rt'); }
public pause() { this.scheduler.stop(); }
public stop() { this.pause(); this.position = 0; }
public seek(position: number) { this.position = position; }
public getPosition(asSeconds: boolean = false) { if(this.position === 0 || this.position === undefined) { return 0; } return !asSeconds ? this.position : this.position / 1000; }
public setPosition(time?: number) { if(time === undefined) { this.position += Math.abs(dayjs().diff(this.clockTS, 'ms')); } else { this.position = time; } this.clockTS = dayjs(); }}
export class GenericRealtimePlayer extends RealtimePlayer { constructor(/* logger: Logger */) { super(); }}