Spaces:
No application file
No application file
| // document.addEventListener('DOMContentLoaded', () => { | |
| // const socket = io(); | |
| // const videoPlayer = document.getElementById('videoPlayer'); | |
| // const yoloTextLabel = document.getElementById('yoloTextLabel'); | |
| // const yoloImageFrame = document.getElementById('yoloImageFrame'); | |
| // const statusLabel = document.getElementById('statusLabel'); | |
| // const resetButton = document.getElementById('resetButton'); | |
| // const videoUploadInput = document.getElementById('videoUpload'); | |
| // const uploadButton = document.getElementById('uploadButton'); | |
| // // CHANGED: Get the new dropdown selector | |
| // const anomalySelector = document.getElementById('anomalySelector'); | |
| // let chart; | |
| // function initializeChart() { | |
| // const ctx = document.getElementById('anomalyChart').getContext('2d'); | |
| // if (chart) { chart.destroy(); } | |
| // chart = new Chart(ctx, { | |
| // type: 'line', data: { labels: [], datasets: [{ label: 'Anomaly Score', data: [], borderColor: 'rgba(255, 99, 132, 1)', backgroundColor: 'rgba(255, 99, 132, 0.2)', borderWidth: 2, tension: 0.4, pointRadius: 0 }] }, options: { scales: { y: { beginAtZero: true, max: 1.0, ticks: { color: '#e0e0e0' }}, x: { ticks: { color: '#e0e0e0' }}}, plugins: { legend: { labels: { color: '#e0e0e0' }}}} | |
| // }); | |
| // } | |
| // function resetUI() { | |
| // videoPlayer.pause(); | |
| // videoPlayer.removeAttribute('src'); | |
| // videoPlayer.load(); | |
| // initializeChart(); | |
| // yoloTextLabel.textContent = 'Waiting for anomaly...'; | |
| // yoloImageFrame.src = ''; | |
| // statusLabel.textContent = 'System reset. Select a video to begin.'; | |
| // videoUploadInput.value = ''; | |
| // anomalySelector.selectedIndex = 0; // Reset dropdown to the default option | |
| // } | |
| // // --- WebSocket Event Listeners (unchanged) --- | |
| // socket.on('connect', () => { statusLabel.textContent = 'Connected. Please select a video to start processing.'; }); | |
| // socket.on('update_graph', (data) => { | |
| // const { score } = data; | |
| // if (!chart) return; | |
| // const newLabel = chart.data.labels.length + 1; | |
| // chart.data.labels.push(newLabel); | |
| // chart.data.datasets[0].data.push(score); | |
| // if (chart.data.labels.length > 100) { chart.data.labels.shift(); chart.data.datasets[0].data.shift(); } | |
| // chart.update(); | |
| // }); | |
| // socket.on('update_yolo_text', (data) => { yoloTextLabel.textContent = data.text; }); | |
| // socket.on('update_yolo_image', (data) => { yoloImageFrame.src = `data:image/jpeg;base64,${data.image_data}`; }); | |
| // socket.on('update_status', (data) => { statusLabel.textContent = data.status; }); | |
| // socket.on('processing_error', (data) => { statusLabel.textContent = `Error: ${data.error}`; }); | |
| // socket.on('processing_finished', (data) => { statusLabel.textContent = data.message; }); | |
| // socket.on('system_reset_confirm', () => { resetUI(); }); | |
| // // --- User Interaction --- | |
| // // CHANGED: Replaced the old event listener for links with one for the dropdown | |
| // anomalySelector.addEventListener('change', (event) => { | |
| // const anomalyName = event.target.value; | |
| // if (!anomalyName) return; // Do nothing if the default option is selected | |
| // resetUI(); | |
| // statusLabel.textContent = `Requesting to process ${anomalyName}...`; | |
| // videoPlayer.src = `/video_stream/demo/${anomalyName}`; | |
| // videoPlayer.play(); | |
| // socket.emit('start_processing', { 'source': 'demo', 'filename': anomalyName }); | |
| // }); | |
| // resetButton.addEventListener('click', () => { socket.emit('reset_system'); }); | |
| // // Upload button logic (unchanged) | |
| // uploadButton.addEventListener('click', () => { | |
| // const file = videoUploadInput.files[0]; | |
| // if (!file) { | |
| // alert('Please select a video file first!'); | |
| // return; | |
| // } | |
| // resetUI(); | |
| // statusLabel.textContent = 'Uploading video...'; | |
| // const formData = new FormData(); | |
| // formData.append('video', file); | |
| // fetch('/upload', { method: 'POST', body: formData }) | |
| // .then(response => response.json()) | |
| // .then(data => { | |
| // if (data.success) { | |
| // const uploadedFilename = data.filename; | |
| // statusLabel.textContent = `Upload successful. Starting analysis...`; | |
| // videoPlayer.src = `/video_stream/upload/${uploadedFilename}`; | |
| // videoPlayer.play(); | |
| // socket.emit('start_processing', { 'source': 'upload', 'filename': uploadedFilename }); | |
| // } else { | |
| // statusLabel.textContent = `Error: ${data.error}`; | |
| // alert(`Upload failed: ${data.error}`); | |
| // } | |
| // }) | |
| // .catch(error => { | |
| // statusLabel.textContent = 'An error occurred during upload.'; | |
| // console.error('Upload error:', error); | |
| // }); | |
| // }); | |
| // initializeChart(); | |
| // }); | |
| document.addEventListener('DOMContentLoaded', () => { | |
| const socket = io(); | |
| // Get all UI elements | |
| const videoPlayer = document.getElementById('videoPlayer'); | |
| const yoloTextLabel = document.getElementById('yoloTextLabel'); | |
| const yoloImageFrame = document.getElementById('yoloImageFrame'); | |
| const statusLabel = document.getElementById('statusLabel'); | |
| const resetButton = document.getElementById('resetButton'); | |
| const anomalySelector = document.getElementById('anomalySelector'); | |
| const videoUploadInput = document.getElementById('videoUpload'); | |
| const uploadButton = document.getElementById('uploadButton'); | |
| // Get the new summary elements | |
| const summaryTextLabel = document.getElementById('summaryTextLabel'); | |
| const summaryLoaderContainer = document.getElementById('summaryLoaderContainer'); | |
| let chart; | |
| function initializeChart() { | |
| const ctx = document.getElementById('anomalyChart').getContext('2d'); | |
| if (chart) { chart.destroy(); } | |
| chart = new Chart(ctx, { | |
| type: 'line', data: { labels: [], datasets: [{ label: 'Anomaly Score', data: [], borderColor: 'rgba(255, 99, 132, 1)', backgroundColor: 'rgba(255, 99, 132, 0.2)', borderWidth: 2, tension: 0.4, pointRadius: 0 }] }, options: { scales: { y: { beginAtZero: true, max: 1.0, ticks: { color: '#e0e0e0' }}, x: { ticks: { color: '#e0e0e0' }}}, plugins: { legend: { labels: { color: '#e0e0e0' }}}} | |
| }); | |
| } | |
| // This function resets the whole UI | |
| function resetUI() { | |
| videoPlayer.pause(); | |
| videoPlayer.removeAttribute('src'); | |
| videoPlayer.load(); | |
| initializeChart(); | |
| yoloTextLabel.textContent = 'Waiting for anomaly...'; | |
| yoloImageFrame.src = ''; | |
| statusLabel.textContent = 'System reset. Select a video to begin.'; | |
| videoUploadInput.value = ''; | |
| anomalySelector.selectedIndex = 0; | |
| // Reset the summary box | |
| summaryLoaderContainer.style.display = 'none'; // Hide loader | |
| summaryTextLabel.style.display = 'block'; // Show text | |
| summaryTextLabel.textContent = 'Summary will appear here after analysis...'; | |
| } | |
| // --- WebSocket Event Listeners --- | |
| socket.on('connect', () => { statusLabel.textContent = 'Connected. Please select a video to start processing.'; }); | |
| socket.on('update_graph', (data) => { | |
| const { score } = data; | |
| if (!chart) return; | |
| const newLabel = chart.data.labels.length + 1; | |
| chart.data.labels.push(newLabel); | |
| chart.data.datasets[0].data.push(score); | |
| if (chart.data.labels.length > 100) { chart.data.labels.shift(); chart.data.datasets[0].data.shift(); } | |
| chart.update(); | |
| }); | |
| socket.on('update_yolo_text', (data) => { yoloTextLabel.textContent = data.text; }); | |
| socket.on('update_yolo_image', (data) => { yoloImageFrame.src = `data:image/jpeg;base64,${data.image_data}`; }); | |
| socket.on('update_status', (data) => { statusLabel.textContent = data.status; }); | |
| socket.on('processing_error', (data) => { statusLabel.textContent = `Error: ${data.error}`; }); | |
| socket.on('processing_finished', (data) => { statusLabel.textContent = data.message; }); | |
| socket.on('system_reset_confirm', () => { resetUI(); }); | |
| // NEW: Listener for the recording light | |
| socket.on('recording_signal', (data) => { | |
| if (data.recording) { | |
| statusLabel.textContent = "Anomaly detected! Recording 30s clip..."; | |
| } | |
| // The 'false' signal is handled by the summary logic | |
| }); | |
| // --- NEW: Logic for the summary box --- | |
| socket.on('update_summary', (data) => { | |
| const summary = data.summary; | |
| if (summary === 'loading') { | |
| // Show the loader | |
| summaryTextLabel.style.display = 'none'; | |
| summaryLoaderContainer.style.display = 'flex'; | |
| } else { | |
| // Hide the loader and show the final summary | |
| summaryLoaderContainer.style.display = 'none'; | |
| summaryTextLabel.style.display = 'block'; | |
| summaryTextLabel.textContent = summary; // Set the final text | |
| statusLabel.textContent = 'Analysis complete.'; // Update status | |
| } | |
| }); | |
| // --- User Interaction (No changes) --- | |
| anomalySelector.addEventListener('change', (event) => { | |
| const anomalyName = event.target.value; | |
| if (!anomalyName) return; | |
| resetUI(); | |
| statusLabel.textContent = `Requesting to process ${anomalyName}...`; | |
| videoPlayer.src = `/video_stream/demo/${anomalyName}`; | |
| videoPlayer.play(); | |
| socket.emit('start_processing', { 'source': 'demo', 'filename': anomalyName }); | |
| }); | |
| resetButton.addEventListener('click', () => { socket.emit('reset_system'); }); | |
| uploadButton.addEventListener('click', () => { | |
| const file = videoUploadInput.files[0]; | |
| if (!file) { | |
| alert('Please select a video file first!'); | |
| return; | |
| } | |
| resetUI(); | |
| statusLabel.textContent = 'Uploading video...'; | |
| const formData = new FormData(); | |
| formData.append('video', file); | |
| fetch('/upload', { method: 'POST', body: formData }) | |
| .then(response => response.json()) | |
| .then(data => { | |
| if (data.success) { | |
| const uploadedFilename = data.filename; | |
| statusLabel.textContent = `Upload successful. Starting analysis...`; | |
| videoPlayer.src = `/video_stream/upload/${uploadedFilename}`; | |
| videoPlayer.play(); | |
| socket.emit('start_processing', { 'source': 'upload', 'filename': uploadedFilename }); | |
| } else { | |
| statusLabel.textContent = `Error: ${data.error}`; | |
| alert(`Upload failed: ${data.error}`); | |
| } | |
| }) | |
| .catch(error => { | |
| statusLabel.textContent = 'An error occurred during upload.'; | |
| console.error('Upload error:', error); | |
| }); | |
| }); | |
| // Initialize the chart and UI on page load | |
| initializeChart(); | |
| resetUI(); // Call reset to ensure correct initial state | |
| }); |