mini video prewarm :3

This commit is contained in:
legop3
2026-01-30 22:31:40 -05:00
parent bdb4f41e93
commit ca3d95319d
5 changed files with 197 additions and 134 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -11,8 +11,8 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" /> <meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
<title>Multi Roomba Rover</title> <title>Multi Roomba Rover</title>
<script type="module" crossorigin src="/assets/index-Bmhgw8c6.js"></script> <script type="module" crossorigin src="/assets/index-f56Apeln.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-C9Dx14Sy.css"> <link rel="stylesheet" crossorigin href="/assets/index-DMYOk2Xw.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
+75 -12
View File
@@ -11,6 +11,7 @@ import AlertFeed from '../components/AlertFeed.jsx';
import useDefaultNickname from '../hooks/useDefaultNickname.js'; import useDefaultNickname from '../hooks/useDefaultNickname.js';
const ROTATE_MS = 20000; const ROTATE_MS = 20000;
const PREWARM_MS = 5000;
const HARD_REFRESH_MS = 3 * 60 * 60 * 1000; const HARD_REFRESH_MS = 3 * 60 * 60 * 1000;
function formatDriverLabel({ roverId, session }) { function formatDriverLabel({ roverId, session }) {
@@ -219,6 +220,8 @@ function MiniSummaryContent() {
const frames = useTelemetryFrames(); const frames = useTelemetryFrames();
const roster = session?.roster ?? []; const roster = session?.roster ?? [];
const [index, setIndex] = useState(0); const [index, setIndex] = useState(0);
const [prewarmRoverId, setPrewarmRoverId] = useState(null);
const prewarmTimer = useRef(null);
const activeDrivers = session?.activeDrivers || {}; const activeDrivers = session?.activeDrivers || {};
const driverRoster = useMemo( const driverRoster = useMemo(
() => roster.filter((rover) => activeDrivers[rover.id]), () => roster.filter((rover) => activeDrivers[rover.id]),
@@ -286,13 +289,37 @@ function MiniSummaryContent() {
return () => clearInterval(timer); return () => clearInterval(timer);
}, [rotationPool.length, rotationKey]); }, [rotationPool.length, rotationKey]);
useEffect(() => {
setPrewarmRoverId(null);
}, [rotationKey]);
useEffect(() => {
clearTimeout(prewarmTimer.current);
if (!canSpectateVideo || rotationPool.length < 2) {
setPrewarmRoverId(null);
return undefined;
}
const nextIndex = (index + 1) % rotationPool.length;
const delay = Math.max(0, ROTATE_MS - PREWARM_MS);
prewarmTimer.current = setTimeout(() => {
const nextEntry = rotationPool[nextIndex];
setPrewarmRoverId(nextEntry?.rover?.id || null);
}, delay);
return () => clearTimeout(prewarmTimer.current);
}, [index, rotationPool, canSpectateVideo]);
const activeEntry = rotationPool.length ? rotationPool[index % rotationPool.length] : null; const activeEntry = rotationPool.length ? rotationPool[index % rotationPool.length] : null;
const activeRover = activeEntry?.type === 'rover' ? activeEntry.rover : null; const activeRover = activeEntry?.type === 'rover' ? activeEntry.rover : null;
const prewarmRover = prewarmRoverId
? rotationPool.find((entry) => entry.rover?.id === prewarmRoverId)?.rover || null
: null;
const activeSnapshot = !canSpectateVideo && activeRover ? snapshotFeeds[activeRover.id] || null : null; const activeSnapshot = !canSpectateVideo && activeRover ? snapshotFeeds[activeRover.id] || null : null;
const activeVideo = canSpectateVideo && activeRover ? videoSources[activeRover.id] || null : null; const activeVideo = canSpectateVideo && activeRover ? videoSources[activeRover.id] || null : null;
const prewarmVideo = canSpectateVideo && prewarmRover ? videoSources[prewarmRover.id] || null : null;
const activeAudio = activeRover ? audioSources[`${activeRover.id}-audio`] || null : null; const activeAudio = activeRover ? audioSources[`${activeRover.id}-audio`] || null : null;
const activeFrame = activeRover ? frames[activeRover.id] || null : null; const activeFrame = activeRover ? frames[activeRover.id] || null : null;
const prewarmFrame = prewarmRover ? frames[prewarmRover.id] || null : null;
const driverLabel = activeRover ? formatDriverLabel({ roverId: activeRover.id, session }) : null; const driverLabel = activeRover ? formatDriverLabel({ roverId: activeRover.id, session }) : null;
if (inLockdown) { if (inLockdown) {
@@ -346,18 +373,54 @@ function MiniSummaryContent() {
</div> </div>
) : activeRover ? ( ) : activeRover ? (
<FitViewportFrame> <FitViewportFrame>
<VideoTile {canSpectateVideo ? (
sessionInfo={activeVideo} <div className="relative h-full w-full">
videoMode={canSpectateVideo ? 'whep' : 'snapshot'} <div className="absolute inset-0">
snapshotFeed={activeSnapshot} <VideoTile
audioSessionInfo={activeAudio} sessionInfo={activeVideo}
label={activeRover.name || activeRover.id} videoMode="whep"
telemetryFrame={activeFrame} snapshotFeed={null}
batteryConfig={activeRover.battery} audioSessionInfo={activeAudio}
layoutFormat="mobile" label={activeRover.name || activeRover.id}
hudVariant="none" telemetryFrame={activeFrame}
fitParent batteryConfig={activeRover.battery}
/> layoutFormat="mobile"
hudVariant="none"
fitParent
/>
</div>
{prewarmRover && prewarmRover.id !== activeRover.id ? (
<div className="absolute inset-0 opacity-0 pointer-events-none">
<VideoTile
sessionInfo={prewarmVideo}
videoMode="whep"
snapshotFeed={null}
audioSessionInfo={null}
forceMute
label={prewarmRover.name || prewarmRover.id}
telemetryFrame={prewarmFrame}
batteryConfig={prewarmRover.battery}
layoutFormat="mobile"
hudVariant="none"
fitParent
/>
</div>
) : null}
</div>
) : (
<VideoTile
sessionInfo={null}
videoMode="snapshot"
snapshotFeed={activeSnapshot}
audioSessionInfo={activeAudio}
label={activeRover.name || activeRover.id}
telemetryFrame={activeFrame}
batteryConfig={activeRover.battery}
layoutFormat="mobile"
hudVariant="none"
fitParent
/>
)}
</FitViewportFrame> </FitViewportFrame>
) : ( ) : (
<div className="flex h-full w-full items-center justify-center text-sm text-slate-500"> <div className="flex h-full w-full items-center justify-center text-sm text-slate-500">