Skip to content

Commit

Permalink
RealMAX - Utilize MusicBrainz isrcs & MusicBrainz fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Inrixia committed Jun 20, 2024
1 parent 8bab6bc commit c9e59ad
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 16 deletions.
16 changes: 11 additions & 5 deletions lib/TrackCache/ExtendedTrackItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { MusicBrainz } from "../musicbrainzApi";
import { Recording } from "../musicbrainzApi/types/Recording";
import { Release } from "../musicbrainzApi/types/UPCData";
import { TrackItemCache } from "./TrackItemCache";
import { undefinedError } from "../undefinedError";
import { undefinedWarn } from "../undefinedError";

export class ExtendedTrackItem {
public readonly trackId: ItemId;
Expand All @@ -24,7 +24,13 @@ export class ExtendedTrackItem {
if (trackId === undefined) return undefined;
return this._cache[trackId] ?? (this._cache[trackId] = new this(trackId));
}
public async isrcs(): Promise<string[] | undefined> {
const trackItem = this.trackItem();
if (trackItem?.isrc !== undefined) return [trackItem.isrc];

const recording = await this.recording();
if (recording?.isrcs !== undefined) return recording.isrcs;
}
public trackItem(): TrackItem | undefined {
if (this._trackItem !== undefined) return this._trackItem;

Expand All @@ -39,14 +45,14 @@ export class ExtendedTrackItem {
public async recording(): Promise<Recording | undefined> {
if (this._recording !== undefined) return this._recording;

this._recording = await MusicBrainz.getRecording(this.trackItem()?.isrc).catch(undefinedError);
this._recording = await MusicBrainz.getRecording(this.trackItem()?.isrc).catch(undefinedWarn("MusicBrainz.getRecording"));
if (this._recording !== undefined) return this._recording;

const trackItem = this.trackItem();
if (trackItem === undefined) return undefined;

const album = await this.album();
const albumRelease = await MusicBrainz.getAlbumRelease(album?.id).catch(undefinedError);
const releaseAlbum = await this.releaseAlbum();
const albumRelease = await MusicBrainz.getAlbumRelease(releaseAlbum?.id).catch(undefinedWarn("MusicBrainz.getAlbumRelease"));

const volumeNumber = (trackItem.volumeNumber ?? 1) - 1;
const trackNumber = (trackItem.trackNumber ?? 1) - 1;
Expand All @@ -57,7 +63,7 @@ export class ExtendedTrackItem {
if (this._releaseAlbum !== undefined) return this._releaseAlbum;

const album = await this.album();
const upcData = await MusicBrainz.getUPCData(album?.upc).catch(undefinedError);
const upcData = await MusicBrainz.getUPCData(album?.upc).catch(undefinedWarn("MusicBrainz.getUPCData"));

return (this._releaseAlbum = upcData?.releases?.[0]);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/TrackCache/TrackItemCache.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { store } from "@neptune";
import { TrackItem, MediaItem, ItemId } from "neptune-types/tidal";
import { undefinedError } from "../undefinedError";
import { undefinedWarn } from "../undefinedError";
export class TrackItemCache {
private static readonly _cache: Record<ItemId, TrackItem> = {};
public static get(trackId?: ItemId) {
Expand Down
2 changes: 1 addition & 1 deletion lib/musicbrainzApi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class MusicBrainz {
if (upc === undefined) return undefined;
return fetchCachedJson<UPCData>(`https://musicbrainz.org/ws/2/release/?query=barcode:${upc}&fmt=json`);
}
public static async getAlbumRelease(albumId?: number) {
public static async getAlbumRelease(albumId?: string) {
if (albumId === undefined) return undefined;
return fetchCachedJson<ReleaseData>(`https://musicbrainz.org/ws/2/release/${albumId}?inc=recordings+isrcs&fmt=json`);
}
Expand Down
5 changes: 3 additions & 2 deletions lib/undefinedError.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const undefinedError = (err: Error) => {
console.error(err);
export const undefinedWarn = (context?: string) => (err: Error) => {
if (context !== undefined) console.warn(context, err);
else console.warn(err);
return undefined;
};
2 changes: 1 addition & 1 deletion plugins/LastFM/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export { Settings } from "./Settings";

// @ts-expect-error Remove this when types are available
import { storage } from "@plugin";
import { undefinedError } from "../../../lib/undefinedError";
import { undefinedWarn } from "../../../lib/undefinedError";
import { ExtendedTrackItem } from "../../../lib/TrackCache/ExtendedTrackItem";

let totalPlayTime = 0;
Expand Down
17 changes: 11 additions & 6 deletions plugins/RealMAX/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { TrackItemCache } from "../../../lib/TrackCache/TrackItemCache";
import { fetchIsrcIterable } from "../../../lib/tidalDevApi/isrc";
import { actions, intercept, store } from "@neptune";
import { PlaybackContext } from "../../../lib/AudioQualityTypes";
import { ExtendedTrackItem } from "../../../lib/TrackCache/ExtendedTrackItem";

const hasHiRes = (trackItem: TrackItem) => {
const tags = trackItem.mediaMetadata?.tags;
Expand All @@ -18,14 +19,18 @@ class MaxTrack {
const idMapping = MaxTrack._idMap[itemId];
if (idMapping !== undefined) return idMapping;

const trackItem = TrackItemCache.get(itemId);
if (trackItem === undefined || trackItem.isrc === undefined || hasHiRes(trackItem)) {
return (this._idMap[itemId] = Promise.resolve(false));
}
const extTrackItem = await ExtendedTrackItem.get(itemId);
const trackItem = extTrackItem?.trackItem();
if (trackItem !== undefined && hasHiRes(trackItem)) return false;

const isrcs = await extTrackItem?.isrcs();
if (isrcs === undefined) return (this._idMap[itemId] = Promise.resolve(false));

return (this._idMap[itemId] = (async () => {
for await (const { resource } of fetchIsrcIterable(trackItem.isrc!)) {
if (resource?.id !== undefined && hasHiRes(resource)) return resource.id;
for (const isrc of isrcs) {
for await (const { resource } of fetchIsrcIterable(isrc)) {
if (resource?.id !== undefined && hasHiRes(resource)) return resource.id;
}
}
return false;
})());
Expand Down

0 comments on commit c9e59ad

Please sign in to comment.