Spaces:
Running
Running
frozen/ stuck connection optim
Browse files- backend/engine.py +2 -2
- backend/server.py +11 -6
- frontend/vehicles.html +21 -0
backend/engine.py
CHANGED
|
@@ -89,7 +89,7 @@ def run(model, video_path, line, config, on_frame, save_annotated=False, annotat
|
|
| 89 |
if save_annotated:
|
| 90 |
annotated_dir = os.path.join(tempfile.gettempdir(), "funky_reports")
|
| 91 |
os.makedirs(annotated_dir, exist_ok=True)
|
| 92 |
-
annotated_path = os.path.join(annotated_dir, "
|
| 93 |
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
|
| 94 |
writer = cv2.VideoWriter(annotated_path, fourcc, fps / stride, (out_w, out_h))
|
| 95 |
|
|
@@ -115,7 +115,7 @@ def run(model, video_path, line, config, on_frame, save_annotated=False, annotat
|
|
| 115 |
vid_stride=stride,
|
| 116 |
stream=True,
|
| 117 |
verbose=False,
|
| 118 |
-
persist=True
|
| 119 |
)
|
| 120 |
|
| 121 |
a = line[0]
|
|
|
|
| 89 |
if save_annotated:
|
| 90 |
annotated_dir = os.path.join(tempfile.gettempdir(), "funky_reports")
|
| 91 |
os.makedirs(annotated_dir, exist_ok=True)
|
| 92 |
+
annotated_path = os.path.join(annotated_dir, f"annotated_{os.path.basename(video_path)}.mp4")
|
| 93 |
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
|
| 94 |
writer = cv2.VideoWriter(annotated_path, fourcc, fps / stride, (out_w, out_h))
|
| 95 |
|
|
|
|
| 115 |
vid_stride=stride,
|
| 116 |
stream=True,
|
| 117 |
verbose=False,
|
| 118 |
+
persist=False # MUST be False — True causes ByteTracker state leak across runs
|
| 119 |
)
|
| 120 |
|
| 121 |
a = line[0]
|
backend/server.py
CHANGED
|
@@ -46,15 +46,22 @@ def index():
|
|
| 46 |
async def upload(file: UploadFile = File(...)):
|
| 47 |
video_id = str(uuid.uuid4())[:8]
|
| 48 |
path = UPLOAD_DIR / f"{video_id}.mp4"
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
print(f"[BACKEND] Received upload request: {file.filename}")
|
| 51 |
try:
|
| 52 |
with open(path, "wb") as f:
|
| 53 |
shutil.copyfileobj(file.file, f)
|
| 54 |
-
|
| 55 |
file_size = os.path.getsize(path)
|
| 56 |
print(f"[BACKEND] Successfully stored: {path} ({file_size} bytes)")
|
| 57 |
-
|
| 58 |
videos[video_id] = str(path)
|
| 59 |
return {"video_id": video_id}
|
| 60 |
except Exception as e:
|
|
@@ -95,10 +102,8 @@ def generate_reports(video_id: str):
|
|
| 95 |
# Include annotated video if it exists
|
| 96 |
annotated_src = data.get("annotated_video")
|
| 97 |
if annotated_src and os.path.exists(annotated_src):
|
| 98 |
-
import shutil
|
| 99 |
dest = os.path.join(out_dir, "annotated.mp4")
|
| 100 |
-
|
| 101 |
-
shutil.copy2(annotated_src, dest)
|
| 102 |
files.append("annotated.mp4")
|
| 103 |
return {"files": files}
|
| 104 |
|
|
|
|
| 46 |
async def upload(file: UploadFile = File(...)):
|
| 47 |
video_id = str(uuid.uuid4())[:8]
|
| 48 |
path = UPLOAD_DIR / f"{video_id}.mp4"
|
| 49 |
+
|
| 50 |
+
# Clean up any previous temp uploads to avoid stale state
|
| 51 |
+
for old_path in UPLOAD_DIR.glob("*.mp4"):
|
| 52 |
+
try:
|
| 53 |
+
old_path.unlink()
|
| 54 |
+
except Exception:
|
| 55 |
+
pass
|
| 56 |
+
|
| 57 |
print(f"[BACKEND] Received upload request: {file.filename}")
|
| 58 |
try:
|
| 59 |
with open(path, "wb") as f:
|
| 60 |
shutil.copyfileobj(file.file, f)
|
| 61 |
+
|
| 62 |
file_size = os.path.getsize(path)
|
| 63 |
print(f"[BACKEND] Successfully stored: {path} ({file_size} bytes)")
|
| 64 |
+
|
| 65 |
videos[video_id] = str(path)
|
| 66 |
return {"video_id": video_id}
|
| 67 |
except Exception as e:
|
|
|
|
| 102 |
# Include annotated video if it exists
|
| 103 |
annotated_src = data.get("annotated_video")
|
| 104 |
if annotated_src and os.path.exists(annotated_src):
|
|
|
|
| 105 |
dest = os.path.join(out_dir, "annotated.mp4")
|
| 106 |
+
shutil.copy2(annotated_src, dest) # Always overwrite — never skip
|
|
|
|
| 107 |
files.append("annotated.mp4")
|
| 108 |
return {"files": files}
|
| 109 |
|
frontend/vehicles.html
CHANGED
|
@@ -1284,8 +1284,28 @@
|
|
| 1284 |
}
|
| 1285 |
};
|
| 1286 |
|
|
|
|
|
|
|
| 1287 |
ws.onclose = () => {
|
| 1288 |
console.log('WS Closed');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1289 |
};
|
| 1290 |
|
| 1291 |
let lastUIUpdate = 0;
|
|
@@ -1294,6 +1314,7 @@
|
|
| 1294 |
const d = JSON.parse(e.data);
|
| 1295 |
|
| 1296 |
if (d.done) {
|
|
|
|
| 1297 |
document.getElementById('proc-label').innerText = 'Complete';
|
| 1298 |
document.getElementById('proc-bar').style.width = '100%';
|
| 1299 |
document.getElementById('proc-pct').innerText = '100%';
|
|
|
|
| 1284 |
}
|
| 1285 |
};
|
| 1286 |
|
| 1287 |
+
let processingDone = false;
|
| 1288 |
+
|
| 1289 |
ws.onclose = () => {
|
| 1290 |
console.log('WS Closed');
|
| 1291 |
+
if (!processingDone) {
|
| 1292 |
+
// Closed before done=True received — show error state
|
| 1293 |
+
document.getElementById('proc-label').innerText = 'Disconnected';
|
| 1294 |
+
const badge = document.getElementById('results-status-badge');
|
| 1295 |
+
if (badge) {
|
| 1296 |
+
badge.innerText = 'Connection Lost';
|
| 1297 |
+
badge.className = 'px-2.5 py-1 bg-red-900/40 text-red-300 text-[10px] font-bold rounded-full uppercase tracking-tighter';
|
| 1298 |
+
}
|
| 1299 |
+
document.getElementById('run-results-content').innerHTML = `
|
| 1300 |
+
<div class="flex flex-col items-center justify-center p-8 border-2 border-dashed border-red-900/40 rounded-2xl col-span-3 text-slate-400">
|
| 1301 |
+
<i class="fa-solid fa-triangle-exclamation text-2xl mb-3 text-red-400"></i>
|
| 1302 |
+
<span class="text-xs font-semibold mb-1">Processing connection was lost.</span>
|
| 1303 |
+
<span class="text-[10px] text-slate-500 mb-4">The server may have timed out or restarted. Please try again.</span>
|
| 1304 |
+
<button onclick="startNewAnalysis()" class="text-[10px] font-bold uppercase tracking-widest px-4 py-2 rounded-full" style="background:#111;border:1px solid #2a2a2a;color:#c89a6c">
|
| 1305 |
+
← Start New Analysis
|
| 1306 |
+
</button>
|
| 1307 |
+
</div>`;
|
| 1308 |
+
}
|
| 1309 |
};
|
| 1310 |
|
| 1311 |
let lastUIUpdate = 0;
|
|
|
|
| 1314 |
const d = JSON.parse(e.data);
|
| 1315 |
|
| 1316 |
if (d.done) {
|
| 1317 |
+
processingDone = true;
|
| 1318 |
document.getElementById('proc-label').innerText = 'Complete';
|
| 1319 |
document.getElementById('proc-bar').style.width = '100%';
|
| 1320 |
document.getElementById('proc-pct').innerText = '100%';
|