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 · 85 lines
TypeScript
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485import 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()) { 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(); }}