spotifylookup/metasearcher.js

91 lines
2.5 KiB
JavaScript

const NodeID3 = require('node-id3');
const fs = require('fs').promises;
const path = require('path');
const { setupSpotify, spotifyApi } = require(path.join(__dirname, 'bits', 'spotify'));
const audPath = process.argv[2];
if (!audPath) {
throw new Error('No directory specified');
}
async function readTags(file) {
return new Promise((resolve) => {
NodeID3.read(file, {noRaw: true, exclude: ['image']}, function(err, tags) {
if (err) return resolve(null)
if (tags.image) tags.image = null;
if (tags.private) tags.private = null;
resolve(tags);
});
});
}
async function readAudioFiles() {
let fileAndMeta = [];
const contents = await fs.readdir(audPath);
for (const file of contents) {
const fullp = path.join(audPath, file);
const tags = await readTags(fullp);
fileAndMeta.push({
path: fullp,
tags: tags,
});
}
fileAndMeta = fileAndMeta.filter((item) => item.tags && item.tags.artist && item.tags.title);
await fs.writeFile('file-meta-cache.json', JSON.stringify(fileAndMeta, undefined, 2));
return fileAndMeta;
}
async function delay(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
let requestDelay = 100;
async function searchTrack(query) {
console.log('Searching for', query);
let returned
try {
returned = await spotifyApi.searchTracks(query, { limit: 5, market: 'EE' });
} catch (e) {
console.error(e);
console.log('We may have hit a rate limit');
console.log('Waiting 30 seconds for the rate limit window');
requestDelay = 1000;
await delay(30000);
return searchTrack(query);
}
await delay(requestDelay);
console.log('Got', returned.body.tracks.total, 'results');
return returned.body.tracks.items;
}
async function searchAllOfSpotify() {
await setupSpotify();
const audioFiles = await readAudioFiles();
let tracks = [];
let progress = 0;
let hits = 0;
for (const file of audioFiles) {
console.log('=> item %d of %d', (progress++), audioFiles.length);
const results = await searchTrack(`${file.tags.title} artist:${file.tags.artist}`);
if (results.length) {
hits++;
tracks.push({
file: file.path,
title: file.tags.title,
artist: file.tags.artist,
spotify: results,
});
}
}
console.log('Traversed %d audio files, of which %d had potential results from Spotify', audioFiles.length, hits);
await fs.writeFile('spotify.json', JSON.stringify(tracks, undefined, 2));
}
searchAllOfSpotify().catch(console.error);