improvement(plex): serve right-sized poster/art images via Plex transcode
Posters/art were proxied at full resolution (many 1-7MB, some 9.5MB) into ≤176px grid/info cells — heavy to fetch + decode, so fast scrolling lagged 1-2s even with a warm cache (the cache removed the Plex round-trip, not the image weight). Now PlexClient.image_bytes optionally hits Plex's /photo/:/transcode to resize server-side; the /image endpoint requests thumb=400x600, art=1280x720 and keys the cache by width (old full-size files orphaned, re-cached small). Measured: a poster 5.5MB->50KB, art 8.1MB->137KB, at 400x600 (crisp on 2x DPR). Grid scroll is near-instant and the disk cache shrinks ~8x.
This commit is contained in:
parent
6df43445df
commit
23fc67cb64
4 changed files with 35 additions and 6 deletions
|
|
@ -6,6 +6,7 @@ metadata, image proxying, and (P5) optional watch-state write-back. Requests JSO
|
|||
``Accept: application/json`` header (Plex serves XML by default).
|
||||
"""
|
||||
import logging
|
||||
from urllib.parse import quote
|
||||
|
||||
import httpx
|
||||
from sqlalchemy.orm import Session
|
||||
|
|
@ -112,11 +113,24 @@ class PlexClient:
|
|||
items = mc.get("Metadata", []) or []
|
||||
return items[0] if items else None
|
||||
|
||||
def image_bytes(self, image_path: str) -> tuple[bytes, str]:
|
||||
def image_bytes(
|
||||
self, image_path: str, width: int | None = None, height: int | None = None
|
||||
) -> tuple[bytes, str]:
|
||||
"""Raw bytes + content-type of a Plex thumb/art image (proxied to the browser). The
|
||||
image_path is a Plex path like ``/library/metadata/123/thumb/456``."""
|
||||
image_path is a Plex path like ``/library/metadata/123/thumb/456``.
|
||||
|
||||
With width+height, Plex's photo transcoder resizes server-side so the browser fetches a small
|
||||
image (~tens of KB) instead of the multi-MB full-res original — far faster grid scroll + a
|
||||
much smaller disk cache. ``minSize=1`` fits within the box; ``upscale=0`` never enlarges."""
|
||||
if width and height:
|
||||
path = (
|
||||
f"/photo/:/transcode?width={width}&height={height}"
|
||||
f"&minSize=1&upscale=0&url={quote(image_path, safe='')}"
|
||||
)
|
||||
else:
|
||||
path = image_path
|
||||
try:
|
||||
r = self._http.get(f"{self.base}{image_path}")
|
||||
r = self._http.get(f"{self.base}{path}")
|
||||
r.raise_for_status()
|
||||
except httpx.HTTPError as e:
|
||||
raise PlexError(str(e)) from e
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue