Tiresias/web/templates/index.html

127 lines
4.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Stream Monitor</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f8f9fa;
}
.video-frame {
width: 100%;
aspect-ratio: 16 / 9;
background: black;
}
.gif-preview {
width: 100%;
border-radius: 5px;
}
.detection-list {
max-height: 80vh;
overflow-y: auto;
}
.section-title {
margin-top: 1rem;
margin-bottom: 1rem;
font-weight: bold;
}
.small-text {
font-size: 0.85rem;
color: #666;
}
</style>
</head>
<body>
<div class="container-fluid mt-4">
<div class="row">
<!-- Live Stream -->
<div class="col-md-6">
<h4 class="section-title">Live Stream</h4>
<div class="video-frame">
<!-- Placeholder RTSP (replace with actual player integration) -->
<video controls autoplay muted width="100%" height="100%">
<source src="{{stream_url}}" type="video/mp4">
RTSP playback not supported.
</video>
</div>
<p class="mt-2 small-text">Frame queue length: <span id="queue-length-f">...</span></p>
<p class="mt-2 small-text">Inference Queue length: <span id="queue-length-i">...</span></p>
</div>
<!-- Negative Detections -->
<div class="col-md-3">
<h4 class="section-title text-danger">Negative Detections</h4>
<div class="detection-list" id="negatives">
<p class="text-muted small">Waiting for data...</p>
</div>
</div>
<!-- Positive Detections -->
<div class="col-md-3">
<h4 class="section-title text-success">Positive Detections</h4>
<div class="detection-list" id="positives">
<p class="text-muted small">Waiting for data...</p>
</div>
</div>
</div>
</div>
<!-- Bootstrap JS + Fetch -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
async function fetchStatus() {
try {
const response = await fetch('/status');
const data = await response.json();
// Update queue length
document.getElementById('queue-length-f').textContent = data.stream_1_queue;
document.getElementById('queue-length-i').textContent = data.stream_2_queue;
// Update negatives
const negContainer = document.getElementById('negatives');
negContainer.innerHTML = '';
data.negatives.forEach(item => {
negContainer.innerHTML += `
<div class="card mb-2">
<img src="/gifs/${item.gif}" class="gif-preview" alt="negative">
<div class="card-body p-2">
<small class="text-muted">${item.timestamp}</small>
</div>
</div>
`;
});
// Update positives
const posContainer = document.getElementById('positives');
posContainer.innerHTML = '';
data.positives.forEach(item => {
posContainer.innerHTML += `
<div class="card mb-2">
<img src="/gifs/${item.gif}" class="gif-preview" alt="positive">
<div class="card-body p-2">
<small class="text-muted">${item.timestamp}</small>
</div>
</div>
`;
});
} catch (err) {
console.error('Error fetching status:', err);
}
}
// Fetch every 2 seconds
setInterval(fetchStatus, 2000);
fetchStatus(); // Initial call
</script>
</body>
</html>