emoapi / cameraPage.js
PatriciaWening's picture
Upload 4 files
cb28fad verified
const timeInput = document.getElementById('time-input');
const startBtn = document.getElementById('start-btn');
const videoElement = document.getElementById('video');
const statusElement = document.getElementById('status');
const stressLevelElement = document.getElementById('stress-level');
const countdownElement = document.getElementById('countdown');
const showResultBtn = document.getElementById('show-result-btn');
let stream;
let interval;
let countdownInterval;
let totalTime;
let frameCount = 0;
let countdownTime;
let sessionId = Date.now().toString();
async function startCamera() {
try {
stream = await navigator.mediaDevices.getUserMedia({
video: true,
});
videoElement.srcObject = stream;
} catch (err) {
console.error("Error accessing the camera", err);
statusElement.textContent = "Gagal mengakses kamera.";
}
}
function stopCamera() {
if (stream) {
let tracks = stream.getTracks();
tracks.forEach(track => track.stop());
videoElement.srcObject = null;
}
}
async function sendFrameToBackend(dataUrl) {
try {
console.log("Preparing to send frame to backend...");
const formData = new FormData();
formData.append('image', dataUrl);
formData.append('sessionId', sessionId);
console.log("Sending request to backend...");
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000);
const apiResponse = await fetch('https://PatriciaWening-emoapi.hf.space/api/deteksi-emosi', {
method: 'POST',
body: formData,
signal: controller.signal
});
clearTimeout(timeoutId);
if (!apiResponse.ok) {
const errorText = await apiResponse.text();
console.error(`Server returned error ${apiResponse.status}: ${errorText}`);
throw new Error(`HTTP error! Status: ${apiResponse.status}`);
}
const data = await apiResponse.json();
console.log("API response:", data);
if (data.faceDetected) {
drawFaceRectangle(data.faceRegion);
updateStressLevel(data.stressLevel, data.emotion);
statusElement.textContent = `Emosi terdeteksi: ${data.emotion}, Tingkat stres: ${data.stressLevel}%`;
} else {
statusElement.textContent = data.error || "Wajah tidak terdeteksi, mohon cek posisi kamera.";
}
} catch (error) {
console.error('Error sending frame to backend:', error);
statusElement.textContent = "Kesalahan saat memproses data: " + error.message;
}
}
function drawFaceRectangle(region) {
const canvas = document.createElement('canvas');
canvas.width = videoElement.videoWidth;
canvas.height = videoElement.videoHeight;
const context = canvas.getContext('2d');
context.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
context.strokeStyle = '#00FF00';
context.lineWidth = 3;
context.strokeRect(region.x, region.y, region.width, region.height);
const dataURL = canvas.toDataURL('image/png');
const tempImg = document.createElement('img');
tempImg.src = dataURL;
tempImg.style.width = '100%';
tempImg.style.height = 'auto';
tempImg.style.border = '2px solid #ccc';
tempImg.style.borderRadius = '8px';
const videoParent = videoElement.parentNode;
videoParent.insertBefore(tempImg, videoElement);
videoElement.style.display = 'none';
setTimeout(() => {
tempImg.remove();
videoElement.style.display = 'block';
}, 200);
}
function updateStressLevel(stressLevel, emotion) {
stressLevelElement.textContent = `Tingkat Stres: ${stressLevel} (${emotion})`;
if (stressLevel >= 80) {
stressLevelElement.classList.remove('text-green-600', 'text-yellow-600');
stressLevelElement.classList.add('text-red-600');
} else if (stressLevel >= 50) {
stressLevelElement.classList.remove('text-green-600', 'text-red-600');
stressLevelElement.classList.add('text-yellow-600');
} else {
stressLevelElement.classList.remove('text-yellow-600', 'text-red-600');
stressLevelElement.classList.add('text-green-600');
}
localStorage.setItem('currentSessionId', sessionId);
}
async function captureAndAnalyze() {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = videoElement.videoWidth;
canvas.height = videoElement.videoHeight;
context.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
const frame = canvas.toDataURL('image/jpeg');
sendFrameToBackend(frame);
frameCount++;
}
function updateCountdown() {
const minutes = Math.floor(countdownTime / 60);
const seconds = countdownTime % 60;
countdownElement.textContent = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
countdownTime--;
if (countdownTime < 0) {
clearInterval(countdownInterval);
}
}
function startDetection() {
totalTime = parseInt(timeInput.value) * 1000;
if (isNaN(totalTime) || totalTime <= 0) {
statusElement.textContent = "Waktu input tidak valid.";
return;
}
countdownTime = totalTime / 1000;
countdownInterval = setInterval(updateCountdown, 1000);
statusElement.textContent = `Kamera aktif selama ${totalTime / 1000} detik.`;
startCamera();
interval = setInterval(captureAndAnalyze, 1000);
setTimeout(() => {
clearInterval(interval);
stopCamera();
statusElement.textContent = "Proses selesai!";
showResultBtn.classList.remove('hidden');
}, totalTime);
}
startBtn.addEventListener('click', startDetection);