fix: ffmpeg fallback for HEIC files that libheif rejects

iPhone photos with depth maps or gain maps have too many auxiliary
image references for libheif 1.17, causing pillow-heif to throw
"Too many auxiliary image references". process_heic_image() now
falls back to ffmpeg when pillow-heif fails — ffmpeg's own HEIC
decoder handles these files without issue. Fixes 27/35 HEIC photos
that were stuck in failed state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
root
2026-04-13 11:08:31 +02:00
parent edd569d095
commit 2adaaf18a1

View File

@@ -102,17 +102,36 @@ def extract_raw_preview(filepath: str) -> Optional[Image.Image]:
return None
def process_heic_image(filepath: str) -> Image.Image:
"""Process HEIC/HEIF image formats"""
"""Process HEIC/HEIF image formats.
Tries pillow-heif first (fast, native). Falls back to ffmpeg for
files that libheif rejects — e.g. iPhone photos with too many
auxiliary image references (depth maps, gain maps).
"""
try:
# Use pillow-heif to open the image
img = Image.open(filepath)
# Convert to RGB if needed
if img.mode != 'RGB':
img = img.convert('RGB')
return img
except Exception as e:
logger.error(f"Error processing HEIC file {filepath}: {e}")
raise
logger.warning(f"pillow-heif failed for {filepath}: {e} — trying ffmpeg")
# ffmpeg fallback: decode HEIC to PNG in memory.
import subprocess
from io import BytesIO
try:
result = subprocess.run(
['ffmpeg', '-i', filepath, '-frames:v', '1',
'-f', 'image2pipe', '-vcodec', 'png', 'pipe:1'],
capture_output=True, timeout=30, stdin=subprocess.DEVNULL,
)
if result.returncode == 0 and result.stdout:
img = Image.open(BytesIO(result.stdout)).convert('RGB')
return img
logger.error(f"ffmpeg HEIC decode failed for {filepath}: {result.stderr.decode()[-200:]}")
except Exception as e2:
logger.error(f"ffmpeg fallback failed for {filepath}: {e2}")
raise RuntimeError(f"Cannot decode HEIC: {filepath}")
def process_video_thumbnail(filepath: str) -> Image.Image:
"""Extract a still frame from a video file as a PIL Image."""