mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-14 18:01:20 +08:00
52f3ed8493
VideoThumbnail and VideoFrameThumbnail each created a hidden <video> per component instance with no shared cache, so N clips on one source meant N extractions. Their sibling AudioWaveform had exactly the peaksCache / decodeInFlight pair both lacked, and mediaProbe's `failed` Set never expired — a transient probe failure was permanent for the tab's life. Generalise AudioWaveform's pair into mediaResolver: in-flight dedup keyed by normalized URL, a bounded LRU, an expiring failure record, a concurrency cap, and one client-side frame extractor. All four consumers move onto it; mediaProbe and AudioWaveform retire their private caches. The cache key is (src, duration), not src: VideoThumbnail derives its six timestamps from the clip's duration, so two clips trimmed differently from one source legitimately need different frames. Scope: this dedups traffic issued by the Studio document only. The media requests issued by <audio src>/<video src> inside the preview iframe are not reachable from a Studio-document module and are unaffected. Bounds come from the existing TIMELINE_VIEWPORT_BUDGETS fields (thumbnailCacheEntries, waveformCacheEntries, metadataRegistryEntries, concurrentVideoDecodes, concurrentMetadataJobs, metadataFailureTtlMs), which until now had no enforcing consumer.