projek / index.html
punab3's picture
Update index.html
facfaff verified
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Pose Recognition - Suara</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
background-color: #f0f2f5;
padding: 20px;
}
h2 { color: #333; }
#canvas {
border: 4px solid #fff;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
background-color: #000;
}
#label-container {
margin-top: 20px;
width: 100%;
max-width: 300px;
}
#label-container div {
background: #fff;
padding: 10px;
margin-bottom: 5px;
border-radius: 5px;
font-weight: bold;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
display: flex;
justify-content: space-between;
}
button {
padding: 12px 24px;
font-size: 18px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
margin-bottom: 20px;
transition: background 0.3s;
}
button:hover { background-color: #0056b3; }
</style>
</head>
<body>
<h2>Deteksi Pose & Suara</h2>
<button type="button" onclick="init()">Mulai Kamera</button>
<div><canvas id="canvas"></canvas></div>
<div id="label-container"></div>
<!-- Elemen Audio (Pastikan nama file sesuai) -->
<audio id="audio-kicaw" src="kicaw_mania.mp3"></audio>
<audio id="audio-semangat" src="semangat.mp3"></audio>
<audio id="audio-berjuang" src="berjuang.mp3"></audio>
<audio id="audio-sukses" src="sukses.mp3"></audio>
<!-- Load TensorFlow.js dan Teachable Machine Pose Library -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@teachablemachine/pose@0.8/dist/teachablemachine-pose.min.js"></script>
<script type="text/javascript">
// Link model kamu (Ganti jika menggunakan URL cloud dari Teachable Machine)
const URL = "./my_model/";
let model, webcam, ctx, labelContainer, maxPredictions;
// Variabel untuk mengontrol suara agar tidak spamming
let lastPlayedClass = "";
async function init() {
const modelURL = URL + "model.json";
const metadataURL = URL + "metadata.json";
// Load model dan metadata
model = await tmPose.load(modelURL, metadataURL);
maxPredictions = model.getTotalClasses();
// Setup webcam
const size = 400; // Ukuran diperbesar agar lebih jelas
const flip = true;
webcam = new tmPose.Webcam(size, size, flip);
await webcam.setup();
await webcam.play();
window.requestAnimationFrame(loop);
// Setup Canvas dan Label
const canvas = document.getElementById("canvas");
canvas.width = size; canvas.height = size;
ctx = canvas.getContext("2d");
labelContainer = document.getElementById("label-container");
labelContainer.innerHTML = ""; // Bersihkan kontainer
for (let i = 0; i < maxPredictions; i++) {
labelContainer.appendChild(document.createElement("div"));
}
}
async function loop(timestamp) {
webcam.update();
await predict();
window.requestAnimationFrame(loop);
}
async function predict() {
// Prediksi Pose
const { pose, posenetOutput } = await model.estimatePose(webcam.canvas);
const prediction = await model.predict(posenetOutput);
let highestProb = 0;
let currentClass = "";
for (let i = 0; i < maxPredictions; i++) {
const prob = prediction[i].probability.toFixed(2);
const className = prediction[i].className;
labelContainer.childNodes[i].innerHTML = `<span>${className}</span> <span>${(prob * 100).toFixed(0)}%</span>`;
// Cari class dengan probabilitas tertinggi
if (prediction[i].probability > highestProb) {
highestProb = prediction[i].probability;
currentClass = className;
}
}
// LOGIKA SUARA:
// Hanya putar jika probabilitas > 85% dan bukan pose yang sama berturut-turut
if (highestProb > 0.85 && currentClass !== lastPlayedClass) {
playSound(currentClass);
lastPlayedClass = currentClass;
}
drawPose(pose);
}
function playSound(className) {
// Hentikan suara lain yang sedang berjalan
const audios = document.querySelectorAll('audio');
audios.forEach(a => {
a.pause();
a.currentTime = 0;
});
// Mapping Class ke ID Audio (Sesuaikan dengan nama class di Teachable Machine kamu)
let id = "";
if (className === "kicaw kicaw mania") id = "audio-kicaw";
else if (className === "semangat") id = "audio-semangat";
else if (className === "berjuang") id = "audio-berjuang";
else if (className === "sukses") id = "audio-sukses";
if (id) {
const playPromise = document.getElementById(id).play();
if (playPromise !== undefined) {
playPromise.catch(error => {
console.log("Autoplay dicegah oleh browser, butuh interaksi user.");
});
}
}
}
function drawPose(pose) {
if (webcam.canvas) {
ctx.drawImage(webcam.canvas, 0, 0);
if (pose) {
const minPartConfidence = 0.5;
tmPose.drawKeypoints(pose.keypoints, minPartConfidence, ctx);
tmPose.drawSkeleton(pose.keypoints, minPartConfidence, ctx);
}
}
}
</script>
</body>
</html>