fix artist name joining from mbz

This commit is contained in:
jeffvli
2026-02-06 22:29:16 -08:00
parent a547be1577
commit f04ea3bca0
+397 -390
View File
@@ -1,392 +1,333 @@
import { IArtist, IRelease, IMedium, ITrack, IWork } from 'musicbrainz-api';
import { IArtist, IMedium, IRelease, ITrack, IWork } from 'musicbrainz-api';
import {
IRelationWithWork,
MUSICBRAINZ_ID_PREFIX,
} from '/@/renderer/features/musicbrainz/api/musicbrainz-api';
import { RelatedArtist, Song, LibraryItem, ServerType, Album } from '/@/shared/types/domain-types';
import { Album, LibraryItem, RelatedArtist, ServerType, Song } from '/@/shared/types/domain-types';
export function collectWorksFromRelease(release: IRelease): IWork[] {
const works: IWork[] = [];
const seenIds = new Set<string>();
for (const medium of release.media ?? []) {
for (const track of medium.tracks ?? []) {
const recording = track.recording;
const relations = (recording as { relations?: IRelationWithWork[] })?.relations ?? [];
for (const rel of relations) {
const work = (rel as IRelationWithWork).work;
if (work?.id && !seenIds.has(work.id)) {
seenIds.add(work.id);
works.push(work);
}
}
}
}
return works;
}
export function getImageUrl(releaseId: string): string {
return `https://coverartarchive.org/release/${releaseId}/front-250.jpg`;
}
export function getMbzReleaseIdFromAlbumId(albumId: string): null | string {
if (!albumId.startsWith(MUSICBRAINZ_ID_PREFIX)) return null;
return albumId.slice(MUSICBRAINZ_ID_PREFIX.length);
}
// function getImageUrlByReleaseGroupId(releaseGroupId: string): string {
// return `https://coverartarchive.org/release-group/${releaseGroupId}/front-250.jpg`;
// }
// const MBZ_COUNTRY_CODES = {
// AD: 'Andorra',
// AE: 'United Arab Emirates',
// AF: 'Afghanistan',
// AG: 'Antigua and Barbuda',
// AI: 'Anguilla',
// AL: 'Albania',
// AM: 'Armenia',
// AN: 'Netherlands Antilles',
// AO: 'Angola',
// AQ: 'Antarctica',
// AR: 'Argentina',
// AS: 'American Samoa',
// AT: 'Austria',
// AU: 'Australia',
// AW: 'Aruba',
// AX: 'Åland Islands',
// AZ: 'Azerbaijan',
// BA: 'Bosnia and Herzegovina',
// BB: 'Barbados',
// BD: 'Bangladesh',
// BE: 'Belgium',
// BF: 'Burkina Faso',
// BG: 'Bulgaria',
// BH: 'Bahrain',
// BI: 'Burundi',
// BJ: 'Benin',
// BL: 'Saint Barthélemy',
// BM: 'Bermuda',
// BN: 'Brunei',
// BO: 'Bolivia',
// BQ: 'Bonaire, Sint Eustatius and Saba',
// BR: 'Brazil',
// BS: 'Bahamas',
// BT: 'Bhutan',
// BV: 'Bouvet Island',
// BW: 'Botswana',
// BY: 'Belarus',
// BZ: 'Belize',
// CA: 'Canada',
// CC: 'Cocos (Keeling) Islands',
// CD: 'Democratic Republic of the Congo',
// CF: 'Central African Republic',
// CG: 'Congo',
// CH: 'Switzerland',
// CI: "Côte d'Ivoire",
// CK: 'Cook Islands',
// CL: 'Chile',
// CM: 'Cameroon',
// CN: 'China',
// CO: 'Colombia',
// CR: 'Costa Rica',
// CS: 'Serbia and Montenegro',
// CU: 'Cuba',
// CV: 'Cape Verde',
// CW: 'Curaçao',
// CX: 'Christmas Island',
// CY: 'Cyprus',
// CZ: 'Czechia',
// DE: 'Germany',
// DJ: 'Djibouti',
// DK: 'Denmark',
// DM: 'Dominica',
// DO: 'Dominican Republic',
// DZ: 'Algeria',
// EC: 'Ecuador',
// EE: 'Estonia',
// EG: 'Egypt',
// EH: 'Western Sahara',
// ER: 'Eritrea',
// ES: 'Spain',
// ET: 'Ethiopia',
// FI: 'Finland',
// FJ: 'Fiji',
// FK: 'Falkland Islands',
// FM: 'Federated States of Micronesia',
// FO: 'Faroe Islands',
// FR: 'France',
// GA: 'Gabon',
// GB: 'United Kingdom',
// GD: 'Grenada',
// GE: 'Georgia',
// GF: 'French Guiana',
// GG: 'Guernsey',
// GH: 'Ghana',
// GI: 'Gibraltar',
// GL: 'Greenland',
// GM: 'Gambia',
// GN: 'Guinea',
// GP: 'Guadeloupe',
// GQ: 'Equatorial Guinea',
// GR: 'Greece',
// GS: 'South Georgia and the South Sandwich Islands',
// GT: 'Guatemala',
// GU: 'Guam',
// GW: 'Guinea-Bissau',
// GY: 'Guyana',
// HK: 'Hong Kong',
// HM: 'Heard Island and McDonald Islands',
// HN: 'Honduras',
// HR: 'Croatia',
// HT: 'Haiti',
// HU: 'Hungary',
// ID: 'Indonesia',
// IE: 'Ireland',
// IL: 'Israel',
// IM: 'Isle of Man',
// IN: 'India',
// IO: 'British Indian Ocean Territory',
// IQ: 'Iraq',
// IR: 'Iran',
// IS: 'Iceland',
// IT: 'Italy',
// JE: 'Jersey',
// JM: 'Jamaica',
// JO: 'Jordan',
// JP: 'Japan',
// KE: 'Kenya',
// KG: 'Kyrgyzstan',
// KH: 'Cambodia',
// KI: 'Kiribati',
// KM: 'Comoros',
// KN: 'Saint Kitts and Nevis',
// KP: 'North Korea',
// KR: 'South Korea',
// KW: 'Kuwait',
// KY: 'Cayman Islands',
// KZ: 'Kazakhstan',
// LA: 'Laos',
// LB: 'Lebanon',
// LC: 'Saint Lucia',
// LI: 'Liechtenstein',
// LK: 'Sri Lanka',
// LR: 'Liberia',
// LS: 'Lesotho',
// LT: 'Lithuania',
// LU: 'Luxembourg',
// LV: 'Latvia',
// LY: 'Libya',
// MA: 'Morocco',
// MC: 'Monaco',
// MD: 'Moldova',
// ME: 'Montenegro',
// MF: 'Saint Martin (French part)',
// MG: 'Madagascar',
// MH: 'Marshall Islands',
// MK: 'North Macedonia',
// ML: 'Mali',
// MM: 'Myanmar',
// MN: 'Mongolia',
// MO: 'Macao',
// MP: 'Northern Mariana Islands',
// MQ: 'Martinique',
// MR: 'Mauritania',
// MS: 'Montserrat',
// MT: 'Malta',
// MU: 'Mauritius',
// MV: 'Maldives',
// MW: 'Malawi',
// MX: 'Mexico',
// MY: 'Malaysia',
// MZ: 'Mozambique',
// NA: 'Namibia',
// NC: 'New Caledonia',
// NE: 'Niger',
// NF: 'Norfolk Island',
// NG: 'Nigeria',
// NI: 'Nicaragua',
// NL: 'Netherlands',
// NO: 'Norway',
// NP: 'Nepal',
// NR: 'Nauru',
// NU: 'Niue',
// NZ: 'New Zealand',
// OM: 'Oman',
// PA: 'Panama',
// PE: 'Peru',
// PF: 'French Polynesia',
// PG: 'Papua New Guinea',
// PH: 'Philippines',
// PK: 'Pakistan',
// PL: 'Poland',
// PM: 'Saint Pierre and Miquelon',
// PN: 'Pitcairn',
// PR: 'Puerto Rico',
// PS: 'Palestine',
// PT: 'Portugal',
// PW: 'Palau',
// PY: 'Paraguay',
// QA: 'Qatar',
// RE: 'Réunion',
// RO: 'Romania',
// RS: 'Serbia',
// RU: 'Russia',
// RW: 'Rwanda',
// SA: 'Saudi Arabia',
// SB: 'Solomon Islands',
// SC: 'Seychelles',
// SD: 'Sudan',
// SE: 'Sweden',
// SG: 'Singapore',
// SH: 'Saint Helena, Ascension and Tristan da Cunha',
// SI: 'Slovenia',
// SJ: 'Svalbard and Jan Mayen',
// SK: 'Slovakia',
// SL: 'Sierra Leone',
// SM: 'San Marino',
// SN: 'Senegal',
// SO: 'Somalia',
// SR: 'Suriname',
// SS: 'South Sudan',
// ST: 'Sao Tome and Principe',
// SU: 'Soviet Union',
// SV: 'El Salvador',
// SX: 'Sint Maarten (Dutch part)',
// SY: 'Syria',
// SZ: 'Eswatini',
// TC: 'Turks and Caicos Islands',
// TD: 'Chad',
// TF: 'French Southern Territories',
// TG: 'Togo',
// TH: 'Thailand',
// TJ: 'Tajikistan',
// TK: 'Tokelau',
// TL: 'Timor-Leste',
// TM: 'Turkmenistan',
// TN: 'Tunisia',
// TO: 'Tonga',
// TR: 'Turkey',
// TT: 'Trinidad and Tobago',
// TV: 'Tuvalu',
// TW: 'Taiwan',
// TZ: 'Tanzania',
// UA: 'Ukraine',
// UG: 'Uganda',
// UM: 'United States Minor Outlying Islands',
// US: 'United States',
// UY: 'Uruguay',
// UZ: 'Uzbekistan',
// VA: 'Vatican City',
// VC: 'Saint Vincent and The Grenadines',
// VE: 'Venezuela',
// VG: 'British Virgin Islands',
// VI: 'U.S. Virgin Islands',
// VN: 'Vietnam',
// VU: 'Vanuatu',
// WF: 'Wallis and Futuna',
// WS: 'Samoa',
// XC: 'Czechoslovakia',
// XE: 'Europe',
// XG: 'East Germany',
// XK: 'Kosovo',
// XW: '[Worldwide]',
// YE: 'Yemen',
// YT: 'Mayotte',
// YU: 'Yugoslavia',
// ZA: 'South Africa',
// ZM: 'Zambia',
// ZW: 'Zimbabwe',
// };
// const MBZ_RELEASE_TYPES = {
// album: 'album',
// audiobook: 'audiobook',
// 'audio drama': 'audio drama',
// broadcast: 'broadcast',
// compilation: 'compilation',
// demo: 'demo',
// 'dj-mix': 'dj-mix',
// ep: 'ep',
// 'field recording': 'field recording',
// interview: 'interview',
// live: 'live',
// 'mixtape/street': 'mixtape/street',
// other: 'other',
// remix: 'remix',
// single: 'single',
// soundtrack: 'soundtrack',
// spokenword: 'spokenword',
// };
export function isMbzAlbumId(albumId: string): boolean {
return albumId.startsWith(MUSICBRAINZ_ID_PREFIX);
}
function getImageUrlByReleaseGroupId(releaseGroupId: string): string {
return `https://coverartarchive.org/release-group/${releaseGroupId}/front-250.jpg`;
}
const MBZ_COUNTRY_CODES = {
AD: 'Andorra',
AE: 'United Arab Emirates',
AF: 'Afghanistan',
AG: 'Antigua and Barbuda',
AI: 'Anguilla',
AL: 'Albania',
AM: 'Armenia',
AN: 'Netherlands Antilles',
AO: 'Angola',
AQ: 'Antarctica',
AR: 'Argentina',
AS: 'American Samoa',
AT: 'Austria',
AU: 'Australia',
AW: 'Aruba',
AX: 'Åland Islands',
AZ: 'Azerbaijan',
BA: 'Bosnia and Herzegovina',
BB: 'Barbados',
BD: 'Bangladesh',
BE: 'Belgium',
BF: 'Burkina Faso',
BG: 'Bulgaria',
BH: 'Bahrain',
BI: 'Burundi',
BJ: 'Benin',
BL: 'Saint Barthélemy',
BM: 'Bermuda',
BN: 'Brunei',
BO: 'Bolivia',
BQ: 'Bonaire, Sint Eustatius and Saba',
BR: 'Brazil',
BS: 'Bahamas',
BT: 'Bhutan',
BV: 'Bouvet Island',
BW: 'Botswana',
BY: 'Belarus',
BZ: 'Belize',
CA: 'Canada',
CC: 'Cocos (Keeling) Islands',
CD: 'Democratic Republic of the Congo',
CF: 'Central African Republic',
CG: 'Congo',
CH: 'Switzerland',
CI: "Côte d'Ivoire",
CK: 'Cook Islands',
CL: 'Chile',
CM: 'Cameroon',
CN: 'China',
CO: 'Colombia',
CR: 'Costa Rica',
CS: 'Serbia and Montenegro',
CU: 'Cuba',
CV: 'Cape Verde',
CW: 'Curaçao',
CX: 'Christmas Island',
CY: 'Cyprus',
CZ: 'Czechia',
DE: 'Germany',
DJ: 'Djibouti',
DK: 'Denmark',
DM: 'Dominica',
DO: 'Dominican Republic',
DZ: 'Algeria',
EC: 'Ecuador',
EE: 'Estonia',
EG: 'Egypt',
EH: 'Western Sahara',
ER: 'Eritrea',
ES: 'Spain',
ET: 'Ethiopia',
FI: 'Finland',
FJ: 'Fiji',
FK: 'Falkland Islands',
FM: 'Federated States of Micronesia',
FO: 'Faroe Islands',
FR: 'France',
GA: 'Gabon',
GB: 'United Kingdom',
GD: 'Grenada',
GE: 'Georgia',
GF: 'French Guiana',
GG: 'Guernsey',
GH: 'Ghana',
GI: 'Gibraltar',
GL: 'Greenland',
GM: 'Gambia',
GN: 'Guinea',
GP: 'Guadeloupe',
GQ: 'Equatorial Guinea',
GR: 'Greece',
GS: 'South Georgia and the South Sandwich Islands',
GT: 'Guatemala',
GU: 'Guam',
GW: 'Guinea-Bissau',
GY: 'Guyana',
HK: 'Hong Kong',
HM: 'Heard Island and McDonald Islands',
HN: 'Honduras',
HR: 'Croatia',
HT: 'Haiti',
HU: 'Hungary',
ID: 'Indonesia',
IE: 'Ireland',
IL: 'Israel',
IM: 'Isle of Man',
IN: 'India',
IO: 'British Indian Ocean Territory',
IQ: 'Iraq',
IR: 'Iran',
IS: 'Iceland',
IT: 'Italy',
JE: 'Jersey',
JM: 'Jamaica',
JO: 'Jordan',
JP: 'Japan',
KE: 'Kenya',
KG: 'Kyrgyzstan',
KH: 'Cambodia',
KI: 'Kiribati',
KM: 'Comoros',
KN: 'Saint Kitts and Nevis',
KP: 'North Korea',
KR: 'South Korea',
KW: 'Kuwait',
KY: 'Cayman Islands',
KZ: 'Kazakhstan',
LA: 'Laos',
LB: 'Lebanon',
LC: 'Saint Lucia',
LI: 'Liechtenstein',
LK: 'Sri Lanka',
LR: 'Liberia',
LS: 'Lesotho',
LT: 'Lithuania',
LU: 'Luxembourg',
LV: 'Latvia',
LY: 'Libya',
MA: 'Morocco',
MC: 'Monaco',
MD: 'Moldova',
ME: 'Montenegro',
MF: 'Saint Martin (French part)',
MG: 'Madagascar',
MH: 'Marshall Islands',
MK: 'North Macedonia',
ML: 'Mali',
MM: 'Myanmar',
MN: 'Mongolia',
MO: 'Macao',
MP: 'Northern Mariana Islands',
MQ: 'Martinique',
MR: 'Mauritania',
MS: 'Montserrat',
MT: 'Malta',
MU: 'Mauritius',
MV: 'Maldives',
MW: 'Malawi',
MX: 'Mexico',
MY: 'Malaysia',
MZ: 'Mozambique',
NA: 'Namibia',
NC: 'New Caledonia',
NE: 'Niger',
NF: 'Norfolk Island',
NG: 'Nigeria',
NI: 'Nicaragua',
NL: 'Netherlands',
NO: 'Norway',
NP: 'Nepal',
NR: 'Nauru',
NU: 'Niue',
NZ: 'New Zealand',
OM: 'Oman',
PA: 'Panama',
PE: 'Peru',
PF: 'French Polynesia',
PG: 'Papua New Guinea',
PH: 'Philippines',
PK: 'Pakistan',
PL: 'Poland',
PM: 'Saint Pierre and Miquelon',
PN: 'Pitcairn',
PR: 'Puerto Rico',
PS: 'Palestine',
PT: 'Portugal',
PW: 'Palau',
PY: 'Paraguay',
QA: 'Qatar',
RE: 'Réunion',
RO: 'Romania',
RS: 'Serbia',
RU: 'Russia',
RW: 'Rwanda',
SA: 'Saudi Arabia',
SB: 'Solomon Islands',
SC: 'Seychelles',
SD: 'Sudan',
SE: 'Sweden',
SG: 'Singapore',
SH: 'Saint Helena, Ascension and Tristan da Cunha',
SI: 'Slovenia',
SJ: 'Svalbard and Jan Mayen',
SK: 'Slovakia',
SL: 'Sierra Leone',
SM: 'San Marino',
SN: 'Senegal',
SO: 'Somalia',
SR: 'Suriname',
SS: 'South Sudan',
ST: 'Sao Tome and Principe',
SU: 'Soviet Union',
SV: 'El Salvador',
SX: 'Sint Maarten (Dutch part)',
SY: 'Syria',
SZ: 'Eswatini',
TC: 'Turks and Caicos Islands',
TD: 'Chad',
TF: 'French Southern Territories',
TG: 'Togo',
TH: 'Thailand',
TJ: 'Tajikistan',
TK: 'Tokelau',
TL: 'Timor-Leste',
TM: 'Turkmenistan',
TN: 'Tunisia',
TO: 'Tonga',
TR: 'Turkey',
TT: 'Trinidad and Tobago',
TV: 'Tuvalu',
TW: 'Taiwan',
TZ: 'Tanzania',
UA: 'Ukraine',
UG: 'Uganda',
UM: 'United States Minor Outlying Islands',
US: 'United States',
UY: 'Uruguay',
UZ: 'Uzbekistan',
VA: 'Vatican City',
VC: 'Saint Vincent and The Grenadines',
VE: 'Venezuela',
VG: 'British Virgin Islands',
VI: 'U.S. Virgin Islands',
VN: 'Vietnam',
VU: 'Vanuatu',
WF: 'Wallis and Futuna',
WS: 'Samoa',
XC: 'Czechoslovakia',
XE: 'Europe',
XG: 'East Germany',
XK: 'Kosovo',
XW: '[Worldwide]',
YE: 'Yemen',
YT: 'Mayotte',
YU: 'Yugoslavia',
ZA: 'South Africa',
ZM: 'Zambia',
ZW: 'Zimbabwe',
};
const MBZ_RELEASE_TYPES = {
album: 'album',
audiobook: 'audiobook',
'audio drama': 'audio drama',
broadcast: 'broadcast',
compilation: 'compilation',
demo: 'demo',
'dj-mix': 'dj-mix',
ep: 'ep',
'field recording': 'field recording',
interview: 'interview',
live: 'live',
'mixtape/street': 'mixtape/street',
other: 'other',
remix: 'remix',
single: 'single',
soundtrack: 'soundtrack',
spokenword: 'spokenword',
};
function normalizeArtistCreditToRelatedArtists(
artistCredit: Array<{ artist: IArtist; name: string }>,
): RelatedArtist[] {
return artistCredit.map((ac) => ({
id: `musicbrainz-${ac.artist.id}`,
imageId: null,
imageUrl: null,
name: ac.name || ac.artist.name,
userFavorite: false,
userRating: null,
}));
}
function normalizeRecordingToSong(
release: IRelease,
medium: IMedium,
track: ITrack,
albumArtistName: string,
albumArtists: RelatedArtist[],
albumId: string,
imageUrl: null | string,
releaseDate: null | string,
releaseYear: null | number,
): Song {
const recording = track.recording;
const trackArtistCredit = track['artist-credit'] ?? recording['artist-credit'] ?? [];
const artistName =
trackArtistCredit.map((ac) => ac.name).join('') || recording.title || track.title;
const artists = normalizeArtistCreditToRelatedArtists(
trackArtistCredit as Array<{ artist: IArtist; name: string }>,
);
const durationMilliseconds = track.length || recording.length || 0;
const trackNumber = track.position || parseInt(track.number, 10) || 0;
return {
_itemType: LibraryItem.SONG,
_serverId: 'musicbrainz',
_serverType: ServerType.EXTERNAL,
album: release.title,
albumArtistName,
albumArtists,
albumId,
artistName,
artists,
bitDepth: null,
bitRate: 0,
bpm: null,
channels: null,
comment: null,
compilation: null,
container: null,
createdAt: '',
discNumber: medium.position || 1,
discSubtitle: medium.title || null,
duration: durationMilliseconds,
explicitStatus: null,
gain: null,
genres: [],
id: `musicbrainz-${release.id}-${recording.id}-${track.position}-${track.number}`,
imageId: null,
imageUrl,
lastPlayedAt: null,
lyrics: null,
mbzRecordingId: recording.id,
mbzTrackId: track.id,
name: track.title || recording.title,
participants: {},
path: null,
peak: null,
playCount: 0,
releaseDate,
releaseYear,
sampleRate: null,
size: 0,
sortName: track.title || recording.title,
tags: null,
trackNumber,
trackSubtitle: null,
updatedAt: '',
userFavorite: false,
userRating: null,
};
}
export function normalizeReleaseToAlbum(release: IRelease): Album {
const releaseGroup = release['release-group'];
const artistCredit = release['artist-credit'] ?? releaseGroup?.['artist-credit'] ?? [];
const albumArtistName = artistCredit.map((ac) => ac.name).join('') || release.title;
const albumArtistName = artistCredit
.map((entry) => `${entry.name}${entry.joinphrase ?? ''}`)
.join(' ');
const albumArtists: RelatedArtist[] = (artistCredit as { artist: IArtist; name: string }[]).map(
(ac) => ({
id: `musicbrainz-${ac.artist.id}`,
@@ -476,23 +417,89 @@ export function normalizeReleaseToAlbum(release: IRelease): Album {
version: null,
};
}
export function collectWorksFromRelease(release: IRelease): IWork[] {
const works: IWork[] = [];
const seenIds = new Set<string>();
for (const medium of release.media ?? []) {
for (const track of medium.tracks ?? []) {
const recording = track.recording;
const relations = (recording as { relations?: IRelationWithWork[] })?.relations ?? [];
for (const rel of relations) {
const work = (rel as IRelationWithWork).work;
if (work?.id && !seenIds.has(work.id)) {
seenIds.add(work.id);
works.push(work);
}
}
}
}
return works;
function normalizeArtistCreditToRelatedArtists(
artistCredit: Array<{ artist: IArtist; name: string }>,
): RelatedArtist[] {
return artistCredit.map((ac) => ({
id: `musicbrainz-${ac.artist.id}`,
imageId: null,
imageUrl: null,
name: ac.name || ac.artist.name,
userFavorite: false,
userRating: null,
}));
}
function normalizeRecordingToSong(
release: IRelease,
medium: IMedium,
track: ITrack,
albumArtistName: string,
albumArtists: RelatedArtist[],
albumId: string,
imageUrl: null | string,
releaseDate: null | string,
releaseYear: null | number,
): Song {
const recording = track.recording;
const trackArtistCredit = track['artist-credit'] ?? recording['artist-credit'] ?? [];
const artistName = trackArtistCredit
.map((entry) => `${entry.name}${entry.joinphrase ?? ''}`)
.join(' ');
const artists = normalizeArtistCreditToRelatedArtists(
trackArtistCredit as Array<{ artist: IArtist; name: string }>,
);
const durationMilliseconds = track.length || recording.length || 0;
const trackNumber = track.position || parseInt(track.number, 10) || 0;
return {
_itemType: LibraryItem.SONG,
_serverId: 'musicbrainz',
_serverType: ServerType.EXTERNAL,
album: release.title,
albumArtistName,
albumArtists,
albumId,
artistName,
artists,
bitDepth: null,
bitRate: 0,
bpm: null,
channels: null,
comment: null,
compilation: null,
container: null,
createdAt: '',
discNumber: medium.position || 1,
discSubtitle: medium.title || null,
duration: durationMilliseconds,
explicitStatus: null,
gain: null,
genres: [],
id: `musicbrainz-${release.id}-${recording.id}-${track.position}-${track.number}`,
imageId: null,
imageUrl,
lastPlayedAt: null,
lyrics: null,
mbzRecordingId: recording.id,
mbzTrackId: track.id,
name: track.title || recording.title,
participants: {},
path: null,
peak: null,
playCount: 0,
releaseDate,
releaseYear,
sampleRate: null,
size: 0,
sortName: track.title || recording.title,
tags: null,
trackNumber,
trackSubtitle: null,
updatedAt: '',
userFavorite: false,
userRating: null,
};
}