const fileInput = document.getElementById('fileUpload'); const urlInput = document.getElementById('urlInput'); const analyzeBtn = document.getElementById('analyzeBtn'); const resultBox = document.getElementById('result'); const resultText = document.getElementById('resultText'); const previewBox = document.getElementById('preview'); const logList = document.getElementById('logList'); analyzeBtn.addEventListener('click', () => { resultBox.classList.add('hidden'); resultText.textContent = ''; previewBox.innerHTML = ''; const urlVal = urlInput.value.trim(); if (fileInput.files.length > 0) { const file = fileInput.files[0]; renderPreview(file); analyzeBackend({ file }); } else if (urlVal) { renderURLPreview(urlVal); analyzeBackend({ url: urlVal }); } else { alert('Please upload a file or enter a URL.'); } }); function renderPreview(file) { const fileURL = URL.createObjectURL(file); if (file.type.startsWith('video')) { const video = document.createElement('video'); video.src = fileURL; video.controls = true; video.width = 400; previewBox.appendChild(video); } else if (file.type.startsWith('audio')) { const audio = document.createElement('audio'); audio.src = fileURL; audio.controls = true; previewBox.appendChild(audio); const canvas = document.createElement('canvas'); canvas.id = 'waveform'; canvas.width = 400; canvas.height = 100; canvas.style.marginTop = '10px'; previewBox.appendChild(canvas); visualizeAudio(audio, canvas); } } function renderURLPreview(url) { const link = document.createElement('a'); link.href = url; link.textContent = url; link.target = '_blank'; previewBox.appendChild(link); } async function analyzeBackend({ file = null, url = '' }) { const fd = new FormData(); if (file) fd.append('file', file); if (url) fd.append('url', url); resultText.textContent = 'Analyzing...\\n'; resultBox.classList.remove('hidden'); try { const res = await fetch("/api/analyze", { method: 'POST', body: fd }); if (!res.ok) throw new Error('Server error'); const data = await res.json(); displayResults(data); } catch (err) { resultText.textContent += `Error: ${err.message}`; } } function displayResults(data) { const { summary, transcript = [], subliminal_flags = [] } = data; resultText.textContent = summary + '\\n\\n'; if (subliminal_flags.length) { subliminal_flags.forEach(flag => { resultText.textContent += `⚠ ${flag.type} at ${flag.timestamp} – ${flag.content}\\n`; }); resultText.textContent += '\\n'; } resultText.textContent += '--- Transcript ---\\n' + transcript.join('\\n'); const li = document.createElement('li'); li.textContent = summary; logList.appendChild(li); } function visualizeAudio(audioEl, canvasEl) { const ctx = canvasEl.getContext('2d'); const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); const analyser = audioCtx.createAnalyser(); analyser.fftSize = 2048; const source = audioCtx.createMediaElementSource(audioEl); source.connect(analyser); analyser.connect(audioCtx.destination); const bufferLength = analyser.fftSize; const dataArray = new Uint8Array(bufferLength); function draw() { requestAnimationFrame(draw); analyser.getByteTimeDomainData(dataArray); ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, canvasEl.width, canvasEl.height); ctx.lineWidth = 2; ctx.strokeStyle = '#3498db'; ctx.beginPath(); const sliceWidth = canvasEl.width * 1.0 / bufferLength; let x = 0; for (let i = 0; i < bufferLength; i++) { const v = dataArray[i] / 128.0; const y = v * canvasEl.height / 2; if (i === 0) { ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } x += sliceWidth; } ctx.lineTo(canvasEl.width, canvasEl.height / 2); ctx.stroke(); } draw(); }