feat(metadata): optimize metadata fetching for MusicBrainz IDs with concurrent API calls and retain file path associations

This commit is contained in:
xtrullor73
2024-05-20 23:46:48 -07:00
parent e3bc3af46a
commit 3329fddcb1

View File

@@ -3,34 +3,45 @@ import getAlbumArt from "../../api/metadata/coverArtArchiveApi.js";
import getLyrics from '../../api/metadata/lyricOvhApi.js';
/**
* Adapter to handle retrieval of metadata for an array of MusicBrainz recording IDs.
* @function
* @param {string[]} recordingIds - An array of MusicBrainz recording IDs.
* @returns {Promise<Object[]>} A promise that resolves with an object of metadata.
* Adapter to handle retrieval of metadata for an array of objects containing MusicBrainz recording IDs and file paths.
* @param {Object[]} fileObjectsWithIds - An array of objects containing file paths and MusicBrainz recording IDs.
* @returns {Promise<Object[]>} A promise that resolves with an array of objects containing file paths, IDs, and metadata.
*/
export default async function getMetadata(recordingIds) {
export default async function getMetadata(fileObjectsWithIds) {
try {
if (!Array.isArray(recordingIds)) {
throw new Error('musicBrainzAdapter expects an array of recordingIds');
if (!Array.isArray(fileObjectsWithIds)) {
throw new Error('musicBrainzAdapter expects an array of objects with file paths and recording IDs');
}
// Prepare an object to hold the metadata results initialized as an array of Promises
const metadataPromises = recordingIds.map(async (recordingId) => {
const trackMetadata = await requestMetadata(recordingId);
const artist = trackMetadata['artist-credit']?.[0]?.name;
const title = trackMetadata.title;
const albumId = trackMetadata.releases[0].id
const metadataPromises = fileObjectsWithIds.map(async (objectWithId) => {
// Only attempt to retrieve metadata if an ID is present
const id = objectWithId.id;
if (id) {
try {
const trackMetadata = await requestMetadata(id);
const artist = trackMetadata['artist-credit']?.[0]?.name;
const title = trackMetadata.title;
const albumId = trackMetadata.releases[[0]]?.id;
// Assume getLyrics requires artist name and track name, which are to be obtained from the trackMetadata
const lyrics = await getLyrics(artist, title);
const albumArt = await getAlbumArt(albumId);
// Parallel requests for lyrics and album art, these are independent
const [lyrics, albumArtUrl] = await Promise.all([
getLyrics(artist, title),
albumId ? getAlbumArt(albumId) : null
]);
// Combine the track metadata with the lyrics
return {
...trackMetadata,
albumArt,
lyrics
};
return {
...objectWithId,
trackMetadata,
albumArtUrl,
lyrics
};
} catch (error) {
console.error(`Error retrieving metadata for ID ${objectWithId.id}:`, error);
return { ...objectWithId };
}
}
});
return await Promise.all(metadataPromises);