Cache audio waveforms and rescue oversized GIF previews
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
gifPoster,
|
||||
previewGapMs,
|
||||
probeDimensions,
|
||||
remoteFrame,
|
||||
videoPoster,
|
||||
type DownloadOptions
|
||||
} from "./download.js";
|
||||
@@ -387,6 +388,24 @@ export class ScrapeEngine {
|
||||
return;
|
||||
}
|
||||
|
||||
// Audio has no image proxy: render a waveform strip with ffmpeg.
|
||||
if (row.kind === "audio" && row.source !== "embed") {
|
||||
const waveform = await remoteFrame(row.url, join(dir, "thumbs"), { waveform: true });
|
||||
if (waveform) {
|
||||
store.markPreview(row.id, {
|
||||
hash: waveform.hash,
|
||||
bytes: waveform.bytes,
|
||||
ext: "webp"
|
||||
});
|
||||
meta.previewed = (meta.previewed ?? 0) + 1;
|
||||
} else {
|
||||
store.markPreviewError(row.id, "waveform failed");
|
||||
}
|
||||
this.persist(dir, meta);
|
||||
await this.sleep(previewGapMs(options));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Some providers (fxtwitter, vxReddit, ...) ship no thumbnail in Discord's data;
|
||||
// resolve one from the provider or the page before caching it.
|
||||
let previewRow = row;
|
||||
@@ -429,6 +448,22 @@ export class ScrapeEngine {
|
||||
mkdirSync(dirname(target), { recursive: true });
|
||||
copyFileSync(join(dir, "thumbs", `${hash}.${ext}`), target);
|
||||
}
|
||||
} else if (
|
||||
outcome.state === "skipped" &&
|
||||
outcome.error === "too large" &&
|
||||
/\.gif(\?|$)/i.test(previewRow.preview_url ?? previewRow.url)
|
||||
) {
|
||||
// Oversized animated GIF: let ffmpeg read the stream and keep one frame.
|
||||
const frame = await remoteFrame(previewRow.preview_url ?? previewRow.url, join(dir, "thumbs"));
|
||||
if (frame) {
|
||||
store.markPreview(row.id, { hash: frame.hash, bytes: frame.bytes, ext: "webp" });
|
||||
meta.previewed = (meta.previewed ?? 0) + 1;
|
||||
} else {
|
||||
store.markPreviewError(row.id, "too large");
|
||||
}
|
||||
} else if (outcome.state === "failed") {
|
||||
// Transient network failure: leave the row pending for the next pass.
|
||||
this.log(`${meta.id}: preview ${row.id} failed: ${outcome.error ?? "unknown"}`);
|
||||
} else {
|
||||
store.markPreviewError(row.id, outcome.error ?? outcome.state);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user