Spaces:
Sleeping
Sleeping
File size: 5,598 Bytes
afde5c9 9616027 afde5c9 9616027 afde5c9 9616027 afde5c9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mini-Omni HTML Demo</title>
<style>
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
#recordButton { width: 100px; height: 100px; border-radius: 50%; background-color: #f0f0f0; border: none; cursor: pointer; }
#recordButton:active { background-color: #ff4444; }
#chatHistory { height: 300px; overflow-y: scroll; border: 1px solid #ccc; padding: 10px; margin-bottom: 20px; }
.message { margin-bottom: 10px; }
.user { color: blue; }
.ai { color: green; }
</style>
</head>
<body>
<h1>Mini-Omni Chat Demo</h1>
<div id="chatHistory"></div>
<button id="recordButton">Hold to Speak</button>
<audio id="audioPlayback" controls style="display:none;"></audio>
<script>
const API_URL = '/chat';
const recordButton = document.getElementById('recordButton');
const chatHistory = document.getElementById('chatHistory');
const audioPlayback = document.getElementById('audioPlayback');
let mediaRecorder;
let audioChunks = [];
recordButton.addEventListener('mousedown', startRecording);
recordButton.addEventListener('mouseup', stopRecording);
recordButton.addEventListener('mouseleave', stopRecording);
async function startRecording() {
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = event => {
audioChunks.push(event.data);
};
mediaRecorder.start();
updateChatHistory('User', 'Recording...');
} catch (error) {
console.error('Error accessing microphone:', error);
alert('Error accessing microphone. Please ensure you have given permission.');
}
}
function stopRecording() {
if (mediaRecorder && mediaRecorder.state === 'recording') {
mediaRecorder.stop();
mediaRecorder.onstop = async () => {
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
audioChunks = [];
updateChatHistory('User', URL.createObjectURL(audioBlob));
await sendAudioToAPI(audioBlob);
};
}
}
async function sendAudioToAPI(audioBlob) {
try {
const reader = new FileReader();
reader.readAsDataURL(audioBlob);
reader.onloadend = async function() {
const base64Audio = reader.result.split(',')[1];
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ audio: base64Audio })
});
if (response.ok) {
const reader = response.body.getReader();
const stream = new ReadableStream({
async start(controller) {
while (true) {
const { done, value } = await reader.read();
if (done) break;
controller.enqueue(value);
}
controller.close();
}
});
const responseBlob = await new Response(stream).blob();
const audioUrl = URL.createObjectURL(responseBlob);
updateChatHistory('AI', audioUrl);
// Play the audio response
const audio = new Audio(audioUrl);
audio.play();
} else {
console.error('API response not ok:', response.status);
updateChatHistory('AI', 'Error in API response');
}
};
} catch (error) {
console.error('Error sending audio to API:', error);
if (error.name === 'TypeError' && error.message === 'Failed to fetch') {
updateChatHistory('AI', 'Error: Unable to connect to the server. Please ensure the server is running and accessible.');
} else {
updateChatHistory('AI', 'Error communicating with the server: ' + error.message);
}
}
}
function updateChatHistory(speaker, content) {
const messageElement = document.createElement('div');
messageElement.className = 'message ' + (speaker === 'User' ? 'user' : 'ai');
if (content.startsWith('blob:') || content.startsWith('data:')) {
messageElement.innerHTML = `<strong>${speaker}:</strong> <audio src="${content}" controls></audio>`;
} else {
messageElement.innerHTML = `<strong>${speaker}:</strong> ${content}`;
}
chatHistory.appendChild(messageElement);
chatHistory.scrollTop = chatHistory.scrollHeight;
}
</script>
</body>
</html>
|