fix(plex): subtitles survive hls.js and a remounted track
hls.js emptied the cues of every text track on the element when a manifest loaded or the media attached, our own <track> included, so a VTT that loaded first showed nothing for the session; its subtitle and caption controllers are no longer built. A remounted default <track> was switched to showing by the browser after the hide had run, drawing the cues natively under ours; the hide now follows every added track and mode change.
This commit is contained in:
@@ -440,14 +440,36 @@ describe("usePlexTracks — the debounced A/V-offset restart", () => {
|
||||
// The browser no longer draws the cues: its rendering sat under the control bar on an iPad, and a cue
|
||||
// placed by `line` cannot move out of the way. The track stays loaded, as `hidden`, for PlexSubtitles.
|
||||
describe("usePlexTracks — who draws the cues", () => {
|
||||
it("keeps the mounted track hidden: loaded and tracked, not drawn by the browser", () => {
|
||||
const track = { mode: "disabled" as TextTrackMode };
|
||||
/** A <video> whose text-track list fires `addtrack` / `change` like a browser's. */
|
||||
function videoWithTracks(...modes: TextTrackMode[]) {
|
||||
const list: { mode: TextTrackMode }[] = modes.map((mode) => ({ mode }));
|
||||
const tracks = Object.assign(new EventTarget(), {
|
||||
get length() {
|
||||
return list.length;
|
||||
},
|
||||
[Symbol.iterator]: () => list[Symbol.iterator](),
|
||||
});
|
||||
const video = document.createElement("video");
|
||||
Object.defineProperty(video, "textTracks", { value: [track] });
|
||||
Object.defineProperty(video, "textTracks", { value: tracks });
|
||||
// What a browser does with a freshly mounted `default` <track>: it switches it on by itself.
|
||||
const browserAddsShowing = () =>
|
||||
act(() => {
|
||||
list.push({ mode: "showing" });
|
||||
tracks.dispatchEvent(new Event("addtrack"));
|
||||
});
|
||||
const browserShows = () =>
|
||||
act(() => {
|
||||
list[0]!.mode = "showing";
|
||||
tracks.dispatchEvent(new Event("change"));
|
||||
});
|
||||
return { video, list, browserAddsShowing, browserShows };
|
||||
}
|
||||
|
||||
function mountOn(video: HTMLVideoElement) {
|
||||
const wrapper = ({ children }: { children: ReactNode }) => (
|
||||
<QueryClientProvider client={client()}>{children}</QueryClientProvider>
|
||||
);
|
||||
const { unmount } = renderHook(
|
||||
return renderHook(
|
||||
() =>
|
||||
usePlexTracks({
|
||||
id: RK,
|
||||
@@ -464,7 +486,22 @@ describe("usePlexTracks — who draws the cues", () => {
|
||||
}),
|
||||
{ wrapper },
|
||||
);
|
||||
expect(track.mode).toBe("hidden");
|
||||
}
|
||||
|
||||
it("keeps the mounted track hidden: loaded and tracked, not drawn by the browser", () => {
|
||||
const { video, list } = videoWithTracks("disabled");
|
||||
const { unmount } = mountOn(video);
|
||||
expect(list[0]!.mode).toBe("hidden");
|
||||
unmount();
|
||||
});
|
||||
|
||||
it("hides a remounted track the browser switched on by itself", () => {
|
||||
const { video, list, browserAddsShowing, browserShows } = videoWithTracks("disabled");
|
||||
const { unmount } = mountOn(video);
|
||||
browserAddsShowing();
|
||||
expect(list.map((t) => t.mode)).toEqual(["hidden", "hidden"]);
|
||||
browserShows();
|
||||
expect(list[0]!.mode).toBe("hidden");
|
||||
unmount();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user