| 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(); | |
| } | |