Files
NODEDC_MISSION_CORE/apps/control-station/test/e46cVideoReplay.test.mjs
T

121 lines
4.0 KiB
JavaScript

import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import { after, before, test } from "node:test";
import { createServer } from "vite";
let server;
let fetchE46CVideoOverlay;
let selectE46CVideoFrame;
before(async () => {
server = await createServer({
appType: "custom",
logLevel: "silent",
server: { middlewareMode: true },
});
({ fetchE46CVideoOverlay, selectE46CVideoFrame } = await server.ssrLoadModule(
"/src/core/laboratory/e46cFullReplayWorldTracks.ts",
));
});
after(async () => {
await server?.close();
});
test("E46C decodes the complete path-free temporal video overlay", async () => {
const resultId = `e46c-full-replay-world-tracks-${"a".repeat(64)}`;
const start = 35.421857292;
const end = 484.044857292;
const step = (end - start) / 4488;
const frames = Array.from({ length: 4489 }, (_, frameIndex) => ({
frame_index: frameIndex,
session_seconds: frameIndex === 4488 ? end : start + frameIndex * step,
fusion_state: "fused",
objects: frameIndex === 20
? [{
bbox_xyxy: [100, 120, 240, 360],
category: "person",
score: 0.91,
route_track_id: 83,
world_track_id: 240001,
motion_state: "dynamic",
motion_confidence: 0.88,
track_hits: 12,
track_age_seconds: 1.2,
camera_evidence_current: true,
world_evidence_current: false,
}]
: [],
}));
const fetcher = async (input) => {
assert.equal(
String(input),
`/api/v1/laboratory/e46c/results/${resultId}/video-overlay`,
);
return new Response(JSON.stringify({
schema_version: "missioncore.e46c-recorded-video-overlay/v1",
result_id: resultId,
recorded_source: {
session_id: "20260720T065719Z_viewer_live",
source_id: "sensor.camera.right",
input_sha256: "4".repeat(64),
synchronization: "host-arrival-best-effort",
},
image_width: 800,
image_height: 600,
timeline_start_seconds: start,
timeline_end_seconds: end,
frame_count: 4489,
frames,
review_windows: [{
id: "dynamic-person-window",
kind: "target-motion",
class_group: "person",
start_seconds: 54,
end_seconds: 62,
target_source_track_ids: [83],
}],
ground_truth: false,
access: "read-only-full-route-diagnostic-video",
}), { status: 200, headers: { "Content-Type": "application/json" } });
};
const overlay = await fetchE46CVideoOverlay(resultId, { fetcher });
assert.equal(overlay.frameCount, 4489);
assert.equal(overlay.recordedSourceSessionId, "20260720T065719Z_viewer_live");
assert.equal(overlay.frames[20].objects[0].routeTrackId, 83);
assert.equal(overlay.frames[20].objects[0].displayCategory, "Человек");
assert.equal(overlay.reviewWindows[0].targetSourceTrackIds[0], 83);
assert.equal(JSON.stringify(overlay).includes("/Users/"), false);
assert.equal(selectE46CVideoFrame(overlay.frames, overlay.frames[20].sessionSeconds).frameIndex, 20);
});
test("E46C viewer opens with full VIDEO and reuses the admitted recorded player", async () => {
const [visual, videoScene, player] = await Promise.all([
readFile(
new URL(
"../src/workspaces/laboratory/E46CFullReplayWorldTracksVisual.tsx",
import.meta.url,
),
"utf8",
),
readFile(
new URL(
"../src/workspaces/laboratory/E46CRecordedVideoScene.tsx",
import.meta.url,
),
"utf8",
),
readFile(new URL("../src/components/RecordedFmp4Player.tsx", import.meta.url), "utf8"),
]);
assert.match(visual, /useState<E46CViewMode>\("video"\)/);
assert.match(visual, /\{ value: "video", label: "VIDEO" \}/);
assert.match(visual, /replayObservationSession\(overlay\.recordedSourceSessionId/);
assert.match(videoScene, /<RecordedFmp4Player/);
assert.match(videoScene, /selectE46CVideoFrame/);
assert.match(player, /requestVideoFrameCallback/);
assert.match(player, /controls=\{interactive\}/);
});