Download static/js/script.js from koesan/VerbaLive: direct link, hf CLI and curl.
- Browser
- Download file 6.75 kB
-
https://huggingface.co/spaces/koesan/VerbaLive/resolve/main/static/js/script.js
- Command line
-
hf download hf://spaces/koesan/VerbaLive/static/js/script.js
-
curl -L -o script.js https://huggingface.co/spaces/koesan/VerbaLive/resolve/main/static/js/script.js
6.75 kB
| document.addEventListener('DOMContentLoaded', () => { | |
| const startBtn = document.getElementById('start-mic-btn'); | |
| const stopBtn = document.getElementById('stop-mic-btn'); | |
| const clearBtn = document.getElementById('clear-btn'); | |
| const serviceSelect = document.getElementById('service-select'); | |
| const langSelect = document.getElementById('lang-select'); | |
| const deeplKeyInput = document.getElementById('deepl-key'); | |
| const deeplLabel = document.getElementById('deepl-label'); | |
| const englishOutput = document.getElementById('english-output'); | |
| const realtimeOutput = document.getElementById('realtime-output'); | |
| const detailedOutput = document.getElementById('detailed-output'); | |
| const statusLabel = document.getElementById('status-label'); | |
| let isRecording = false; | |
| let audioContext; | |
| let processor; | |
| let eventSource = null; | |
| let lastEnglishText = ""; // Tamamlanmış son İngilizce metin | |
| let lastRealtimeText = ""; // Tamamlanmış son çeviri metni | |
| // DeepL API key girişini göster/gizle | |
| serviceSelect.addEventListener('change', (e) => { | |
| if (e.target.value === 'DeepL') { | |
| deeplKeyInput.style.display = 'inline-block'; | |
| deeplLabel.style.display = 'inline-block'; | |
| } else { | |
| deeplKeyInput.style.display = 'none'; | |
| deeplLabel.style.display = 'none'; | |
| } | |
| }); | |
| // Ses verisini sunucuya gönderme | |
| function sendAudioToServer(data) { | |
| if (!isRecording) return; | |
| fetch('/upload_audio', { | |
| method: 'POST', | |
| body: data, | |
| headers: { | |
| 'Content-Type': 'application/octet-stream' | |
| } | |
| }).catch(error => console.error('Error sending audio:', error)); | |
| } | |
| // SSE bağlantısını başlat | |
| function startEventSource() { | |
| const params = new URLSearchParams({ | |
| target_lang: langSelect.value, | |
| service: serviceSelect.value, | |
| deepl_key: deeplKeyInput.value | |
| }); | |
| eventSource = new EventSource(`/stream_results?${params.toString()}`); | |
| eventSource.onmessage = (event) => { | |
| const data = JSON.parse(event.data); | |
| const asrText = data.english; | |
| const asrType = data.type; | |
| const translation = data.translation; | |
| if (asrType === "partial") { | |
| // Anlık İngilizce ve çeviri metnini güncelle | |
| englishOutput.textContent = lastEnglishText + asrText; | |
| realtimeOutput.textContent = lastRealtimeText + translation; | |
| } else if (asrType === "final") { | |
| // Final cümle geldiğinde alt satıra geç ve metinleri sakla | |
| lastEnglishText += asrText + "\n"; | |
| lastRealtimeText += translation + "\n"; | |
| // Detaylı çeviriye ekle | |
| detailedOutput.textContent += asrText + " --> " + translation + "\n"; | |
| // Anlık çeviri kutusunu sıfırla | |
| englishOutput.textContent = lastEnglishText; | |
| realtimeOutput.textContent = lastRealtimeText; | |
| } | |
| englishOutput.scrollTop = englishOutput.scrollHeight; | |
| realtimeOutput.scrollTop = realtimeOutput.scrollHeight; | |
| detailedOutput.scrollTop = detailedOutput.scrollHeight; | |
| }; | |
| eventSource.onerror = (err) => { | |
| console.error("EventSource hatası:", err); | |
| statusLabel.textContent = "🔴 Hata: Bağlantı kesildi!"; | |
| statusLabel.style.color = "#ff453a"; | |
| if (eventSource) eventSource.close(); | |
| stopRecording(); | |
| }; | |
| } | |
| function stopEventSource() { | |
| if (eventSource) { | |
| eventSource.close(); | |
| eventSource = null; | |
| } | |
| } | |
| // Olay Dinleyicileri | |
| startBtn.addEventListener('click', async () => { | |
| if (isRecording) return; | |
| isRecording = true; | |
| startBtn.style.display = 'none'; | |
| stopBtn.style.display = 'block'; | |
| statusLabel.textContent = "🟢 Kaydediyor..."; | |
| statusLabel.style.color = "#30d158"; | |
| // Metin alanlarını temizle | |
| englishOutput.textContent = ""; | |
| realtimeOutput.textContent = ""; | |
| detailedOutput.textContent = ""; | |
| lastEnglishText = ""; | |
| lastRealtimeText = ""; | |
| try { | |
| const stream = await navigator.mediaDevices.getUserMedia({ audio: { sampleRate: 16000 } }); | |
| audioContext = new (window.AudioContext || window.webkitAudioContext)({ sampleRate: 16000 }); | |
| const source = audioContext.createMediaStreamSource(stream); | |
| const bufferSize = 4096; | |
| processor = audioContext.createScriptProcessor(bufferSize, 1, 1); | |
| source.connect(processor); | |
| processor.connect(audioContext.destination); | |
| processor.onaudioprocess = (e) => { | |
| if (!isRecording) return; | |
| const pcmData = e.inputBuffer.getChannelData(0); | |
| const pcm16 = new Int16Array(pcmData.length); | |
| for (let i = 0; i < pcmData.length; i++) { | |
| pcm16[i] = Math.max(-1, Math.min(1, pcmData[i])) * 0x7FFF; | |
| } | |
| sendAudioToServer(pcm16.buffer); | |
| }; | |
| await fetch('/start', { method: 'POST' }); | |
| startEventSource(); | |
| } catch (err) { | |
| console.error('Mikrofon erişimi reddedildi veya hata oluştu:', err); | |
| statusLabel.textContent = "🔴 Hata: Mikrofon erişimi reddedildi!"; | |
| statusLabel.style.color = "#ff453a"; | |
| isRecording = false; | |
| startBtn.style.display = 'block'; | |
| stopBtn.style.display = 'none'; | |
| } | |
| }); | |
| stopBtn.addEventListener('click', () => { | |
| stopRecording(); | |
| }); | |
| function stopRecording() { | |
| if (!isRecording) return; | |
| isRecording = false; | |
| if (audioContext) { | |
| audioContext.close(); | |
| audioContext = null; | |
| } | |
| startBtn.style.display = 'block'; | |
| stopBtn.style.display = 'none'; | |
| statusLabel.textContent = "🔴 Hazır - 'Başlat' butonuna basın"; | |
| statusLabel.style.color = "#30d158"; | |
| stopEventSource(); | |
| fetch('/stop', { method: 'POST' }); | |
| } | |
| clearBtn.addEventListener('click', () => { | |
| englishOutput.textContent = ""; | |
| realtimeOutput.textContent = ""; | |
| detailedOutput.textContent = ""; | |
| lastEnglishText = ""; | |
| lastRealtimeText = ""; | |
| statusLabel.textContent = "🟢 Tüm veriler temizlendi."; | |
| }); | |
| }); |