Spaces:
Sleeping
Sleeping
Update templates/index.html
Browse files- templates/index.html +64 -0
templates/index.html
CHANGED
|
@@ -359,6 +359,27 @@
|
|
| 359 |
<i class="fas fa-play"></i> Raw Feed
|
| 360 |
</button>
|
| 361 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 362 |
|
| 363 |
<div class="grid grid-cols-3 gap-2 sm:gap-5 mt-6 sm:mt-10">
|
| 364 |
<div class="ios-glass-inner p-3 sm:p-5 rounded-2xl sm:rounded-3xl flex flex-col items-center text-center gap-1 hover:bg-white/60 dark:hover:bg-white/10 transition-colors">
|
|
@@ -720,6 +741,7 @@
|
|
| 720 |
|
| 721 |
let streamId = null;
|
| 722 |
let poller = null;
|
|
|
|
| 723 |
|
| 724 |
function openIpCamModal() { document.getElementById('ipCamModal').classList.remove('hidden'); }
|
| 725 |
function closeIpCamModal() { document.getElementById('ipCamModal').classList.add('hidden'); }
|
|
@@ -780,6 +802,10 @@
|
|
| 780 |
|
| 781 |
document.getElementById('previewImg').src = `/video_feed/${streamId}?loc=${encodeURIComponent(data.location)}&t=${Date.now()}`;
|
| 782 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 783 |
if(poller) clearInterval(poller);
|
| 784 |
poller = setInterval(update, 1000);
|
| 785 |
}
|
|
@@ -807,6 +833,39 @@
|
|
| 807 |
});
|
| 808 |
}
|
| 809 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 810 |
function takeSnapshot() {
|
| 811 |
const feed = document.getElementById('previewImg');
|
| 812 |
if(feed && feed.src) {
|
|
@@ -851,6 +910,10 @@
|
|
| 851 |
document.getElementById('rcnnVal').innerText = `${data.rcnn || 0}%`;
|
| 852 |
document.getElementById('severityLevel').innerText = data.severity || "--";
|
| 853 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 854 |
const statusCard = document.getElementById('statusCard');
|
| 855 |
const statusIcon = document.getElementById('statusIcon');
|
| 856 |
const emergencyBanner = document.getElementById('emergencyBanner');
|
|
@@ -891,6 +954,7 @@
|
|
| 891 |
document.getElementById('results').classList.add('hidden');
|
| 892 |
document.getElementById('emergencyBanner').classList.add('hidden');
|
| 893 |
document.getElementById('alprSection').classList.add('hidden');
|
|
|
|
| 894 |
|
| 895 |
// Wipe Form and Upload fields completely
|
| 896 |
document.getElementById('fileInput').value = "";
|
|
|
|
| 359 |
<i class="fas fa-play"></i> Raw Feed
|
| 360 |
</button>
|
| 361 |
</div>
|
| 362 |
+
|
| 363 |
+
<!-- Advanced Video Controls -->
|
| 364 |
+
<div class="mt-6 bg-white/40 dark:bg-black/40 p-4 rounded-2xl border border-indigo-200/50 dark:border-white/10 shadow-sm backdrop-blur-sm">
|
| 365 |
+
<!-- Progress Bar -->
|
| 366 |
+
<div class="w-full h-2 bg-indigo-200/50 dark:bg-white/20 rounded-full mb-4 cursor-pointer relative" onclick="seekVideo(event)" id="progressBarContainer">
|
| 367 |
+
<div id="progressFill" class="absolute top-0 left-0 h-full bg-indigo-600 dark:bg-purple-500 rounded-full transition-all duration-300 pointer-events-none" style="width: 0%"></div>
|
| 368 |
+
</div>
|
| 369 |
+
|
| 370 |
+
<!-- Playback Buttons -->
|
| 371 |
+
<div class="flex justify-center items-center gap-6">
|
| 372 |
+
<button onclick="skipVideo(-5)" class="text-indigo-900 dark:text-white hover:text-indigo-600 dark:hover:text-purple-300 transition-colors cursor-pointer">
|
| 373 |
+
<i class="fas fa-backward"></i> <span class="text-[10px] font-black ml-1">-5s</span>
|
| 374 |
+
</button>
|
| 375 |
+
<button onclick="togglePlayPause()" class="w-12 h-12 rounded-full bg-indigo-600 dark:bg-purple-600 text-white flex items-center justify-center hover:scale-105 transition-transform shadow-lg cursor-pointer">
|
| 376 |
+
<i id="playPauseIcon" class="fas fa-pause text-lg"></i>
|
| 377 |
+
</button>
|
| 378 |
+
<button onclick="skipVideo(5)" class="text-indigo-900 dark:text-white hover:text-indigo-600 dark:hover:text-purple-300 transition-colors cursor-pointer">
|
| 379 |
+
<span class="text-[10px] font-black mr-1">+5s</span> <i class="fas fa-forward"></i>
|
| 380 |
+
</button>
|
| 381 |
+
</div>
|
| 382 |
+
</div>
|
| 383 |
|
| 384 |
<div class="grid grid-cols-3 gap-2 sm:gap-5 mt-6 sm:mt-10">
|
| 385 |
<div class="ios-glass-inner p-3 sm:p-5 rounded-2xl sm:rounded-3xl flex flex-col items-center text-center gap-1 hover:bg-white/60 dark:hover:bg-white/10 transition-colors">
|
|
|
|
| 741 |
|
| 742 |
let streamId = null;
|
| 743 |
let poller = null;
|
| 744 |
+
let isPaused = false;
|
| 745 |
|
| 746 |
function openIpCamModal() { document.getElementById('ipCamModal').classList.remove('hidden'); }
|
| 747 |
function closeIpCamModal() { document.getElementById('ipCamModal').classList.add('hidden'); }
|
|
|
|
| 802 |
|
| 803 |
document.getElementById('previewImg').src = `/video_feed/${streamId}?loc=${encodeURIComponent(data.location)}&t=${Date.now()}`;
|
| 804 |
|
| 805 |
+
// Reset pause state
|
| 806 |
+
isPaused = false;
|
| 807 |
+
document.getElementById('playPauseIcon').className = 'fas fa-pause text-lg';
|
| 808 |
+
|
| 809 |
if(poller) clearInterval(poller);
|
| 810 |
poller = setInterval(update, 1000);
|
| 811 |
}
|
|
|
|
| 833 |
});
|
| 834 |
}
|
| 835 |
|
| 836 |
+
async function togglePlayPause() {
|
| 837 |
+
if(!streamId) return;
|
| 838 |
+
isPaused = !isPaused;
|
| 839 |
+
document.getElementById('playPauseIcon').className = isPaused ? 'fas fa-play text-lg' : 'fas fa-pause text-lg';
|
| 840 |
+
await fetch(`/video_control/${streamId}`, {
|
| 841 |
+
method: 'POST',
|
| 842 |
+
headers: {'Content-Type': 'application/json'},
|
| 843 |
+
body: JSON.stringify({action: isPaused ? 'pause' : 'play'})
|
| 844 |
+
});
|
| 845 |
+
}
|
| 846 |
+
|
| 847 |
+
async function skipVideo(seconds) {
|
| 848 |
+
if(!streamId) return;
|
| 849 |
+
await fetch(`/video_control/${streamId}`, {
|
| 850 |
+
method: 'POST',
|
| 851 |
+
headers: {'Content-Type': 'application/json'},
|
| 852 |
+
body: JSON.stringify({action: 'skip', value: seconds})
|
| 853 |
+
});
|
| 854 |
+
}
|
| 855 |
+
|
| 856 |
+
async function seekVideo(event) {
|
| 857 |
+
if(!streamId) return;
|
| 858 |
+
const container = document.getElementById('progressBarContainer');
|
| 859 |
+
const rect = container.getBoundingClientRect();
|
| 860 |
+
const pos = Math.max(0, Math.min(1, (event.clientX - rect.left) / rect.width));
|
| 861 |
+
|
| 862 |
+
await fetch(`/video_control/${streamId}`, {
|
| 863 |
+
method: 'POST',
|
| 864 |
+
headers: {'Content-Type': 'application/json'},
|
| 865 |
+
body: JSON.stringify({action: 'seek', value: pos})
|
| 866 |
+
});
|
| 867 |
+
}
|
| 868 |
+
|
| 869 |
function takeSnapshot() {
|
| 870 |
const feed = document.getElementById('previewImg');
|
| 871 |
if(feed && feed.src) {
|
|
|
|
| 910 |
document.getElementById('rcnnVal').innerText = `${data.rcnn || 0}%`;
|
| 911 |
document.getElementById('severityLevel').innerText = data.severity || "--";
|
| 912 |
|
| 913 |
+
if (data.progress !== undefined) {
|
| 914 |
+
document.getElementById('progressFill').style.width = `${data.progress}%`;
|
| 915 |
+
}
|
| 916 |
+
|
| 917 |
const statusCard = document.getElementById('statusCard');
|
| 918 |
const statusIcon = document.getElementById('statusIcon');
|
| 919 |
const emergencyBanner = document.getElementById('emergencyBanner');
|
|
|
|
| 954 |
document.getElementById('results').classList.add('hidden');
|
| 955 |
document.getElementById('emergencyBanner').classList.add('hidden');
|
| 956 |
document.getElementById('alprSection').classList.add('hidden');
|
| 957 |
+
document.getElementById('progressFill').style.width = "0%";
|
| 958 |
|
| 959 |
// Wipe Form and Upload fields completely
|
| 960 |
document.getElementById('fileInput').value = "";
|