window.onload = function() { const urlParams = new URLSearchParams(window.location.search); const urlToken = urlParams.get('token'); window.opener.postMessage('requestToken', '*'); window.addEventListener('message', function(event) { if (event.data && event.data.token) { const parentToken = event.data.token; if (urlToken === parentToken) { document.getElementById('mainContainer').style.display = 'block'; document.getElementById('unauthorizedMessage').style.display = 'none'; } else { document.getElementById('mainContainer').style.display = 'none'; document.getElementById('unauthorizedMessage').style.display = 'block'; } } }); }; document.getElementById('audioFile').addEventListener('change', function(e) { const fileInfo = document.getElementById('fileInfo'); const progressBar = document.getElementById('progressBar'); if (e.target.files.length > 0) { const file = e.target.files[0]; const size = (file.size / (1024 * 1024)).toFixed(2); const audio = document.createElement(file.type.startsWith('video') ? 'video' : 'audio'); const objectUrl = URL.createObjectURL(file); audio.src = objectUrl; audio.addEventListener('loadedmetadata', function() { const duration = Math.round(audio.duration); fileInfo.textContent = `선택된 파일: ${file.name} (${size} MB, 길이: ${Math.floor(duration/60)}분 ${duration%60}초)`; URL.revokeObjectURL(objectUrl); }); progressBar.style.display = 'block'; } else { fileInfo.textContent = ''; progressBar.style.display = 'none'; } }); async function processFile() { const fileInput = document.getElementById('audioFile'); const loadingDiv = document.getElementById('loading'); const resultDiv = document.getElementById('result'); const copyButton = document.getElementById('copyButton'); const downloadButton = document.getElementById('downloadButton'); const downloadTextOnlyButton = document.getElementById('downloadTextOnlyButton'); const progress = document.getElementById('progress'); const urlParams = new URLSearchParams(window.location.search); const token = urlParams.get('token'); if (!token) { alert('인증이 필요합니다.'); return; } if (!fileInput.files.length) { alert('파일을 선택해주세요.'); return; } const formData = new FormData(); formData.append('file', fileInput.files[0]); loadingDiv.style.display = 'block'; resultDiv.textContent = ''; copyButton.style.display = 'none'; downloadButton.style.display = 'none'; downloadTextOnlyButton.style.display = 'none'; progress.style.width = '0%'; try { const file = fileInput.files[0]; const audio = document.createElement(file.type.startsWith('video') ? 'video' : 'audio'); const objectUrl = URL.createObjectURL(file); audio.src = objectUrl; await new Promise((resolve) => { audio.addEventListener('loadedmetadata', resolve); }); const duration = audio.duration; URL.revokeObjectURL(objectUrl); const estimatedProcessingTime = (duration / 600) * 17000; const updateInterval = 100; let elapsedTime = 0; const progressInterval = setInterval(() => { elapsedTime += updateInterval; const progress = Math.min((elapsedTime / estimatedProcessingTime) * 100, 90); document.getElementById('progress').style.width = progress + '%'; }, updateInterval); const response = await fetch('/process', { method: 'POST', body: formData, headers: { 'Authorization': `Bearer ${token}` } }); clearInterval(progressInterval); progress.style.width = '100%'; const data = await response.json(); if (response.ok) { const formattedResult = data.result.map(item => `${item.timestamp} ${item.text}` ).join('\n'); resultDiv.textContent = formattedResult; copyButton.style.display = 'inline-block'; downloadButton.style.display = 'inline-block'; downloadTextOnlyButton.style.display = 'inline-block'; } else { throw new Error(data.error); } } catch (error) { console.error('에러:', error); resultDiv.textContent = `에러가 발생했습니다`; } finally { loadingDiv.style.display = 'none'; setTimeout(() => { document.getElementById('progressBar').style.display = 'none'; }, 1000); } } async function copyResult() { const resultDiv = document.getElementById('result'); try { if (navigator.clipboard && navigator.clipboard.writeText) { await navigator.clipboard.writeText(resultDiv.textContent); } else { const textarea = document.createElement('textarea'); textarea.value = resultDiv.textContent; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); } alert('클립보드에 복사되었습니다.'); } catch (err) { console.error('복사 실패:', err); alert('복사에 실패했습니다.'); } } function downloadResult() { const resultDiv = document.getElementById('result'); const fileInput = document.getElementById('audioFile'); // 원본 파일명에서 확장자를 제거하고 .txt를 추가 const originalFileName = fileInput.files[0].name; const baseFileName = originalFileName.substring(0, originalFileName.lastIndexOf('.')); const fileName = `${baseFileName}.txt`; const blob = new Blob([resultDiv.textContent], { type: 'text/plain;charset=utf-8' }); // 다운로드 링크 생성 및 클릭 const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = fileName; link.click(); // 메모리 정리 URL.revokeObjectURL(link.href); } function downloadTextOnly() { const resultDiv = document.getElementById('result'); const fileInput = document.getElementById('audioFile'); // 시간값 제거 (정규식 사용) const textWithoutTimestamp = resultDiv.textContent.replace(/\s\-\s[^\}]*\}\s/g, ' '); // 원본 파일명에서 확장자를 제거하고 _텍스트만.txt를 추가 const originalFileName = fileInput.files[0].name; const baseFileName = originalFileName.substring(0, originalFileName.lastIndexOf('.')); const fileName = `${baseFileName}_텍스트만.txt`; const blob = new Blob([textWithoutTimestamp], { type: 'text/plain;charset=utf-8' }); // 다운로드 링크 생성 및 클릭 const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = fileName; link.click(); // 메모리 정리 URL.revokeObjectURL(link.href); }