First commit
This commit is contained in:
parent
1adfb8e005
commit
7d9800806a
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"apiKey": "YOUR_LASTFM_API_KEY",
|
||||||
|
"username": "YOUR_LASTFM_USERNAME"
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
const axios = require('axios');
|
||||||
|
const sharp = require('sharp');
|
||||||
|
const getColors = require('get-image-colors');
|
||||||
|
const rp = require("request-promise");
|
||||||
|
const fs = require('fs');
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
|
||||||
|
const config = JSON.parse(fs.readFileSync("config.json"));
|
||||||
|
const updateInterval = 5000;
|
||||||
|
|
||||||
|
async function processAlbumCover(url) {
|
||||||
|
try {
|
||||||
|
console.log(`Processing album cover from URL: ${url}`);
|
||||||
|
|
||||||
|
const response = await axios.get(url, { responseType: 'arraybuffer' });
|
||||||
|
const imageBuffer = Buffer.from(response.data, 'binary');
|
||||||
|
|
||||||
|
const imageSharp = sharp(imageBuffer);
|
||||||
|
const metadata = await imageSharp.metadata();
|
||||||
|
|
||||||
|
if (metadata.format !== 'jpeg' && metadata.format !== 'jpg') {
|
||||||
|
throw new Error('Not a JPEG image');
|
||||||
|
}
|
||||||
|
|
||||||
|
const dominantColor = await getDominantColor(imageBuffer);
|
||||||
|
|
||||||
|
const resizedBuffer = await imageSharp
|
||||||
|
.resize({ width: 1920, height: 1080, fit: 'inside' })
|
||||||
|
.toBuffer();
|
||||||
|
|
||||||
|
const resizedMetadata = await sharp(resizedBuffer).metadata();
|
||||||
|
|
||||||
|
const extendByX = Math.round((1920 - resizedMetadata.width) / 2);
|
||||||
|
const extendByY = Math.round((1080 - resizedMetadata.height) / 2);
|
||||||
|
|
||||||
|
const outputBuffer = await sharp(resizedBuffer)
|
||||||
|
.extend({
|
||||||
|
top: extendByY,
|
||||||
|
bottom: extendByY,
|
||||||
|
left: extendByX,
|
||||||
|
right: extendByX,
|
||||||
|
background: dominantColor
|
||||||
|
})
|
||||||
|
.toBuffer();
|
||||||
|
|
||||||
|
return outputBuffer;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error processing album cover from URL: ${url}`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getDominantColor(imageBuffer) {
|
||||||
|
const imageSharp = sharp(imageBuffer);
|
||||||
|
const { channels } = await imageSharp.stats();
|
||||||
|
|
||||||
|
const redAvg = channels[0].mean;
|
||||||
|
const greenAvg = channels[1].mean;
|
||||||
|
const blueAvg = channels[2].mean;
|
||||||
|
|
||||||
|
return {
|
||||||
|
r: Math.round(redAvg),
|
||||||
|
g: Math.round(greenAvg),
|
||||||
|
b: Math.round(blueAvg)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setAsWallpaper(buffer) {
|
||||||
|
try {
|
||||||
|
await fs.promises.writeFile('current_album_cover.png', buffer);
|
||||||
|
exec('feh --bg-center current_album_cover.png');
|
||||||
|
console.log("Wallpaper set using feh.");
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error setting wallpaper:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchCurrentScrobble(user) {
|
||||||
|
let lastTrackName;
|
||||||
|
let lastArtist;
|
||||||
|
try {
|
||||||
|
const optionsGetTrack = {
|
||||||
|
uri: `http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${user}&api_key=${config.apiKey}&format=json&limit=1`,
|
||||||
|
json: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const lastTrack = await rp(optionsGetTrack);
|
||||||
|
|
||||||
|
if (!lastTrack.recenttracks || !lastTrack.recenttracks.track || !lastTrack.recenttracks.track[0]) {
|
||||||
|
console.error("No valid track data in recenttracks");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastArtist = lastTrack.recenttracks.track[0].artist["#text"];
|
||||||
|
lastTrackName = lastTrack.recenttracks.track[0].name;
|
||||||
|
|
||||||
|
const images = lastTrack.recenttracks.track[0].image;
|
||||||
|
|
||||||
|
let coverURL = null;
|
||||||
|
for (const img of images) {
|
||||||
|
if (img.size === 'extralarge' || img.size === 'mega') {
|
||||||
|
coverURL = img["#text"].trim();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coverURL) {
|
||||||
|
coverURL = coverURL.replace('300x300', '1000x1000');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coverURL) {
|
||||||
|
const processedCover = await processAlbumCover(coverURL);
|
||||||
|
await setAsWallpaper(processedCover);
|
||||||
|
console.log("Wallpaper updated to album cover of: " + lastTrackName);
|
||||||
|
} else {
|
||||||
|
console.error(`Cover URL not found for track: ${lastTrackName}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to fetch current scrobble`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startFetching() {
|
||||||
|
setInterval(async () => {
|
||||||
|
await fetchCurrentScrobble(config.username);
|
||||||
|
}, updateInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
startFetching();
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.5.1",
|
||||||
|
"file-type": "^18.5.0",
|
||||||
|
"get-image-colors": "^4.0.1",
|
||||||
|
"request-promise": "^4.2.6",
|
||||||
|
"sharp": "^0.32.6"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue