Spaces:
Runtime error
Runtime error
| let selectedFile = null; | |
| let currentTrajectories = null; | |
| // DOM elements | |
| const uploadBox = document.getElementById('uploadBox'); | |
| const videoInput = document.getElementById('videoInput'); | |
| const uploadBtn = document.getElementById('uploadBtn'); | |
| const loadingSection = document.getElementById('loadingSection'); | |
| const resultsSection = document.getElementById('resultsSection'); | |
| const playBtn = document.getElementById('playBtn'); | |
| const resetBtn = document.getElementById('resetBtn'); | |
| const showTrails = document.getElementById('showTrails'); | |
| // Upload box click | |
| uploadBox.addEventListener('click', () => { | |
| videoInput.click(); | |
| }); | |
| // File selection | |
| videoInput.addEventListener('change', (e) => { | |
| const file = e.target.files[0]; | |
| if (file) { | |
| selectedFile = file; | |
| uploadBox.querySelector('h3').textContent = `Selected: ${file.name}`; | |
| uploadBox.querySelector('p').textContent = `Size: ${(file.size / 1024 / 1024).toFixed(2)} MB`; | |
| uploadBtn.style.display = 'block'; | |
| } | |
| }); | |
| // Drag and drop | |
| uploadBox.addEventListener('dragover', (e) => { | |
| e.preventDefault(); | |
| uploadBox.classList.add('dragover'); | |
| }); | |
| uploadBox.addEventListener('dragleave', () => { | |
| uploadBox.classList.remove('dragover'); | |
| }); | |
| uploadBox.addEventListener('drop', (e) => { | |
| e.preventDefault(); | |
| uploadBox.classList.remove('dragover'); | |
| const file = e.dataTransfer.files[0]; | |
| if (file && file.type.startsWith('video/')) { | |
| selectedFile = file; | |
| uploadBox.querySelector('h3').textContent = `Selected: ${file.name}`; | |
| uploadBox.querySelector('p').textContent = `Size: ${(file.size / 1024 / 1024).toFixed(2)} MB`; | |
| uploadBtn.style.display = 'block'; | |
| } else { | |
| alert('Please drop a valid video file'); | |
| } | |
| }); | |
| // Upload and process | |
| uploadBtn.addEventListener('click', async () => { | |
| if (!selectedFile) return; | |
| const formData = new FormData(); | |
| formData.append('file', selectedFile); | |
| // Show loading | |
| document.querySelector('.upload-section').style.display = 'none'; | |
| loadingSection.style.display = 'block'; | |
| try { | |
| const response = await fetch('/api/upload', { | |
| method: 'POST', | |
| body: formData | |
| }); | |
| if (!response.ok) { | |
| throw new Error('Upload failed'); | |
| } | |
| const data = await response.json(); | |
| currentTrajectories = data.trajectories; | |
| // Display results | |
| displayResults(data.trajectories); | |
| loadingSection.style.display = 'none'; | |
| resultsSection.style.display = 'block'; | |
| } catch (error) { | |
| console.error('Error:', error); | |
| alert('Error processing video: ' + error.message); | |
| loadingSection.style.display = 'none'; | |
| document.querySelector('.upload-section').style.display = 'block'; | |
| } | |
| }); | |
| // Display results | |
| function displayResults(data) { | |
| const metadata = data.metadata; | |
| const trajectories = data.trajectories; | |
| // Update stats | |
| document.getElementById('statObjects').textContent = metadata.num_objects; | |
| document.getElementById('statFrames').textContent = metadata.frame_count; | |
| document.getElementById('statFPS').textContent = metadata.fps.toFixed(1); | |
| document.getElementById('statDuration').textContent = | |
| (metadata.frame_count / metadata.fps).toFixed(1) + 's'; | |
| // Initialize 3D visualization | |
| if (window.visualizer) { | |
| window.visualizer.destroy(); | |
| } | |
| window.visualizer = new TrajectoryVisualizer('canvas3d'); | |
| window.visualizer.loadTrajectories(trajectories); | |
| } | |
| // Control buttons | |
| playBtn.addEventListener('click', () => { | |
| if (window.visualizer) { | |
| if (window.visualizer.isPlaying) { | |
| window.visualizer.pause(); | |
| playBtn.textContent = '▶ Play'; | |
| } else { | |
| window.visualizer.play(); | |
| playBtn.textContent = '⏸ Pause'; | |
| } | |
| } | |
| }); | |
| resetBtn.addEventListener('click', () => { | |
| if (window.visualizer) { | |
| window.visualizer.reset(); | |
| playBtn.textContent = '▶ Play'; | |
| } | |
| }); | |
| showTrails.addEventListener('change', (e) => { | |
| if (window.visualizer) { | |
| window.visualizer.setShowTrails(e.target.checked); | |
| } | |
| }); |