fix video auth stuff

This commit is contained in:
legop3
2025-11-20 16:47:56 -05:00
parent ac634a4ab2
commit 3af8702d48
5 changed files with 53 additions and 12 deletions
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>webui</title> <title>webui</title>
<script type="module" crossorigin src="/assets/index-j7W157tS.js"></script> <script type="module" crossorigin src="/assets/index-BsFjPjMz.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BlCqEIWr.css"> <link rel="stylesheet" crossorigin href="/assets/index-BlCqEIWr.css">
</head> </head>
<body> <body>
+3 -1
View File
@@ -115,7 +115,9 @@ export default function RoomCameraFeed({ sessionInfo, label }) {
} }
}, [status, sessionInfo?.url, scheduleRestart]); }, [status, sessionInfo?.url, scheduleRestart]);
const renderedStatus = !sessionInfo?.url const renderedStatus = sessionInfo?.error
? `Error: ${sessionInfo.error}`
: !sessionInfo?.url
? 'Waiting for stream session' ? 'Waiting for stream session'
: status === 'error' : status === 'error'
? `Error: ${detail || 'unknown'}` ? `Error: ${detail || 'unknown'}`
+2 -2
View File
@@ -71,10 +71,10 @@ export default function RoomCameraPanel({ defaultOrientation = 'horizontal', ori
const sessionInfo = videoSources[key]; const sessionInfo = videoSources[key];
return ( return (
<article key={camera.id} className="w-full space-y-0.5 rounded border border-slate-800 bg-zinc-950 p-0.5"> <article key={camera.id} className="w-full space-y-0.5 rounded border border-slate-800 bg-zinc-950 p-0.5">
<header className="space-y-0.5"> {/* <header className="space-y-0.5">
<p className="text-lg font-semibold text-white">{camera.name || camera.id}</p> <p className="text-lg font-semibold text-white">{camera.name || camera.id}</p>
{camera.description && <p className="text-xs text-slate-500">{camera.description}</p>} {camera.description && <p className="text-xs text-slate-500">{camera.description}</p>}
</header> </header> */}
<RoomCameraFeed sessionInfo={sessionInfo} label={camera.name || camera.id} /> <RoomCameraFeed sessionInfo={sessionInfo} label={camera.name || camera.id} />
</article> </article>
); );
+40 -1
View File
@@ -1,6 +1,8 @@
import { useEffect, useMemo, useRef, useState } from 'react'; import { useEffect, useMemo, useRef, useState } from 'react';
import { useSocket } from '../context/SocketContext.jsx'; import { useSocket } from '../context/SocketContext.jsx';
const RETRY_DELAY_MS = 3000;
function normalizeEntry(entry) { function normalizeEntry(entry) {
if (!entry) return null; if (!entry) return null;
if (typeof entry === 'string') { if (typeof entry === 'string') {
@@ -52,6 +54,7 @@ export function useVideoRequests(sourceList = []) {
[normalizedEntries], [normalizedEntries],
); );
const entriesRef = useRef([]); const entriesRef = useRef([]);
const retryTimers = useRef(new Map());
useEffect(() => { useEffect(() => {
entriesRef.current = normalizedEntries; entriesRef.current = normalizedEntries;
@@ -63,19 +66,55 @@ export function useVideoRequests(sourceList = []) {
} }
const entries = entriesRef.current; const entries = entriesRef.current;
let cancelled = false; let cancelled = false;
entries.forEach((entry) => { const timers = retryTimers.current;
function clearRetry(key) {
const timer = timers.get(key);
if (timer) {
clearTimeout(timer);
timers.delete(key);
}
}
function scheduleRetry(entry) {
clearRetry(entry.key);
const timer = setTimeout(() => {
timers.delete(entry.key);
if (cancelled) return;
requestEntry(entry);
}, RETRY_DELAY_MS);
timers.set(entry.key, timer);
}
function requestEntry(entry) {
const payload = entry.type === 'room' ? { roomCameraId: entry.id } : { roverId: entry.id }; const payload = entry.type === 'room' ? { roomCameraId: entry.id } : { roverId: entry.id };
socket.emit('video:request', payload, (resp = {}) => { socket.emit('video:request', payload, (resp = {}) => {
if (cancelled) return; if (cancelled) return;
if (!resp || resp.error || !resp.url || !resp.token) {
scheduleRetry(entry);
setSources((prev) => ({
...prev,
[entry.key]: resp,
}));
return;
}
clearRetry(entry.key);
setSources((prev) => ({ setSources((prev) => ({
...prev, ...prev,
[entry.key]: resp, [entry.key]: resp,
})); }));
}); });
}
entries.forEach((entry) => {
clearRetry(entry.key);
requestEntry(entry);
}); });
return () => { return () => {
cancelled = true; cancelled = true;
timers.forEach((timer) => clearTimeout(timer));
timers.clear();
}; };
}, [socket, normalizedKey]); }, [socket, normalizedKey]);