Reduce FFmpeg cover-art storms (#3109)
* fix(images): add in-memory cache and concurrency limit for image data
Add a TTL-based LRU memory cache (256 entries, 15min TTL) to
get_image_data() to avoid redundant fetches of the same image.
Deduplicate concurrent in-flight requests via task_id and limit
embedded image extractions to 2 concurrent ffmpeg processes
using a semaphore.
Includes unit tests for cache hits, TTL expiry, eviction, and
request deduplication.
* Revert "fix(images): add in-memory cache and concurrency limit for image data"
This reverts commit
a676a2484d24df1de4d2631118f1f0315c503fc8.
* feat(images): add on-disk thumbnail cache to avoid repeated ffmpeg extractions
Implement a two-tier caching system for image thumbnails:
- On-disk cache: thumbnails stored as {sha256(provider/path)}_{size}.{ext}
in a "thumbnails" subfolder of the cache directory, surviving restarts.
- In-memory FIFO cache: last 50 thumbnails for instant access on hot paths.
- In-flight deduplication: concurrent requests for the same thumbnail share
a single generation task via create_task, preventing ffmpeg bursts.
This eliminates repeated ffmpeg spawns for embedded cover art extraction,
which caused high CPU usage and playback interruptions especially on
lower-powered hardware and network-mounted music libraries (e.g. SMB).