fix(plex): subtitles — a retried full pass resumes, a stalled track is polled slowly
A full pass that ran out of time kept what it reached, but its retry an hour later started again at 0, so a file too big to read inside the extraction timeout never completed. The pass now starts where every embedded track's coverage from the head ends (less the window pre-roll, so a cue across the join is read whole). The seek needs -avoid_negative_ts on this read as on a window, measured on a real file: without it the cue running at the start shifts the whole output. A partial track whose full pass had failed never reached a settled state, so the player polled it every 2 s for the rest of the film. The status now says whether the track is still growing, and a stalled one is polled every 15 s — still inside the 60 s lookahead that reads the next window before an edge.
This commit is contained in:
@@ -208,6 +208,22 @@ describe("usePlexTracks — when the status poll asks again, and when it stops",
|
||||
expect(status).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("slows down on a partial track that will not grow on its own, and keeps asking", async () => {
|
||||
// The full pass failed and is backed off for an hour: `partial` never turns `ready` by itself,
|
||||
// and the 2 s cadence ran for the rest of the film. It still carries the position — reading
|
||||
// ahead of an edge depends on it — so it slows rather than stops.
|
||||
const status = vi
|
||||
.spyOn(api, "plexSubtitleStatus")
|
||||
.mockResolvedValue({ state: "partial", code: null, gen: 4, growing: false });
|
||||
const { result } = mount(client());
|
||||
result.current.setSubOrd(0);
|
||||
await waitFor(() => expect(status).toHaveBeenCalledTimes(1));
|
||||
await vi.advanceTimersByTimeAsync(10_000);
|
||||
expect(status).toHaveBeenCalledTimes(1);
|
||||
await vi.advanceTimersByTimeAsync(6000);
|
||||
expect(status).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it("backs off after a failed request, and still asks again so a blip heals on its own", async () => {
|
||||
// A failed request leaves `data` empty; it used to read as "still preparing" and re-ask every
|
||||
// second for as long as the player stayed open.
|
||||
|
||||
Reference in New Issue
Block a user