From 58622a2a3cc42642e7ed1634d17818265882d05f Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Sun, 15 Nov 2026 11:47:36 -0600 Subject: [PATCH] hold the last frame on screen when the live mode changes Turning on two-way talk while watching MSE switched the player to WebRTC and showed a buffering spinner until WebRTC played. The frame capture now runs on a mode change as well as a stream change, so the outgoing frame stays up until the new player plays. --- web/src/components/player/LivePlayer.tsx | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/web/src/components/player/LivePlayer.tsx b/web/src/components/player/LivePlayer.tsx index 6f9c94583d..11ebb78908 100644 --- a/web/src/components/player/LivePlayer.tsx +++ b/web/src/components/player/LivePlayer.tsx @@ -238,20 +238,20 @@ export default function LivePlayer({ cameraActive, ]); - useEffect(() => { - setLiveReady(false); - }, [preferredLiveMode]); - const [key, setKey] = useState(0); - // the stream is part of the MSE and WebRTC keys, so a stream change - // remounts them in the same render and the new player is hidden until it - // plays. jsmpeg plays the camera, not the stream, and keeps playing - const [renderedStream, setRenderedStream] = useState(streamName); + // a stream or mode change remounts the player in the same render, and the + // new player is hidden until it plays. jsmpeg plays the camera, not the + // stream, so a stream change alone keeps it playing + const [renderedPlayer, setRenderedPlayer] = useState({ + stream: streamName, + mode: preferredLiveMode, + }); const [switchFrame, setSwitchFrame] = useState(); - if (renderedStream !== streamName) { - setRenderedStream(streamName); - if (preferredLiveMode !== "jsmpeg") { + const modeChanged = renderedPlayer.mode !== preferredLiveMode; + if (modeChanged || renderedPlayer.stream !== streamName) { + setRenderedPlayer({ stream: streamName, mode: preferredLiveMode }); + if (modeChanged || preferredLiveMode !== "jsmpeg") { setLiveReady(false); // the old video is still in the DOM until this render commits, so its