Browse Source

feat: robust date-time parsing and persistent overlay resilience

IMPROVEMENTS:

- **utils.js**: Enhanced [extractTimestampInfo](cci:1://file:///d:/Work/Repo/refactor/steps/src/utils.js:36:0-70:1) with a robust, prefix-agnostic regular expression. It now identifies `YYYYMMDD_HHMMSS` and `DDMMYYYY_HHMMSS` patterns anywhere in a filename, enabling support for generic camera names like `cam_20260312_163310` or raw recordings.
- **dom.js**: Decoupled persistent overlays and debug diagnostics from mandatory video date-time metadata. The dashboard now remains fully functional even when loading generic video files (e.g., `output.mp4`).
- **Standardized Epoch Fallback**: Implemented a unified time-anchoring logic. If a filename lacks date-time information, the system now defaults to **January 1, 1970 (Unix Epoch)**, ensuring the absolute time clocks and sync diagnostics proceed without error or disappearance.
- **Bug Fixes**: Corrected syntax errors and structural scoping issues in the [updateDebugOverlay](cci:1://file:///d:/Work/Repo/refactor/steps/src/dom.js:200:0-291:1) function that were causing diagnostics to display inconsistently.
refactor/sync-centralize
RUSHIL AMBARISH KADU 2 months ago
parent
commit
1556231f17
  1. 31
      steps/src/dom.js
  2. 21
      steps/src/utils.js

31
steps/src/dom.js

@ -217,9 +217,8 @@ export function updateDebugOverlay(currentMediaTime) {
// --- Logic for the original debug overlay ---
if (isDebug1Visible) {
content.push(`--- Basic Info ---`);
if (appState.videoStartDate) {
const videoAbsoluteTimeMs =
appState.videoStartDate.getTime() + currentMediaTime * 1000;
const baseTimeMs = appState.videoStartDate ? appState.videoStartDate.getTime() : (appState.radarStartTimeMs || 0);
const videoAbsoluteTimeMs = baseTimeMs + currentMediaTime * 1000;
let timeString = `Media Time (s): ${currentMediaTime.toFixed(2)}`; // Two decimal places
if (videoPlayer && !isNaN(videoPlayer.duration) && videoPlayer.duration > 0) {
@ -234,20 +233,18 @@ export function updateDebugOverlay(currentMediaTime) {
.split("T")[1]
.replace("Z", "")}`
); // Format and display video absolute time
} else {
content.push("Video not loaded..."); // Indicate video not loaded.
}
if (
appState.vizData &&
appState.vizData.radarFrames[appState.currentFrame]
) {
content.push(`Radar Frame: ${appState.currentFrame + 1}`);
const frameTime =
appState.vizData.radarFrames[appState.currentFrame].timestampMs;
const frameData = appState.vizData.radarFrames[appState.currentFrame];
const frameTime = frameData.timestampMs;
const baseTimeMs = appState.videoStartDate ? appState.videoStartDate.getTime() : (appState.radarStartTimeMs || 0);
content.push(
`Radar Abs Time: ${new Date(
appState.videoStartDate.getTime() + frameTime
)
`Radar Abs Time: ${new Date(baseTimeMs + frameTime)
.toISOString()
.split("T")[1]
.replace("Z", "")}`
@ -259,7 +256,6 @@ export function updateDebugOverlay(currentMediaTime) {
if (isDebug2Visible) {
content.push(`--- Sync Diagnostics ---`);
if (
appState.videoStartDate &&
appState.vizData &&
appState.vizData.radarFrames[appState.currentFrame]
) {
@ -275,8 +271,9 @@ export function updateDebugOverlay(currentMediaTime) {
content.push(`Video Time (s): ${currentMediaTime.toFixed(3)}`); // Display current video time
content.push(`Target Sync Time (s): ${currentRadarFrame.videoSyncedTime.toFixed(3)}`);
content.push(`Drift (ms): <b style="color: ${driftColor};">${driftMs.toFixed(0)}</b>`);
content.push(`Video Start Time: ${appState.videoStartDate.toISOString()}`);
content.push(`Radar Start Time: ${new Date(appState.radarStartTimeMs).toISOString()}`);
const videoStart = appState.videoStartDate ? appState.videoStartDate.toISOString() : new Date(0).toISOString();
content.push(`Video Start Time: ${videoStart}`);
content.push(`Radar Start Time: ${new Date(appState.radarStartTimeMs || 0).toISOString()}`);
content.push(`Calculated Offset (ms): ${offsetInput.value}`); // Display calculated offset.
const renderTime = appState.lastFrameRenderTime;
// Color is green if render time is under 33ms (~30fps budget), otherwise red
@ -320,7 +317,7 @@ export function updatePersistentOverlays(currentMediaTime) {
}
// If we don't have the necessary data, hide the overlays and exit.
if (!appState.vizData || !appState.videoStartDate) {
if (!appState.vizData) {
radarInfoOverlay.classList.add("hidden");
videoInfoOverlay.classList.add("hidden");
return;
@ -521,7 +518,9 @@ export function updatePersistentOverlays(currentMediaTime) {
}
// --- Update Video Persistent Overlay ---
const absVideoTime = new Date(appState.videoStartDate.getTime() + currentMediaTime * 1000);
// Default to Unix Epoch (Jan 1, 1970) if no dates are available
const baseTimeMs = appState.videoStartDate ? appState.videoStartDate.getTime() : (appState.radarStartTimeMs || 0);
const absVideoTime = new Date(baseTimeMs + currentMediaTime * 1000);
const videoFrame = Math.floor(currentMediaTime * VIDEO_FPS);
let timeDisplay = `Elapsed Time: ${currentMediaTime.toFixed(2)}s`;

21
steps/src/utils.js

@ -52,13 +52,20 @@ export function extractTimestampInfo(filename) {
const timestamp = `${match[1]}_${match[2]}${match[3]}${match[4]}`;
return { timestampStr: timestamp, format: "video" };
}
// Try to match another common video filename pattern: "video_YYYYMMDD_HHMMSS"
match = filename.match(/video_(\d{8}_\d{6})/);
if (match)
return {
timestampStr: match[1],
format: "video",
};
// Try to match generic YYYYMMDD_HHMMSS or similar patterns anywhere in the name
// Examples: video_20231027_103000, cam_20260312_163310, 20260312163310
match = filename.match(/((?:19|20)\d{2})(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])[-_]?([01]\d|2[0-3])([0-5]\d)([0-5]\d)/);
if (match) {
const timestamp = `${match[1]}${match[2]}${match[3]}_${match[4]}${match[5]}${match[6]}`;
return { timestampStr: timestamp, format: "video" };
}
// Try generic DDMMYYYY_HHMMSS pattern just in case
match = filename.match(/(0[1-9]|[12]\d|3[01])(0[1-9]|1[0-2])((?:19|20)\d{2})[-_]?([01]\d|2[0-3])([0-5]\d)([0-5]\d)/);
if (match) {
const timestamp = `${match[3]}${match[2]}${match[1]}_${match[4]}${match[5]}${match[6]}`;
return { timestampStr: timestamp, format: "video" };
}
// If no pattern matches, return null
return null;
}

Loading…
Cancel
Save