Musicsitetest / server.js
riddhiman's picture
Update server.js
0861f14 verified
const express = require('express');
const mm = require('music-metadata');
const util = require('util');
const fs = require('fs');
const path = require('path');
const sharp = require('sharp');
const app = express();
const PORT = process.env.PORT || 7860;
app.use(express.static('public'));
app.use('/music', express.static('music'));
const SUPPORTED_FORMATS = ['.mp3', '.mp4', '.wav', '.flac', '.ogg', '.opus']; // Add or remove formats as needed
function isSupportedFormat(filename) {
const ext = path.extname(filename).toLowerCase();
return SUPPORTED_FORMATS.includes(ext);
}
app.get('/tracks', async (req, res) => {
const searchQuery = (req.query.search || '').toLowerCase();
const pageNumber = parseInt(req.query.page) || 1;
const pageSize = 5;
fs.readdir('music', async (err, files) => {
if (err) {
console.error('Error reading music directory', err);
return res.sendStatus(500);
}
// If there's a search query, filter files by it
let filteredFiles = files.filter(file => isSupportedFormat(file));
if (searchQuery) {
filteredFiles = filteredFiles.filter(file => file.toLowerCase().includes(searchQuery));
}
const pageStart = (pageNumber - 1) * pageSize;
const pageEnd = pageStart + pageSize;
// Slice files for pagination after filtering, ONLY if not searching. If searching, ignore pagination and send first 5 results.
const pagedFiles = filteredFiles.slice(searchQuery ? 0 : pageStart, searchQuery ? pageSize : pageEnd);
const trackDetails = [];
for (const file of pagedFiles) {
const filePath = path.join(__dirname, 'music', file);
try {
const metadata = await mm.parseFile(filePath, { native: true });
let artwork = '';
// Fallback path for default icon
const fallbackIconPath = path.join(__dirname, 'music', 'icon.png');
try {
let imageBuffer;
if (metadata.common.picture && metadata.common.picture[0]) {
imageBuffer = await sharp(metadata.common.picture[0].data)
.resize(256, 256, { fit: 'inside' })
.toBuffer();
} else {
// Use the default icon if no album art is present
imageBuffer = await sharp(fallbackIconPath)
.resize(256, 256, { fit: 'inside' })
.toBuffer();
}
// Determine the image format
const imageFormat = metadata.common.picture && metadata.common.picture[0] ? metadata.common.picture[0].format : 'image/png';
artwork = `data:${imageFormat};base64,${imageBuffer.toString('base64')}`;
} catch (e) {
console.error(`Error processing artwork for file: ${file}`, e);
}
trackDetails.push({filename: file, artwork});
} catch (error) {
console.error(`Error reading metadata for file: ${file}`, error);
}
}
res.json({tracks: trackDetails, total: filteredFiles.length});
});
});
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));