Trickplay sheets already on disk are neither catalogued nor moved #147
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Split (3) of #99's comment, untouched by the batch that closed it. #99 landed the
generation, the row and
RefreshTrickplayImages; two upstream pieces remain,both in
MediaBrowser.Providers/Trickplay/andTrickplayManager.csat the pin.TrickplayMoveImagesTask(keyMoveTrickplayImages) moves sheets betweenthe media directory and the data directory as the library option changes. This
server writes only to the data directory, so a library configured for
media-adjacent storage keeps its sheets where nothing looks for them.
DiscoverExistingTrickplayAsynccatalogues sheets a user placedthemselves, with interval-snapping arithmetic that has to be ported rather
than invented.
Two upstream behaviours to port faithfully rather than correct:
DiscoverExistingrecords the configured width rather than the even one the scaler produced,
and it records the tile count as
ThumbnailCount. Both look like defects,and both are numbers a client reads back out of
TrickplayInfos, so ours has toagree with them.
Where to start
crates/jellyfin-server/src/artefacts.rscarries the sweep #99 landed — thepaging, the
CanGenerateTrickplayguards, the tiling and the row write are allthere and this is a third entry point into the same machine. The on-disk
convention is
<data>/data/trickplay/<xx>/<hyphenated guid>/<width> - <tw>x<th>/<n>.jpgand is verified byte-identical against upstream.
How to know it is done
Neither piece is reachable from a harness run today — see the issue filed beside
this one about the fixture carrying no sheets. That is the precondition for
measuring either of these against a pair rather than against a unit test.
House rules
Tests run under
cargo nextest; upstream's source is the checkout inupstream/at the pin (v12.0-rc5,6d501ba4), not the clone beside therepository. Generated artifacts are regenerated, never edited. A comment says
what the code does, not how it got there. The reference on
:8096is read-only;anything needing a write gets its own container from the pinned image over a
cp -acopy of a snapshot, on its own ports. Kill a server by the PIDss -lntpH 'sport = :NNNN'reports.Landed in
8a7f4d8.What went in
SaveTrickplayWithMediais now a library setting (save_trickplay_with_media),and the four places that had to agree about it do:
Paths::trickplay_ofis the one rule for where a video's sheets are — the datadirectory, or
<file>.trickplaybeside the file — and the cutting, thediscovery, the serving route and the new task all go through it.
DiscoverExistingTrickplayAsyncruns before anything is cut, and does bothhalves: rows whose sheets are gone from both locations are dropped (a new
forget_trickplay_widths), and a<width> - <tw>x<th>directory nothingdescribes is catalogued with upstream's own arithmetic — the tile count bounds
the thumbnail count, and the interval is the configured one where the runtime
allows it and the middle of what the runtime allows where it does not, rounded
half to even because that is what
Math.Rounddoes.MoveTrickplayImagesis declared rather than argued absent.ABSENTis down tofive,
D34is rewritten,scenarios/tasks.jsonasks for the new id, and theharness README's count is updated.
Also ported, because it is the same branch: a library that has stopped
extracting no longer takes the sheets away when they live beside the media —
upstream treats those as the viewer's own and leaves them where they are.
One correction to this issue's premise
Those two belong to a different branch.
DiscoverExistingTrickplayAsyncrecordsthe width it parsed out of the directory name — which is the even one, because
that is what wrote the directory — and computes
ThumbnailCountfrom theruntime rather than from the tile count.
The branch that does what the issue describes is the "Import existing tiles"
block inside
RefreshTrickplayDataInternal(
TrickplayManager.cs:437), which setsWidth = width(configured) andThumbnailCount = existingFiles.Length(tiles). It is unreachable at the pin.Discovery runs first and files a row keyed on the directory's width; the import
branch is guarded by
HasTrickplayResolutionAsync(video.Id, actualWidth), andthe directory is named with
actualWidth, so that guard is always true by thetime it is reached. The only way past it is a folder holding files none of which
are
.jpg— discovery skips those andGetImageSizewould throw on them.So the port implements
DiscoverExistingas upstream writes it, and does notreproduce the two numbers, because nothing upstream produces them either.
What is not measured
Neither piece is reachable from a harness run: the snapshot still carries no
sheets. That is #148, and it is the precondition for measuring either of these
against a pair rather than against the unit tests beside them.