This commit is contained in:
2026-09-10 00:07:22 +02:00
parent 43ff87ed62
commit 73ffe02bbb
12 changed files with 1327 additions and 275 deletions
+35 -8
View File
@@ -354,9 +354,12 @@ export default new class queue {
}
async genThumbnail(filename, mime, itemid, link, pending = false, size = 512) {
const bDir = pending ? path.join(cfg.paths.pending, 'b') : cfg.paths.b;
const tDir = pending ? path.join(cfg.paths.pending, 't') : cfg.paths.t;
const cDir = pending ? path.join(cfg.paths.pending, 'ca') : cfg.paths.ca;
let bDir = pending ? path.join(cfg.paths.pending, 'b') : cfg.paths.b;
let tDir = pending ? path.join(cfg.paths.pending, 't') : cfg.paths.t;
let cDir = pending ? path.join(cfg.paths.pending, 'ca') : cfg.paths.ca;
try { bDir = await fs.promises.realpath(bDir); } catch (_) {}
try { tDir = await fs.promises.realpath(tDir); } catch (_) {}
try { cDir = await fs.promises.realpath(cDir); } catch (_) {}
const tmpFile = path.join(os.tmpdir(), itemid + '.png');
const tmpJpg = path.join(os.tmpdir(), itemid + '.jpg');
const thumbSize = (size && size > 128) ? size : 128;
@@ -372,7 +375,13 @@ export default new class queue {
}
} catch (e) {}
const outPath = path.join(tDir, itemid + '.webp');
let outPath = path.join(tDir, itemid + '.webp');
try {
const outStat = await fs.promises.lstat(outPath);
if (outStat.isSymbolicLink()) {
await fs.promises.unlink(outPath).catch(() => {});
}
} catch (_) {}
try {
@@ -457,17 +466,17 @@ export default new class queue {
else if (mime.startsWith('audio/')) {
let coverExtracted = false;
this._lastCoverExtracted = false; // Reset state for this call
if (link.match(/soundcloud/)) {
if (link && typeof link === 'string' && link.match(/soundcloud/)) {
const proxyArgs = (cfg.main.socks && cfg.main.socks !== 'undefined' && cfg.main.socks !== '') ? ['--proxy', cfg.main.socks.includes('://') ? cfg.main.socks : `socks5h://${cfg.main.socks}`] : [];
let cover = (await this.spawn('yt-dlp', [...proxyArgs, '-f', 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w', '--get-thumbnail', link])).stdout.trim().split('\n').map(l => l.trim()).filter(l => l.length > 0).pop();
if (!cover.match(/default_avatar/)) {
if (cover && !cover.match(/default_avatar/)) {
cover = cover.replace(/-(large|original)\./, '-t500x500.');
try {
const curlArgs = ['-s', '-L', cover, '-o', tmpJpg];
if (proxyArgs.length > 0) curlArgs.push(...proxyArgs);
await this.spawn('curl', curlArgs);
const size = (await fs.promises.stat(tmpJpg)).size;
if (size >= 0) {
if (size > 0) {
await this.spawn('magick', [tmpJpg, tmpFile]);
await this.spawn('magick', [tmpJpg, path.join(cDir, itemid + '.webp')]);
coverExtracted = true;
@@ -497,6 +506,17 @@ export default new class queue {
}
} catch (err) { }
}
// If no new cover art extracted, check if cover art was already saved previously in cDir
if (!coverExtracted) {
const existingCover = path.join(cDir, itemid + '.webp');
try {
const stat = await fs.promises.stat(existingCover);
if (stat.size > 0) {
await this.spawn('magick', [existingCover, tmpFile]);
coverExtracted = true;
}
} catch (_) { }
}
// If no cover art found, use audio.webp as the thumbnail
if (!coverExtracted) {
const audioFallback = path.join(cfg.paths.s, 'img', 'audio.webp');
@@ -641,9 +661,16 @@ export default new class queue {
async genBlurredThumbnail(itemid, pending = false) {
const tDir = pending ? path.join(cfg.paths.pending, 't') : cfg.paths.t;
let tDir = pending ? path.join(cfg.paths.pending, 't') : cfg.paths.t;
try { tDir = await fs.promises.realpath(tDir); } catch (_) {}
const src = path.join(tDir, `${itemid}.webp`);
const dst = path.join(tDir, `${itemid}_blur.webp`);
try {
const dstStat = await fs.promises.lstat(dst);
if (dstStat.isSymbolicLink()) {
await fs.promises.unlink(dst).catch(() => {});
}
} catch (_) {}
try {
await this.spawn('magick', [src, '-blur', '0x48', dst]);
return true;