File size: 4,955 Bytes
308500d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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();
});