diff --git a/backend/services/thumbnail_ai.py b/backend/services/thumbnail_ai.py index 3bf2114..4b10ff0 100644 --- a/backend/services/thumbnail_ai.py +++ b/backend/services/thumbnail_ai.py @@ -343,7 +343,9 @@ def _too_similar(a: dict, b: dict) -> bool: for c in candidates: if len(selected) >= count: break - if c in selected: + # Identity, not equality: these dicts hold a numpy frame, and + # comparing two of them raises rather than answering. + if any(c is s for s in selected): continue if any(_too_similar(c, s) for s in selected): continue @@ -449,7 +451,13 @@ def _too_similar(a: dict, b: dict) -> bool: fh, fw = frame.shape[:2] if (fw, fh) != (target_w, target_h): frame = cv2.resize(frame, (target_w, target_h), interpolation=cv2.INTER_LANCZOS4) - cv2.imwrite(path, frame, [cv2.IMWRITE_JPEG_QUALITY, 92]) + # imwrite answers a failed write with False rather than raising, and a + # full disk is the usual reason. Listing the path regardless hands the + # renderer a frame that is not on disk, which it refuses. + if not cv2.imwrite(path, frame, [cv2.IMWRITE_JPEG_QUALITY, 92]): + log_event("thumbnail-ai", "could not write candidate frame", + level="warn", path=path) + continue results.append({ "path": path, "timestamp": c["timestamp"],