2
music mood
gerrit edited this page 2026-06-24 10:24:27 +00:00
const axios = require('axios');
// --- CONFIGURATION ---
const LIDARR_URL = 'http://localhost:8686';
const LIDARR_API_KEY = 'YOUR_LIDARR_API_KEY';
const OLLAMA_URL = 'http://localhost:11434';
const OLLAMA_MODEL = 'llama3'; // or mistral, qwen2.5, phi3, etc.
/**
* 1. Fetch comprehensive Artist data from Lidarr
*/
async function getLidarrArtist(artistId) {
try {
const response = await axios.get(`${LIDARR_URL}/api/v1/artist/${artistId}`, {
params: { apikey: LIDARR_API_KEY }
});
const artist = response.data;
return {
name: artist.artistName,
genres: artist.genres || [],
overview: artist.overview || "No biography available."
};
} catch (error) {
console.error(`❌ Error fetching Lidarr artist (${artistId}):`, error.message);
throw error;
}
}
/**
* 2. Send purely local database context to Ollama
*/
async function generateMoodWithOllama(context) {
const prompt = `
You are an expert musicologist. Analyze the local media library metadata provided below to generate a highly nuanced emotional profile for this album.
--- LIBRARY METADATA ---
Artist Name: ${context.artistName}
Album Title: ${context.albumTitle}
Artist Genres/Styles: ${context.genres.join(', ')}
Artist Biography & Context: ${context.biography}
-----------------------
Respond ONLY with a valid JSON object matching the schema below. Do not include introductory text, conversational remarks, or markdown formatting blocks.
Schema:
{
"dominantMood": "The single most prevailing emotion of the album",
"subtextMoods": ["Up to three supporting emotional textures"],
"situationalContext": "The ideal setting, activity, or scenario to listen to this music",
"emotionalVibe": "A one-sentence breakdown of the sonic and emotional journey"
}
`;
try {
const response = await axios.post(`${OLLAMA_URL}/api/generate`, {
model: OLLAMA_MODEL,
prompt: prompt,
stream: false,
format: 'json' // Enforces JSON constraints natively inside Ollama
});
return JSON.parse(response.data.response);
} catch (error) {
console.error('❌ Error communicating with Ollama:', error.message);
throw error;
}
}
/**
* 3. Pipeline Orchestrator
*/
async function runMoodPipeline(lidarrArtistId, albumTitle) {
console.log(`🚀 Processing Album: "${albumTitle}" (Lidarr Artist ID: ${lidarrArtistId})...`);
try {
// Step 1: Pull data from Lidarr
const artist = await getLidarrArtist(lidarrArtistId);
console.log(`🎵 Found local artist entry: ${artist.name}`);
// Step 2: Bundle context
const contextBundle = {
artistName: artist.name,
albumTitle: albumTitle,
genres: artist.genres,
biography: artist.overview
};
// Step 3: Prompt local LLM
console.log(`🤖 Analyzing data via local Ollama instance (${OLLAMA_MODEL})...`);
const moodProfile = await generateMoodWithOllama(contextBundle);
console.log('\n✅ Successfully Generated Mood Profile:');
console.log(JSON.stringify(moodProfile, null, 2));
return moodProfile;
} catch (error) {
console.error('❌ Pipeline execution failed.');
}
}
// --- EXECUTION EXAMPLE ---
// Replace '1' with an actual Artist ID from your Lidarr library
runMoodPipeline(1, 'Kid A');