// API base URL - automatically detect from current location const API_BASE = `${window.location.protocol}//${window.location.host}/api/videos`; // Tab switching document.querySelectorAll('.tab-btn').forEach(btn => { btn.addEventListener('click', () => { const tab = btn.dataset.tab; switchTab(tab); }); }); function switchTab(tabName) { // Update buttons document.querySelectorAll('.tab-btn').forEach(btn => { btn.classList.remove('active'); if (btn.dataset.tab === tabName) { btn.classList.add('active'); } }); // Update content document.querySelectorAll('.tab-content').forEach(content => { content.classList.remove('active'); }); document.getElementById(`${tabName}-tab`).classList.add('active'); // Load data when switching tabs if (tabName === 'list') { loadVideos(); } else if (tabName === 'compare') { loadVideosForCompare(); } } // File upload const fileInput = document.getElementById('file-input'); const uploadArea = document.getElementById('upload-area'); fileInput.addEventListener('change', handleFileSelect); uploadArea.addEventListener('dragover', (e) => { e.preventDefault(); uploadArea.style.borderColor = '#764ba2'; }); uploadArea.addEventListener('dragleave', () => { uploadArea.style.borderColor = '#667eea'; }); uploadArea.addEventListener('drop', (e) => { e.preventDefault(); uploadArea.style.borderColor = '#667eea'; const files = e.dataTransfer.files; if (files.length > 0) { fileInput.files = files; handleFileSelect({ target: fileInput }); } }); function handleFileSelect(e) { const file = e.target.files[0]; if (!file) return; uploadFile(file); } function uploadFile(file) { const formData = new FormData(); formData.append('file', file); const progressDiv = document.getElementById('upload-progress'); const progressFill = document.getElementById('progress-fill'); const progressText = document.getElementById('progress-text'); const resultDiv = document.getElementById('upload-result'); // Show progress document.querySelector('.upload-placeholder').style.display = 'none'; progressDiv.style.display = 'block'; progressFill.style.width = '0%'; resultDiv.style.display = 'none'; // Upload using fetch fetch(`${API_BASE}/upload`, { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { progressFill.style.width = '100%'; progressText.textContent = '上传完成!'; setTimeout(() => { if (data.success) { showResult('upload-result', `视频上传成功!ID: ${data.data.video_id}`, 'success'); // Reset form fileInput.value = ''; document.querySelector('.upload-placeholder').style.display = 'block'; progressDiv.style.display = 'none'; } else { showResult('upload-result', data.message || '上传失败', 'error'); } }, 500); }) .catch(error => { showResult('upload-result', `上传失败: ${error.message}`, 'error'); progressDiv.style.display = 'none'; document.querySelector('.upload-placeholder').style.display = 'block'; }); } // Load videos list function loadVideos() { const videoList = document.getElementById('video-list'); videoList.innerHTML = '
加载中...
'; fetch(`${API_BASE}`) .then(response => response.json()) .then(data => { if (data.success && data.data.length > 0) { videoList.innerHTML = ''; data.data.forEach(video => { const videoItem = createVideoItem(video); videoList.appendChild(videoItem); }); } else { videoList.innerHTML = '暂无视频
'; } }) .catch(error => { videoList.innerHTML = `加载失败: ${error.message}
`; }); } function createVideoItem(video) { const div = document.createElement('div'); div.className = 'video-item'; const sizeMB = (video.file_size / (1024 * 1024)).toFixed(2); const uploadTime = new Date(video.upload_time).toLocaleString('zh-CN'); div.innerHTML = `文件名: ${video.filename}
大小: ${(video.file_size / (1024 * 1024)).toFixed(2)} MB
状态: ${getStatusText(video.status)}
上传时间: ${new Date(video.upload_time).toLocaleString('zh-CN')}
${video.analysis.content}
FPS: ${video.analysis.fps} | 创建时间: ${new Date(video.analysis.created_at).toLocaleString('zh-CN')}
${video.summary.summary_text}
创建时间: ${new Date(video.summary.created_at).toLocaleString('zh-CN')}
正在分析视频,请稍候...
'; document.body.appendChild(loadingMsg); fetch(`${API_BASE}/${videoId}/analyze`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}) }) .then(response => response.json()) .then(data => { // Remove loading message const loadingEl = document.getElementById('analysis-loading'); if (loadingEl) { loadingEl.remove(); } if (data.success) { // Refresh video list first loadVideos(); // Then automatically open video details to show the analysis setTimeout(() => { viewVideoDetails(videoId); }, 500); } else { alert(data.message || '分析失败'); } }) .catch(error => { // Remove loading message const loadingEl = document.getElementById('analysis-loading'); if (loadingEl) { loadingEl.remove(); } alert(`分析失败: ${error.message}`); }); } // Summarize video function summarizeVideo(videoId) { if (!confirm('确定要生成视频总结吗?这可能需要一些时间。')) { return; } // Show loading message const loadingMsg = document.createElement('div'); loadingMsg.id = 'summary-loading'; loadingMsg.style.cssText = 'position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); z-index: 10000;'; loadingMsg.innerHTML = '正在生成视频总结,请稍候...
'; document.body.appendChild(loadingMsg); fetch(`${API_BASE}/${videoId}/summarize`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}) }) .then(response => response.json()) .then(data => { // Remove loading message const loadingEl = document.getElementById('summary-loading'); if (loadingEl) { loadingEl.remove(); } if (data.success) { // Refresh video list first loadVideos(); // Then automatically open video details to show the summary setTimeout(() => { viewVideoDetails(videoId); }, 500); } else { alert(data.message || '总结生成失败'); } }) .catch(error => { // Remove loading message const loadingEl = document.getElementById('summary-loading'); if (loadingEl) { loadingEl.remove(); } alert(`总结生成失败: ${error.message}`); }); } // Compare videos function loadVideosForCompare() { const compareList = document.getElementById('compare-video-list'); compareList.innerHTML = '加载中...
'; fetch(`${API_BASE}`) .then(response => response.json()) .then(data => { if (data.success && data.data.length > 0) { compareList.innerHTML = ''; data.data.forEach(video => { const checkbox = document.createElement('div'); checkbox.className = 'video-checkbox-item'; checkbox.innerHTML = ` `; compareList.appendChild(checkbox); }); } else { compareList.innerHTML = '暂无视频,请先上传视频
'; } }) .catch(error => { compareList.innerHTML = `加载失败: ${error.message}
`; }); } function updateCompareButton() { const checked = document.querySelectorAll('#compare-video-list input[type="checkbox"]:checked'); const compareBtn = document.getElementById('compare-btn'); compareBtn.disabled = checked.length < 2; } function compareVideos() { const checked = document.querySelectorAll('#compare-video-list input[type="checkbox"]:checked'); if (checked.length < 2) { alert('请至少选择2个视频进行对比'); return; } if (!confirm(`确定要对比这 ${checked.length} 个视频吗?这可能需要一些时间。`)) { return; } const videoIds = Array.from(checked).map(cb => cb.value); const resultDiv = document.getElementById('compare-result'); resultDiv.innerHTML = '对比中,请稍候...
'; resultDiv.className = 'result-message'; resultDiv.style.display = 'block'; fetch(`${API_BASE}/compare`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ video_ids: videoIds }) }) .then(response => response.json()) .then(data => { if (data.success) { resultDiv.className = 'result-message success'; resultDiv.innerHTML = `