From 564cf6b18fbf70b5434d41c07aa24cdba63aff17 Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Tue, 26 May 2026 16:27:27 +0000 Subject: [PATCH] fix: thumbnail img uses signed URL from API; switch transcoding to CPU libx264 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - FilesTab: fetch /assets/:id/thumbnail (returns signed S3 URL JSON), display the resolved URL in instead of pointing directly at the endpoint which returns JSON not image bytes - Transcoding: settings updated on ZAMPP1 to gpu_transcode_enabled=false, codec=libx264 — NVENC not available in worker container (no GPU passthrough) The proxy worker already has a CPU fallback but this prevents the unnecessary failed GPU attempt on every job --- services/web-ui/public/screens-asset.jsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/services/web-ui/public/screens-asset.jsx b/services/web-ui/public/screens-asset.jsx index 2909101..90da965 100644 --- a/services/web-ui/public/screens-asset.jsx +++ b/services/web-ui/public/screens-asset.jsx @@ -774,6 +774,15 @@ function FilesTab({ asset, filmFrames, filmstripLoading, streamUrl, reprocessing const hasThumb = !!asset.thumbnail_s3_key; const hasFilmstrip = Array.isArray(filmFrames) && filmFrames.length > 0; + // Thumbnail endpoint returns a signed URL, not raw image bytes + const [thumbUrl, setThumbUrl] = React.useState(null); + React.useEffect(function() { + if (!hasThumb) return; + window.ZAMPP_API.fetch('/assets/' + asset.id + '/thumbnail') + .then(function(r) { if (r && r.url) setThumbUrl(r.url); }) + .catch(function() {}); + }, [asset.id, hasThumb]); + // Rows: label | status badge | path | action button const FileRow = function({ label, present, path, icon, actionLabel, onAction, disabled, children }) { return ( @@ -838,9 +847,9 @@ function FilesTab({ asset, filmFrames, filmstripLoading, streamUrl, reprocessing onAction={onRegenThumbnail} disabled={reprocessing === 'thumbnail'} > - {hasThumb && ( + {thumbUrl && (