annie.media.previews¶
The preview loader: decodes and encodes preview frames off the event loop (service).
Browse and the Annotator show decoded frames for every visible row. Each row used to start its own decode the moment it was built, with no limit, and encode the frames on the event loop. This module puts all of that behind one small interface:
Bounded: at most
max_workersdecodes run at once, on the loader’s own threads.Newest batch first: requests that arrive together (one page of rows being built) form a batch and start in order, top row first; a newer batch (rows just scrolled into view) goes ahead of older ones, so what is on screen fills first.
Skips the unwanted: each request carries a
wantedcheck, asked just before its decode starts. A row that was refreshed or closed while it waited is skipped and getsSKIPPED, without decoding anything.Encoded in the worker: results are WebP data URIs sized for their box, ready to show, so the event loop only assigns them.
Cached: a bounded LRU keeps recent results, so a row scrolled back into view shows at once.
PreviewLoader.clear()empties it (e.g. on rescan). Errors are never cached.
The decoders are injected (defaulting to annie.media.preview and
annie.media.probe.has_audio()), so tests drive the loader with plain fakes.
Attributes¶
A display box |
|
Seconds within which consecutive requests count as one batch (one page being built). |
|
Returned instead of a result when the request was no longer wanted when its turn came. |
Classes¶
A row's frame strip, ready to show. |
|
A grid tile's single frame, ready to show. |
|
Bounded, newest-batch-first, cached decoding of preview frames (see the module docs). |
Module Contents¶
- annie.media.previews.Box¶
A display box
(width, height)in CSS px; frames are encoded to fit it.
- annie.media.previews.BATCH_WINDOW = 0.05¶
Seconds within which consecutive requests count as one batch (one page being built).
- annie.media.previews.SKIPPED: Final¶
Returned instead of a result when the request was no longer wanted when its turn came.
- class annie.media.previews.Strip[source]¶
A row’s frame strip, ready to show.
- uris¶
One WebP data URI per strip frame, sized for the requested box.
- num_frames¶
The video’s total frame count.
- class annie.media.previews.Tile[source]¶
A grid tile’s single frame, ready to show.
- uri¶
The WebP data URI of the annotated middle frame.
- num_frames¶
The video’s total frame count.
- class annie.media.previews.PreviewLoader(max_workers: int, *, cache_size: int = 300, strip_fn: collections.abc.Callable[[annie.core.models.VideoEntry], tuple[PIL.Image.Image, list[PIL.Image.Image], int]] = build_preview, tile_fn: collections.abc.Callable[[annie.core.models.VideoEntry], tuple[PIL.Image.Image, int]] = build_grid_preview, band_fn: collections.abc.Callable[[pathlib.Path, float, float, int], list[PIL.Image.Image]] = build_band_strip, audio_fn: collections.abc.Callable[[pathlib.Path], bool] = has_audio)[source]¶
Bounded, newest-batch-first, cached decoding of preview frames (see the module docs).
Every public method must be awaited on the event loop that serves the UI.
- Parameters:
max_workers – How many decodes may run at once.
cache_size – How many results the LRU keeps.
strip_fn – Decodes a video’s annotated strip (default
build_preview()).tile_fn – Decodes a video’s annotated middle frame (default
build_grid_preview()).band_fn – Decodes frames across a time span (default
build_band_strip()).audio_fn – Probes for an audio stream (default
has_audio()).
- async strip(entry: annie.core.models.VideoEntry, box: Box, *, wanted: collections.abc.Callable[[], bool]) Strip | _Skipped[source]¶
Decode
entry’s annotated strip, encoded forbox.
- async tile(entry: annie.core.models.VideoEntry, box: Box, *, wanted: collections.abc.Callable[[], bool]) Tile | _Skipped[source]¶
Decode
entry’s annotated middle frame for a grid tile, encoded forbox.
- async band(video_path: pathlib.Path, start: float, end: float, count: int, box: Box, *, wanted: collections.abc.Callable[[], bool]) list[str] | _Skipped[source]¶
Decode
countframes spread over[start, end)seconds, encoded forbox.- Parameters:
video_path – The video file.
start – Span start in seconds.
end – Span end in seconds.
count – How many frames to sample.
box – The display box of one frame.
wanted – Asked just before decoding;
Falseskips the request.
- Returns:
One data URI per decoded frame, or
SKIPPED.
- async audio(video_path: pathlib.Path, *, wanted: collections.abc.Callable[[], bool]) bool | _Skipped[source]¶
Probe whether
video_pathhas an audio stream (bounded like a decode, not cached).- Parameters:
video_path – The video file.
wanted – Asked just before probing;
Falseskips the request.
- Returns:
Whether an audio stream exists, or
SKIPPED.