document.addEventListener('DOMContentLoaded', () => { // DOM Elements const dropZone = document.getElementById('drop-zone'); const fileInput = document.getElementById('file-input'); const filePreview = document.getElementById('file-preview'); const fileName = document.getElementById('file-name'); const fileSize = document.getElementById('file-size'); const removeFileBtn = document.getElementById('remove-file-btn'); const transcribeBtn = document.getElementById('transcribe-btn'); const uploadSection = document.getElementById('upload-section'); const processingSection = document.getElementById('processing-section'); const resultSection = document.getElementById('result-section'); const detectedLang = document.getElementById('detected-lang'); const captionsList = document.getElementById('captions-list'); const fullTextContent = document.getElementById('full-text-content'); const copyTextBtn = document.getElementById('copy-text-btn'); const downloadTxtBtn = document.getElementById('download-txt-btn'); const downloadSrtBtn = document.getElementById('download-srt-btn'); const newTranscriptionBtn = document.getElementById('new-transcription-btn'); const tabBtns = document.querySelectorAll('.tab-btn'); const tabContents = document.querySelectorAll('.tab-content'); const toast = document.getElementById('toast'); const toastMessage = document.getElementById('toast-message'); // State let selectedFile = null; let transcriptionResult = null; // --- File Upload Logic --- // Click to upload dropZone.addEventListener('click', (e) => { if (e.target !== removeFileBtn && !removeFileBtn.contains(e.target)) { fileInput.click(); } }); fileInput.addEventListener('change', (e) => { if (e.target.files.length > 0) { handleFile(e.target.files[0]); } }); // Drag and drop dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.classList.add('dragover'); }); dropZone.addEventListener('dragleave', () => { dropZone.classList.remove('dragover'); }); dropZone.addEventListener('drop', (e) => { e.preventDefault(); dropZone.classList.remove('dragover'); if (e.dataTransfer.files.length > 0) { handleFile(e.dataTransfer.files[0]); } }); function handleFile(file) { // Validate file type const validTypes = ['video/mp4', 'video/quicktime', 'video/x-msvideo', 'video/webm', 'video/x-matroska']; if (!validTypes.includes(file.type) && !file.name.match(/\.(mp4|mov|avi|webm|mkv)$/i)) { showToast('Invalid file format. Please upload a video.', true); return; } // Validate file size (e.g., 50MB max to prevent huge uploads locally) const maxSize = 50 * 1024 * 1024; if (file.size > maxSize) { showToast('File is too large. Max size is 50MB.', true); return; } selectedFile = file; fileName.textContent = file.name; fileSize.textContent = formatBytes(file.size); dropZone.style.display = 'none'; filePreview.classList.remove('hidden'); transcribeBtn.classList.remove('hidden'); } removeFileBtn.addEventListener('click', (e) => { e.stopPropagation(); selectedFile = null; fileInput.value = ''; dropZone.style.display = 'block'; filePreview.classList.add('hidden'); transcribeBtn.classList.add('hidden'); }); // --- API & Processing --- transcribeBtn.addEventListener('click', async () => { if (!selectedFile) return; // Show processing uploadSection.classList.add('hidden'); processingSection.classList.remove('hidden'); const formData = new FormData(); formData.append('file', selectedFile); const apiKeyInput = document.getElementById('api-key-input'); if (apiKeyInput && apiKeyInput.value.trim() !== '') { formData.append('api_key', apiKeyInput.value.trim()); } let apiUrl = '/api/transcribe'; // Fallback for local development if opened directly or via Live Server if (window.location.protocol === 'file:' || window.location.port === '5500' || window.location.hostname === '127.0.0.1' && window.location.port !== '8000') { apiUrl = 'http://127.0.0.1:8000/api/transcribe'; } try { const response = await fetch(apiUrl, { method: 'POST', body: formData }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.detail || `Server error: ${response.status}`); } const data = await response.json(); transcriptionResult = data; renderResults(data); processingSection.classList.add('hidden'); resultSection.classList.remove('hidden'); showToast('Transcription successful!'); } catch (error) { console.error('Transcription error:', error); showToast(error.message || 'Transcription failed', true); // Revert UI processingSection.classList.add('hidden'); uploadSection.classList.remove('hidden'); } }); // --- Result Rendering --- function renderResults(data) { // Language detection let langName = 'Mixed / Unknown'; if (data.segments && data.segments.length > 0) { const lang = data.segments[0].lang || 'hi-en'; if (lang === 'en') langName = 'English'; else if (lang === 'hi') langName = 'Hindi'; else if (lang.includes('hi') && lang.includes('en')) langName = 'Hinglish'; else langName = lang.toUpperCase(); } detectedLang.textContent = `Detected: ${langName}`; // Render full text fullTextContent.textContent = data.text; // Render captions captionsList.innerHTML = ''; if (data.segments && data.segments.length > 0) { data.segments.forEach(seg => { const item = document.createElement('div'); item.className = 'caption-item'; item.innerHTML = `