snapshot fixes

This commit is contained in:
legop3
2026-07-18 03:22:01 -04:00
parent 387a5f47d7
commit 8a4162683f
3 changed files with 30 additions and 9 deletions
+21
View File
@@ -196,6 +196,26 @@ function canDrive(roverId, socket) {
return activeDrivers.get(roverId) === socket.id; return activeDrivers.get(roverId) === socket.id;
} }
function canRequestLiveVideo(roverId, socket) {
if (!socket) return false;
if (canDrive(roverId, socket)) return true;
const queue = driverQueues.get(roverId);
if (!queue || getMode() !== MODES.TURNS) {
return false;
}
/*
This helper is intentionally broader than canDrive(). Bandwidth saving is a
presentation/subscription decision for normal driver clients: the UI keeps
non-current drivers on snapshots, and only asks for live video when it wants
to warm or show the stream. The server should still verify that the socket is
actually attached to this rover, but it should not reject a legitimate queued
driver because the browser and turn timer are a few milliseconds out of sync.
*/
return queue.queue.includes(socket.id);
}
function isQueuedDriver(roverId, socketId) { function isQueuedDriver(roverId, socketId) {
if (!socketId) return false; if (!socketId) return false;
const queue = driverQueues.get(roverId); const queue = driverQueues.get(roverId);
@@ -410,6 +430,7 @@ module.exports = {
driverRemoved, driverRemoved,
cleanupRover, cleanupRover,
canDrive, canDrive,
canRequestLiveVideo,
isQueuedDriver, isQueuedDriver,
getActiveDrivers, getActiveDrivers,
turnEvents, turnEvents,
@@ -104,12 +104,12 @@ function createVideoAuthPolicy(deps) {
if ( if (
!isAudio && !isAudio &&
shouldUseSnapshotsForNonTurnVideo({ controllableUserCount: countControllableUsers() }) && shouldUseSnapshotsForNonTurnVideo({ controllableUserCount: countControllableUsers() }) &&
!turnService.canDrive(roverId, socket) !turnService.canRequestLiveVideo(roverId, socket)
) { ) {
/* /*
This mirrors videoSocketService's token gate. MediaMTX can ask auth This mirrors videoSocketService's token gate. MediaMTX can ask auth
after a token has been issued, so the active-turn bandwidth rule must after a token has been issued, so the same "must belong to this rover's
be evaluated here too instead of trusting an older browser decision. driver queue" rule has to be evaluated here too.
*/ */
return false; return false;
} }
@@ -153,15 +153,15 @@ io.on('connection', (socket) => {
role !== 'spectator' && role !== 'spectator' &&
!isAdmin(socket) && !isAdmin(socket) &&
shouldUseSnapshotsForNonTurnVideo({ controllableUserCount: countControllableUsers() }) && shouldUseSnapshotsForNonTurnVideo({ controllableUserCount: countControllableUsers() }) &&
!turnService.canDrive(baseId, socket) !turnService.canRequestLiveVideo(baseId, socket)
) { ) {
/* /*
The browser also forces snapshots for non-active turn holders, but The browser owns the snapshot-vs-live presentation for queued rover
the socket token path must enforce the same rule. Otherwise a stale drivers. The server side only verifies that the socket belongs to
component or direct socket caller could still mint a MediaMTX token this rover's driver queue so legitimate warm-up/switch requests are
while the UI is showing snapshots. not rejected by small turn-timer timing differences.
*/ */
throw new Error('Live video is limited to the active turn'); throw new Error('Live video is limited to this rover queue');
} }
} else if (target.type === 'room') { } else if (target.type === 'room') {
throw new Error('Room cameras now use the snapshot feed'); throw new Error('Room cameras now use the snapshot feed');