Skip to content

Commit

Permalink
Merge pull request #212 from FoxxMD/playerStateCleanup
Browse files Browse the repository at this point in the history
feat(player): Real time positional player state
  • Loading branch information
FoxxMD authored Oct 25, 2024
2 parents da76945 + c498bde commit f308f71
Show file tree
Hide file tree
Showing 27 changed files with 645 additions and 343 deletions.
10 changes: 3 additions & 7 deletions src/backend/common/infrastructure/Atomic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Dayjs } from "dayjs";
import { Request, Response } from "express";
import { NextFunction, ParamsDictionary, Query } from "express-serve-static-core";
import { FixedSizeList } from 'fixed-size-list';
import { PlayMeta, PlayObject } from "../../../core/Atomic.js";
import { isPlayObject, PlayMeta, PlayObject } from "../../../core/Atomic.js";
import TupleMap from "../TupleMap.js";

export type SourceType =
Expand Down Expand Up @@ -122,13 +122,9 @@ export interface PlayerStateDataMaybePlay {
timestamp?: Dayjs
}

export const asPlayerStateData = (obj: object): obj is PlayerStateData => {
return 'platformId' in obj && 'play' in obj;
}
export const asPlayerStateData = (obj: object): obj is PlayerStateData => asPlayerStateDataMaybePlay(obj) && 'play' in obj && isPlayObject(obj.play)

export const asPlayerStateDataMaybePlay = (obj: object): obj is PlayerStateDataMaybePlay => {
return 'platformId' in obj;
}
export const asPlayerStateDataMaybePlay = (obj: object): obj is PlayerStateDataMaybePlay => 'platformId' in obj

export interface FormatPlayObjectOptions {
newFromSource?: boolean
Expand Down
4 changes: 2 additions & 2 deletions src/backend/sources/ChromecastSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { difference, genGroupIdStr, parseBool } from "../utils.js";
import { findCauseByReference } from "../utils/ErrorUtils.js";
import { discoveryAvahi, discoveryNative } from "../utils/MDNSUtils.js";
import { RecentlyPlayedOptions } from "./AbstractSource.js";
import MemorySource from "./MemorySource.js";
import { MemoryPositionalSource } from "./MemoryPositionalSource.js";

interface ChromecastDeviceInfo {
mdns: MdnsDeviceInfo
Expand All @@ -46,7 +46,7 @@ interface ChromecastDeviceInfo {
applications: Map<string, PlatformApplicationWithContext>
}

export class ChromecastSource extends MemorySource {
export class ChromecastSource extends MemoryPositionalSource {

declare config: ChromecastSourceConfig;

Expand Down
4 changes: 2 additions & 2 deletions src/backend/sources/JRiverSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { FormatPlayObjectOptions, InternalConfig } from "../common/infrastructur
import { JRiverSourceConfig } from "../common/infrastructure/config/source/jriver.js";
import { Info, JRiverApiClient, PLAYER_STATE } from "../common/vendor/JRiverApiClient.js";
import { RecentlyPlayedOptions } from "./AbstractSource.js";
import MemorySource from "./MemorySource.js";
import { MemoryPositionalSource } from "./MemoryPositionalSource.js";

export class JRiverSource extends MemorySource {
export class JRiverSource extends MemoryPositionalSource {
declare config: JRiverSourceConfig;

url: URL;
Expand Down
7 changes: 2 additions & 5 deletions src/backend/sources/JellyfinApiSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,11 @@ import {
import { JellyApiSourceConfig } from "../common/infrastructure/config/source/jellyfin.js";
import { combinePartsToString, genGroupIdStr, getPlatformIdFromData, joinedUrl, parseBool, } from "../utils.js";
import { parseArrayFromMaybeString } from "../utils/StringUtils.js";
import MemorySource from "./MemorySource.js";
import { PlayerStateOptions } from "./PlayerState/AbstractPlayerState.js";
import { JellyfinPlayerState } from "./PlayerState/JellyfinPlayerState.js";
import { MemoryPositionalSource } from "./MemoryPositionalSource.js";

const shortDeviceId = truncateStringToLength(10, '');

export default class JellyfinApiSource extends MemorySource {
export default class JellyfinApiSource extends MemoryPositionalSource {
users: string[] = [];

client: Jellyfin
Expand Down Expand Up @@ -476,7 +474,6 @@ export default class JellyfinApiSource extends MemorySource {
}
}

getNewPlayer = (logger: Logger, id: PlayPlatformId, opts: PlayerStateOptions) => new JellyfinPlayerState(logger, id, opts)
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/backend/sources/KodiSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { FormatPlayObjectOptions, InternalConfig } from "../common/infrastructur
import { KodiSourceConfig } from "../common/infrastructure/config/source/kodi.js";
import { KodiApiClient } from "../common/vendor/KodiApiClient.js";
import { RecentlyPlayedOptions } from "./AbstractSource.js";
import MemorySource from "./MemorySource.js";
import { MemoryPositionalSource } from "./MemoryPositionalSource.js";

export class KodiSource extends MemorySource {
export class KodiSource extends MemoryPositionalSource {
declare config: KodiSourceConfig;

client: KodiApiClient;
Expand Down
4 changes: 2 additions & 2 deletions src/backend/sources/MPDSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from "../common/infrastructure/config/source/mpd.js";
import { isPortReachable } from "../utils/NetworkUtils.js";
import { RecentlyPlayedOptions } from "./AbstractSource.js";
import MemorySource from "./MemorySource.js";
import { MemoryPositionalSource } from "./MemoryPositionalSource.js";

const mpdClient = mpdapiNS.default;

Expand All @@ -29,7 +29,7 @@ const CLIENT_PLAYER_STATE: Record<PlayerState, ReportedPlayerStatus> = {
'stop': REPORTED_PLAYER_STATUSES.stopped,
}

export class MPDSource extends MemorySource {
export class MPDSource extends MemoryPositionalSource {
declare config: MPDSourceConfig;

host?: string
Expand Down
9 changes: 9 additions & 0 deletions src/backend/sources/MemoryPositionalSource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Logger } from "@foxxmd/logging";
import { PlayPlatformId } from "../common/infrastructure/Atomic.js";
import MemorySource from "./MemorySource.js";
import { PlayerStateOptions } from "./PlayerState/AbstractPlayerState.js";
import { PositionalPlayerState } from "./PlayerState/PositionalPlayerState.js";

export class MemoryPositionalSource extends MemorySource {
getNewPlayer = (logger: Logger, id: PlayPlatformId, opts: PlayerStateOptions) => new PositionalPlayerState(logger, id, opts)
}
14 changes: 12 additions & 2 deletions src/backend/sources/MemorySource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export default class MemorySource extends AbstractSource {
return record;
}

getNewPlayer = (logger: Logger, id: PlayPlatformId, opts: PlayerStateOptions) => new GenericPlayerState(logger, id, opts)
getNewPlayer = (logger: Logger, id: PlayPlatformId, opts: PlayerStateOptions): AbstractPlayerState => new GenericPlayerState(logger, id, opts)

setNewPlayer = (idStr: string, logger: Logger, id: PlayPlatformId, opts: PlayerStateOptions = {}) => {
this.players.set(idStr, this.getNewPlayer(this.logger, id, {
Expand Down Expand Up @@ -167,7 +167,17 @@ export default class MemorySource extends AbstractSource {
}
incomingData = relevantDatas[0];

const [currPlay, prevPlay] = asPlayerStateDataMaybePlay(incomingData) ? player.setState(incomingData.status, incomingData.play) : player.setState(undefined, incomingData);
let playerState: PlayerStateDataMaybePlay;
if(asPlayerStateDataMaybePlay(incomingData)) {
playerState = incomingData;
} else {
playerState = {play: incomingData, platformId: getPlatformIdFromData(incomingData)};
}
if(playerState.position === undefined && playerState.play !== undefined && playerState.play.meta.trackProgressPosition !== undefined) {
playerState.position = playerState.play.meta?.trackProgressPosition;
}

const [currPlay, prevPlay] = player.update(playerState);
const candidate = prevPlay !== undefined ? prevPlay : currPlay;
const playChanged = prevPlay !== undefined;

Expand Down
4 changes: 2 additions & 2 deletions src/backend/sources/MopidySource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import {
} from "../common/infrastructure/Atomic.js";
import { MopidySourceConfig } from "../common/infrastructure/config/source/mopidy.js";
import { RecentlyPlayedOptions } from "./AbstractSource.js";
import MemorySource from "./MemorySource.js";
import { MemoryPositionalSource } from "./MemoryPositionalSource.js";

export class MopidySource extends MemorySource {
export class MopidySource extends MemoryPositionalSource {
declare config: MopidySourceConfig;

albumBlacklist: string[] = [];
Expand Down
4 changes: 2 additions & 2 deletions src/backend/sources/MusikcubeSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
} from "../common/infrastructure/config/source/musikcube.js";
import { sleep } from "../utils.js";
import { RecentlyPlayedOptions } from "./AbstractSource.js";
import MemorySource from "./MemorySource.js";
import { MemoryPositionalSource } from "./MemoryPositionalSource.js";

const CLIENT_STATE = {
0: 'connecting',
Expand All @@ -31,7 +31,7 @@ const CLIENT_STATE = {
3: 'closed'
}

export class MusikcubeSource extends MemorySource {
export class MusikcubeSource extends MemoryPositionalSource {
declare config: MusikcubeSourceConfig;

url: URL;
Expand Down
Loading

0 comments on commit f308f71

Please sign in to comment.