[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
0

Configure Feed

Select the types of activity you want to include in your feed.

refactor(musicbrainz): Rename recording mbid property to recording

So that introducing trackId isn't confusing

FoxxMD (Jan 19, 2026, 6:09 PM UTC) 0b51c3a5 9ccdd53b

+26 -26
+3 -3
src/backend/common/transforms/MusicbrainzTransformer.ts
··· 407 407 if(logPreMbid) { 408 408 const a = play.data.meta?.brainz?.artist; 409 409 const parts: string[] = [ 410 - `Recording ${play.data.meta?.brainz?.track ?? '(None)'}`, 410 + `Recording ${play.data.meta?.brainz?.recording ?? '(None)'}`, 411 411 `Release ${play.data.meta?.brainz?.album ?? '(None)'}`, 412 412 `Artists ${a === undefined || a.length === 0 ? '(None)' : a.join(', ')}`, 413 413 `ISRC ${play.data.isrc ?? '(None)'}` ··· 494 494 } = {} 495 495 } = play; 496 496 497 - using.push(brainz.track !== undefined ? 'mbidrecording' : 'title'); 497 + using.push(brainz.recording !== undefined ? 'mbidrecording' : 'title'); 498 498 using.push(brainz.album !== undefined ? 'mbidrelease' : 'album'); 499 499 using.push((brainz.artist ?? []).length > 0 ? 'mbidartist' : 'artist'); 500 500 ··· 511 511 } 512 512 513 513 public async searchByRecordingMbid(play: PlayObject, stageConfig: MusicbrainzTransformerDataStage): Promise<IRecordingMSList> { 514 - if(play.data.meta?.brainz?.track !== undefined) { 514 + if(play.data.meta?.brainz?.recording !== undefined) { 515 515 this.logger.debug({labels: ['MBID Search']},'Searching with Recording MBID'); 516 516 return await this.api.searchByRecording(play, {using: ['mbidrecording']}); 517 517 }
+3 -3
src/backend/common/vendor/LastfmApiClient.ts
··· 448 448 if(nonEmptyStringOrDefault(mbid) !== undefined) { 449 449 play.data.meta = { 450 450 brainz: { 451 - track: mbid 451 + recording: mbid 452 452 } 453 453 }; 454 454 } ··· 467 467 playDate, 468 468 meta: { 469 469 brainz: { 470 - track: mbid 470 + recording: mbid 471 471 } = {}, 472 472 } = {} 473 473 } = {} ··· 553 553 const brainz: BrainzMeta = removeUndefinedKeys({ 554 554 album: nonEmptyStringOrDefault<undefined>(albumMbid), 555 555 artist: splitByFirstFound<undefined>(artistMbid, [',',';'], undefined), 556 - track: nonEmptyStringOrDefault<undefined>(mbid) 556 + recording: nonEmptyStringOrDefault<undefined>(mbid) 557 557 }); 558 558 559 559 const play: PlayObject = {
+2 -2
src/backend/common/vendor/ListenbrainzApiClient.ts
··· 777 777 ...minTrackData, 778 778 additional_info: { 779 779 duration: play.data.duration !== undefined ? Math.round(duration) : undefined, 780 - track_mbid: brainz.track, 781 - recording_mbid: brainz.track, 780 + track_mbid: brainz.recording, 781 + recording_mbid: brainz.recording, 782 782 artist_mbids: brainz.artist, 783 783 release_mbid: brainz.album, 784 784 release_group_mbid: brainz.releaseGroup,
+1 -1
src/backend/common/vendor/bluesky/AbstractBlueSkyApiClient.ts
··· 69 69 submissionClientAgent: `multi-scrobbler/${getRoot().items.version}`, 70 70 musicServiceBaseDomain: musicServiceToCononical(play.meta.musicService) ?? play.meta.musicService, 71 71 isrc: play.data.isrc, 72 - recordingMbId: play.data.meta?.brainz?.track, 72 + recordingMbId: play.data.meta?.brainz?.recording, 73 73 releaseMbId: play.data.meta?.brainz?.album 74 74 }; 75 75
+1 -1
src/backend/common/vendor/koito/KoitoApiClient.ts
··· 200 200 if (obj.track.musicbrainz_id !== null) { 201 201 play.data.meta = { 202 202 brainz: { 203 - track: obj.track.musicbrainz_id 203 + recording: obj.track.musicbrainz_id 204 204 } 205 205 } 206 206 }
+3 -3
src/backend/common/vendor/musicbrainz/MusicbrainzApiClient.ts
··· 213 213 const query: Record<string, any> = { 214 214 }; 215 215 216 - if(play.data?.meta?.brainz?.track !== undefined && using.includes('mbidrecording')) { 217 - query.recording_mbid = play.data.meta.brainz.track 216 + if(play.data?.meta?.brainz?.recording !== undefined && using.includes('mbidrecording')) { 217 + query.recording_mbid = play.data.meta.brainz.recording 218 218 } 219 219 if(play.data?.meta?.brainz?.album !== undefined && using.includes('mbidrelease')) { 220 220 query.release_mbid = play.data.meta.brainz.album ··· 375 375 isrc: data.isrcs !== undefined && data.isrcs.length > 0 ? data.isrcs[0] : undefined, 376 376 meta: { 377 377 brainz: { 378 - track: data.id, 378 + recording: data.id, 379 379 artist: data["artist-credit"] !== undefined ? data["artist-credit"].map(x => x.artist.id) : undefined, 380 380 albumArtist: albumArtistIds, 381 381 album: album !== undefined ? album.id : undefined,
+2 -2
src/backend/sources/JellyfinApiSource.ts
··· 429 429 meta.album = ProviderIds.MusicBrainzAlbum; 430 430 } 431 431 if(ProviderIds.MusicBrainzTrack !== undefined) { 432 - meta.track = ProviderIds.MusicBrainzTrack; 432 + meta.recording = ProviderIds.MusicBrainzTrack; 433 433 } 434 434 if(ProviderIds.MusicBrainzTrack !== undefined) { 435 - meta.track = ProviderIds.MusicBrainzTrack; 435 + meta.recording = ProviderIds.MusicBrainzTrack; 436 436 } 437 437 if(ProviderIds.MusicBrainzArtist !== undefined) { 438 438 meta.artist = [ProviderIds.MusicBrainzArtist];
+1 -1
src/backend/sources/MPDSource.ts
··· 181 181 const brainz: BrainzMeta = { 182 182 albumArtist: [musicbrainz_albumartistid], 183 183 album: musicbrainz_albumid, 184 - track: musicbrainz_trackid, 184 + recording: musicbrainz_trackid, 185 185 }; 186 186 if(musicbrainz_artistid !== undefined) { 187 187 brainz.artist = [musicbrainz_artistid];
+1 -1
src/backend/sources/PlexApiSource.ts
··· 418 418 const prevBrainzMeta = sessionData[0].play.data.meta.brainz ?? {}; 419 419 sessionData[0].play.data.meta.brainz = { 420 420 ...prevBrainzMeta, 421 - track: trackMbId, 421 + recording: trackMbId, 422 422 album: albumMbId, 423 423 // Plex doesn't track MBIDs for track artists, so we use the 424 424 // album artist MBID instead.
+2 -2
src/backend/tests/lastfm/lastfm.test.ts
··· 27 27 28 28 expect(play.data.meta?.brainz?.album).to.be.undefined; 29 29 expect(play.data.meta?.brainz?.artist).to.be.undefined; 30 - expect(play.data.meta?.brainz?.track).to.be.undefined; 30 + expect(play.data.meta?.brainz?.recording).to.be.undefined; 31 31 }); 32 32 33 33 it('Sets brainz if any mbid is not undefined', function() { ··· 42 42 43 43 const toTrack = generateLastfmTrackObject(); 44 44 toTrack.mbid = generateMbid(); 45 - expect(formatPlayObj(toTrack).data.meta?.brainz?.track).to.not.be.undefined; 45 + expect(formatPlayObj(toTrack).data.meta?.brainz?.recording).to.not.be.undefined; 46 46 }); 47 47 48 48 it('Sets artist correctly from #text or name', function() {
+1 -1
src/backend/tests/listenbrainz/listenbrainz.test.ts
··· 136 136 // @ts-expect-error wrong on purpose 137 137 artist: 'fad8967c-a327-4af5-a64a-d4de66ece652;100846a7-06f6-4129-97ce-4409b9a9a311', 138 138 album: '2eb6a8fb-14f6-436e-9bdf-2f9d0d8cbae0', 139 - track: '677862e0-3603-4120-8c44-ee9a70893647', 139 + recording: '677862e0-3603-4120-8c44-ee9a70893647', 140 140 releaseGroup: 'bd3bb964-6da7-4d59-b0aa-f8bf639cd419' 141 141 } 142 142 }
+1 -1
src/backend/tests/musicbrainz/musicbrainz.test.ts
··· 117 117 album: "Fake", 118 118 meta: { 119 119 brainz: { 120 - track: '026fa041-3917-4c73-9079-ed16e36f20f8' 120 + recording: '026fa041-3917-4c73-9079-ed16e36f20f8' 121 121 } 122 122 } 123 123 },
+1 -1
src/backend/tests/tealfm/tealfm.test.ts
··· 31 31 32 32 expect(play.data.meta.brainz).to.not.be.undefined; 33 33 expect(play.data.meta.brainz.album).eq(rec.value.releaseMbId); 34 - expect(play.data.meta.brainz.track).eq(rec.value.recordingMbId); 34 + expect(play.data.meta.brainz.recording).eq(rec.value.recordingMbId); 35 35 expect(play.data.meta.brainz.artist).eql(rec.value.artists.map(x => x.artistMbId)); 36 36 expect(play.data.isrc).eq(rec.value.isrc); 37 37 });
+2 -2
src/backend/tests/utils/PlayTestUtils.ts
··· 176 176 for(const i of include) { 177 177 switch(i) { 178 178 case 'track': 179 - if(play.data.meta?.brainz?.track === undefined) { 179 + if(play.data.meta?.brainz?.recording === undefined) { 180 180 play.data.meta = { 181 181 ...(play.data.meta ?? {}), 182 182 brainz: { 183 183 ...(play.data.meta?.brainz ?? {}), 184 - track: generateMbid() 184 + recording: generateMbid() 185 185 } 186 186 } 187 187 }
+1 -1
src/backend/utils.ts
··· 604 604 return missing; 605 605 } 606 606 const { 607 - track, 607 + recording: track, 608 608 album, 609 609 artist 610 610 } = play.data.meta.brainz;
+1 -1
src/core/Atomic.ts
··· 124 124 * */ 125 125 album?: string 126 126 /** Unique track id, recording_mbid */ 127 - track?: string 127 + recording?: string 128 128 /** 129 129 * 130 130 * The "consolidated" album like --> "The Wall" by "Pink Floyd" */