Add per-kind stats, GIF hover playback, and static gif previews

This commit is contained in:
Fisto
2026-09-16 13:36:51 +02:00
parent 612b2504dc
commit 0081224954
13 changed files with 189 additions and 57 deletions
+20 -10
View File
@@ -3,12 +3,13 @@
* Rules: docs/media-scraper.md.
*/
import { copyFileSync, mkdirSync } from "node:fs";
import { copyFileSync, mkdirSync, rmSync } from "node:fs";
import { dirname, join } from "node:path";
import {
downloadGapMs,
downloadOne,
downloadPreview,
gifPoster,
probeDimensions,
videoPoster,
type DownloadOptions
@@ -378,21 +379,30 @@ export class ScrapeEngine {
const outcome = await downloadPreview(previewRow, join(dir, "thumbs"), options);
if (outcome.state === "downloaded" && outcome.hash) {
const ext = outcome.ext ?? "webp";
store.markPreview(row.id, { hash: outcome.hash, bytes: outcome.bytes ?? 0, ext });
let hash = outcome.hash;
let bytes = outcome.bytes ?? 0;
let ext = outcome.ext ?? "webp";
// Animated GIFs are kept static in the grid; hovering plays the original.
if (ext === "gif") {
const poster = await gifPoster(join(dir, "thumbs", `${hash}.gif`), join(dir, "thumbs"));
if (poster) {
rmSync(join(dir, "thumbs", `${hash}.gif`), { force: true });
hash = poster.hash;
bytes = poster.bytes;
ext = "webp";
}
}
store.markPreview(row.id, { hash, bytes, ext });
meta.previewed = (meta.previewed ?? 0) + 1;
// Embed thumbnails also land in the custom destination, so the download has a
// viewable poster for embeds while the media tab keeps its local copy.
if (options.destinationDir && row.source === "embed") {
const target = join(
options.destinationDir,
meta.id,
"thumbnails",
`${outcome.hash}.${ext}`
);
const target = join(options.destinationDir, meta.id, "thumbnails", `${hash}.${ext}`);
mkdirSync(dirname(target), { recursive: true });
copyFileSync(join(dir, "thumbs", `${outcome.hash}.${ext}`), target);
copyFileSync(join(dir, "thumbs", `${hash}.${ext}`), target);
}
} else {
store.markPreviewError(row.id, outcome.error ?? outcome.state);