diff --git a/src/servers/sidecar/music/indexer.ts b/src/servers/sidecar/music/indexer.ts index 0743627f..213f1540 100644 --- a/src/servers/sidecar/music/indexer.ts +++ b/src/servers/sidecar/music/indexer.ts @@ -9,7 +9,7 @@ import { homedir } from 'node:os'; // (relative to the Music root): // // DATA_PATH/music/cache//meta.json { path, cover?, tracks: [{ file, title, artist, albumArtist, -// album, track, year, durationSec, lyrics?:'lrc'|'txt' }], +// album, track, disc?, year, durationSec, lyrics?:'lrc'|'txt' }], // videos?: [{ file, title, durationSec, width, height, poster? }], // images?: [{ file }] } (phone IndexMeta schema) // DATA_PATH/music/cache//cover.jpg compressed (<=600px, jpeg q5) @@ -89,6 +89,7 @@ export type IndexTrack = { albumArtist?: string; album?: string; track?: string; + disc?: number; // disc / part-of-set number, from ID3 TPOS (the `disc` tag "n" or "n/total") year?: string; durationSec?: number; lyrics?: 'lrc' | 'txt'; // available lyrics format ('lrc' = synced/timestamped); text via /lyrics. Absent = none. @@ -344,6 +345,8 @@ async function ffprobeTrack(absPath: string, file: string): Promise<{ track: Ind for (const [k, val] of Object.entries(fmt.tags ?? {})) tags[k.toLowerCase()] = val; const durNum = fmt.duration ? Math.round(parseFloat(fmt.duration)) : undefined; const yearMatch = tags.date?.match(/\d{4}/); + // Disc / part-of-set from ID3 TPOS (ffprobe surfaces it as `disc`, "n" or "n/total"). + const discNum = tags.disc ? parseInt(tags.disc.split('/')[0]!.trim(), 10) : NaN; // Embedded lyrics: USLT/foobar keys — `lyrics`, `lyrics-`, `unsyncedlyrics`. let lyricsText: string | undefined; for (const [k, val] of Object.entries(tags)) { @@ -360,6 +363,7 @@ async function ffprobeTrack(absPath: string, file: string): Promise<{ track: Ind albumArtist: tags.album_artist || tags.albumartist || undefined, album: tags.album || undefined, track: tags.track || undefined, + disc: Number.isFinite(discNum) ? discNum : undefined, year: yearMatch ? yearMatch[0] : undefined, durationSec: Number.isFinite(durNum) ? durNum : undefined, },