From b4bd64fdb7bed5acad021eb0a283514a2d2c84f8 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Tue, 13 Oct 2026 17:30:05 -0700 Subject: [PATCH] player: keep the playback session and stores with the hosted video Player remounts with the layout even though the video now doesn't. Its cleanup cleared the streamer's playback session, which changed the HLS URL and restarted hls.js, so usePlaybackSession now runs next to the video (inside the hosted subtree on web, in Fullscreen on native). The hosted subtree also needs the livestream and video stores (the webcam ingest reads the stream key from the livestream store), and a remounted ingest Player no longer resets a live connection's state to "new". The resize e2e now compares the video's src/srcObject rather than counting emptied events, and covers the streamer's own HLS playback. --- .../mobile-player/fullscreen.native.tsx | 2 + .../components/mobile-player/fullscreen.tsx | 9 +++ .../mobile-player/playback-session.tsx | 50 +++++++++++++ .../src/components/mobile-player/player.tsx | 52 ++------------ .../components/mobile-player/video-host.tsx | 14 +++- js/e2e-web/flows/stream.spec.ts | 70 +++++++++++++------ 6 files changed, 127 insertions(+), 70 deletions(-) create mode 100644 js/components/src/components/mobile-player/playback-session.tsx diff --git a/js/components/src/components/mobile-player/fullscreen.native.tsx b/js/components/src/components/mobile-player/fullscreen.native.tsx index 78cbbd56b..a584cd3ee 100644 --- a/js/components/src/components/mobile-player/fullscreen.native.tsx +++ b/js/components/src/components/mobile-player/fullscreen.native.tsx @@ -22,6 +22,7 @@ import { VideoRetry, } from "../.."; import { colors, surfaces } from "../../lib/theme/tokens"; +import { usePlaybackSession } from "./playback-session"; import { AudioOnlyOverlay } from "./ui/audio-only-overlay"; import Video from "./video.native"; @@ -31,6 +32,7 @@ export function Fullscreen(props: { objectFit?: "contain" | "cover"; pictureInPictureEnabled?: boolean; }) { + usePlaybackSession(props.src); const ref = useRef(null); const insets = useSafeAreaInsets(); const dimensions = useWindowDimensions(); diff --git a/js/components/src/components/mobile-player/fullscreen.tsx b/js/components/src/components/mobile-player/fullscreen.tsx index faeedda4f..b877ef0de 100644 --- a/js/components/src/components/mobile-player/fullscreen.tsx +++ b/js/components/src/components/mobile-player/fullscreen.tsx @@ -11,6 +11,7 @@ import { usePlayerStore, } from "../.."; import { View } from "../../components/ui"; +import { usePlaybackSession } from "./playback-session"; import { AudioOnlyOverlay } from "./ui/audio-only-overlay"; import Video from "./video"; import { HostedVideo } from "./video-host"; @@ -125,6 +126,7 @@ export function Fullscreen(props: { style={{ width: "100%", height: "100%", overflow: "hidden" }} > +