test11 / index.html
joermd's picture
Update index.html
36480a4 verified
raw
history blame
8.24 kB
<!DOCTYPE html>
<html dir="rtl" lang="ar">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>محادثة صوتية</title>
<style>
/* ... Previous CSS styles ... */
.wave-container {
position: fixed;
bottom: 100px;
width: 100%;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
opacity: 0;
transition: opacity 0.3s ease;
}
.wave-container.active {
opacity: 1;
}
.wave {
width: 8px;
height: 40px;
background: #ffffff;
border-radius: 4px;
animation: wave 1s ease-in-out infinite;
}
.wave:nth-child(2) { animation-delay: 0.1s; }
.wave:nth-child(3) { animation-delay: 0.2s; }
.wave:nth-child(4) { animation-delay: 0.3s; }
.wave:nth-child(5) { animation-delay: 0.4s; }
@keyframes wave {
0%, 100% { transform: scaleY(0.3); }
50% { transform: scaleY(1); }
}
</style>
</head>
<body>
<div class="container">
<button class="toggle-code-button" id="toggleCode">عرض النص</button>
<div class="record-button-container">
<button class="record-button" id="recordButton">
<div class="inner-circle"></div>
</button>
</div>
<div class="status-text" id="statusText">انقر للبدء في التسجيل</div>
<!-- إضافة حاوية الموجات الصوتية -->
<div class="wave-container" id="waveContainer">
<div class="wave"></div>
<div class="wave"></div>
<div class="wave"></div>
<div class="wave"></div>
<div class="wave"></div>
</div>
<div class="code-section" id="codeSection">
<div class="message-container">
<div class="message-label">ما قلته:</div>
<div class="message-content" id="spokenText"></div>
</div>
<div class="message-container">
<div class="message-label">رد النموذج:</div>
<div class="message-content" id="modelResponse"></div>
</div>
<div class="voice-settings">
<select id="voiceSelect">
<option value="">اختر صوت رجل عربي فصحى</option>
</select>
</div>
</div>
</div>
<script>
const API_URL = 'https://8o1mzdgh9f40t4-7777.proxy.runpod.net/proxy/8000/chat';
const recordButton = document.getElementById('recordButton');
const statusText = document.getElementById('statusText');
const spokenText = document.getElementById('spokenText');
const modelResponse = document.getElementById('modelResponse');
const voiceSelect = document.getElementById('voiceSelect');
const toggleCodeButton = document.getElementById('toggleCode');
const codeSection = document.getElementById('codeSection');
const waveContainer = document.getElementById('waveContainer');
let isRecording = false;
toggleCodeButton.onclick = () => {
codeSection.classList.toggle('visible');
toggleCodeButton.textContent = codeSection.classList.contains('visible') ? 'إخفاء النص' : 'عرض النص';
};
const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
recognition.lang = 'ar-SA';
recognition.continuous = false;
recognition.interimResults = false;
function loadVoices() {
const voices = speechSynthesis.getVoices();
voiceSelect.innerHTML = '<option value="">اختر صوت رجل عربي فصحى</option>';
// تحسين اختيار الأصوات العربية للرجال
voices.forEach((voice, index) => {
if (voice.lang.includes('ar') && (voice.name.includes('Male') || voice.name.includes('رجل'))) {
const option = document.createElement('option');
option.value = index;
option.textContent = voice.name;
if (voice.default) {
option.selected = true;
}
voiceSelect.appendChild(option);
}
});
// إذا لم يتم العثور على أصوات عربية، اختر أول صوت رجل متاح
if (voiceSelect.options.length === 1) {
voices.forEach((voice, index) => {
if (voice.name.includes('Male')) {
const option = document.createElement('option');
option.value = index;
option.textContent = voice.name;
voiceSelect.appendChild(option);
}
});
}
}
speechSynthesis.onvoiceschanged = loadVoices;
loadVoices();
recognition.onresult = async (event) => {
const text = event.results[0][0].transcript;
spokenText.textContent = text;
try {
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ message: text })
});
const data = await response.json();
const botReply = data.response;
modelResponse.textContent = botReply;
const utterance = new SpeechSynthesisUtterance(botReply);
const voices = speechSynthesis.getVoices();
const selectedVoice = voices[voiceSelect.value || 0];
utterance.voice = selectedVoice;
utterance.lang = 'ar-SA';
utterance.rate = 1;
utterance.pitch = 1;
// إظهار الموجات الصوتية عند بدء الكلام
waveContainer.classList.add('active');
utterance.onend = () => {
// إخفاء الموجات الصوتية عند انتهاء الكلام
waveContainer.classList.remove('active');
};
speechSynthesis.speak(utterance);
} catch (error) {
modelResponse.textContent = 'حدث خطأ في الاتصال بالنموذج';
statusText.textContent = 'حدث خطأ في الاتصال';
}
};
recognition.onerror = (event) => {
console.error('خطأ:', event.error);
statusText.textContent = 'حدث خطأ في التعرف على الكلام';
isRecording = false;
recordButton.classList.remove('recording');
};
recognition.onend = () => {
isRecording = false;
recordButton.classList.remove('recording');
statusText.textContent = 'انقر للبدء في التسجيل';
};
recordButton.onclick = () => {
if (!isRecording) {
recognition.start();
isRecording = true;
recordButton.classList.add('recording');
statusText.textContent = 'جارٍ التسجيل... انقر للإيقاف';
spokenText.textContent = '';
modelResponse.textContent = '';
waveContainer.classList.remove('active');
} else {
recognition.stop();
isRecording = false;
recordButton.classList.remove('recording');
statusText.textContent = 'جارٍ معالجة الكلام...';
}
};
</script>
</body>
</html>