klik untuk menyalin
👇
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Voice Translator - Demo</title>
<style>
body{font-family:system-ui,Segoe UI,Roboto;max-width:720px;margin:2rem auto;padding:1rem}
button{padding:10px 16px;margin:6px}
.box{border:1px solid #ddd;padding:12px;border-radius:8px;margin-top:12px}
</style>
</head>
<body>
<h1>Voice Translator Demo</h1>
<p>Bahasa input:
<select id="srcLang">
<option value="id">Indonesian (id)</option>
<option value="su">Sundanese (su)</option>
<option value="en">English (en)</option>
<option value="ja">Japanese (ja)</option>
<option value="ar">Arabic (ar)</option>
</select>
→ Bahasa keluaran:
<select id="tgtLang">
<option value="en">English (en)</option>
<option value="id" selected>Indonesian (id)</option>
<option value="su">Sundanese (su)</option>
<option value="ja">Japanese (ja)</option>
</select>
</p>
<button id="startBtn">🎤 Start Listening</button>
<button id="stopBtn" disabled>⏹ Stop</button>
<button id="speakBtn" disabled>🔊 Play Translation</button>
<div class="box">
<strong>Recognized:</strong>
<div id="recognized" style="min-height:2rem"></div>
<strong>Translated:</strong>
<div id="translated" style="min-height:2rem;color:blue"></div>
</div>
<script>
/*
NOTES:
- This demo uses Web Speech API for recognition and SpeechSynthesis for TTS.
- For translation it calls a public LibreTranslate endpoint. For production, use
an official paid API (Google/Microsoft) and keep API keys on a backend.
- Browser support: Chrome recommended.
*/
const startBtn = document.getElementById('startBtn');
const stopBtn = document.getElementById('stopBtn');
const speakBtn = document.getElementById('speakBtn');
const recognizedEl = document.getElementById('recognized');
const translatedEl = document.getElementById('translated');
const srcLangSel = document.getElementById('srcLang');
const tgtLangSel = document.getElementById('tgtLang');
let recognition;
let lastTranslated = '';
if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
alert('Browser not supported: please use Chrome (desktop or Android Chrome).');
} else {
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
recognition = new SpeechRecognition();
recognition.lang = srcLangSel.value || 'id';
recognition.interimResults = false;
recognition.maxAlternatives = 1;
recognition.onresult = async (event) => {
const text = event.results[0][0].transcript;
recognizedEl.textContent = text;
await doTranslate(text);
speakBtn.disabled = false;
};
recognition.onerror = (e) => {
console.error('Recognition error', e);
};
recognition.onend = () => {
startBtn.disabled = false;
stopBtn.disabled = true;
};
}
srcLangSel.addEventListener('change', () => {
if (recognition) recognition.lang = srcLangSel.value;
});
startBtn.addEventListener('click', () => {
recognition.start();
startBtn.disabled = true;
stopBtn.disabled = false;
recognizedEl.textContent = 'Listening...';
translatedEl.textContent = '';
speakBtn.disabled = true;
});
stopBtn.addEventListener('click', () => {
recognition.stop();
startBtn.disabled = false;
stopBtn.disabled = true;
});
speakBtn.addEventListener('click', () => {
if (!lastTranslated) return;
const utter = new SpeechSynthesisUtterance(lastTranslated);
// choose voice that matches target language (best effort)
const tgt = tgtLangSel.value || 'en';
const voices = speechSynthesis.getVoices();
// try find a voice with matching lang prefix
let chosen = voices.find(v => v.lang && v.lang.startsWith(tgt));
if (chosen) utter.voice = chosen;
utter.lang = tgt;
speechSynthesis.cancel();
speechSynthesis.speak(utter);
});
// Simple translate using LibreTranslate public instance
async function doTranslate(text) {
translatedEl.textContent = 'Translating...';
const src = srcLangSel.value || 'id';
const tgt = tgtLangSel.value || 'en';
try {
// WARNING: Using public demo endpoints may have rate limits & privacy risks.
// For production, put an API key call on your server and use paid translate API.
const res = await fetch('https://libretranslate.com/translate', {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({
q: text,
source: src,
target: tgt,
format: "text"
})
});
if (!res.ok) throw new Error('Translate failed: ' + res.status);
const data = await res.json();
lastTranslated = data.translatedText;
translatedEl.textContent = lastTranslated;
} catch (err) {
console.error(err);
translatedEl.textContent = 'Translate error: ' + err.message;
}
}
</script>
</body>
</html>
Tidak ada komentar:
Posting Komentar