posee / index.html
punab3's picture
Update index.html
ad6f487 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 with Audio</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
text-align: center;
background-color: #1a1a1a;
color: white;
padding: 20px;
}
h2 { color: #00d4ff; }
#canvas-container {
position: relative;
display: inline-block;
border: 5px solid #333;
border-radius: 15px;
overflow: hidden;
background: #000;
}
#label-container {
margin-top: 20px;
display: flex;
justify-content: center;
gap: 15px;
}
#label-container div {
background: #333;
padding: 10px 20px;
border-radius: 8px;
font-size: 18px;
min-width: 120px;
}
button {
padding: 15px 35px;
font-size: 18px;
font-weight: bold;
cursor: pointer;
background: linear-gradient(45deg, #00d4ff, #0056b3);
color: white;
border: none;
border-radius: 50px;
transition: 0.3s;
margin-bottom: 20px;
box-shadow: 0 4px 15px rgba(0, 212, 255, 0.3);
}
button:hover {
transform: scale(1.05);
box-shadow: 0 6px 20px rgba(0, 212, 255, 0.5);
}
.active-pose {
border: 2px solid #00d4ff !important;
background: #0056b3 !important;
}
</style>
</head>
<body>
<h2>AI Pose Detector: Peace, Mantap, Metal</h2>
<p>Pastikan kamera aktif dan tekan tombol di bawah:</p>
<button type="button" onclick="init()">MULAI KAMERA</button>
<div id="status"></div>
<div id="canvas-container">
<canvas id="canvas"></canvas>
</div>
<div id="label-container"></div>
<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 dari Teachable Machine kamu
const URL = "https://teachablemachine.withgoogle.com/models/0Y2ifsgF4/";
let model, webcam, ctx, labelContainer, maxPredictions;
// Persiapan Audio
const sounds = {
"peace": new Audio("mp3peace.mp3"),
"mantap": new Audio("mp3mantap.mp3"),
"metal": new Audio("mp3metal.mp3")
};
let lastPlayedPose = ""; // Mencegah suara terulang terus menerus
let silenceTimer; // Timer untuk meriset status suara
async function init() {
const modelURL = URL + "model.json";
const metadataURL = URL + "metadata.json";
// Load model
model = await tmPose.load(modelURL, metadataURL);
maxPredictions = model.getTotalClasses();
// Setup Webcam
const size = 400;
const flip = true;
webcam = new tmPose.Webcam(size, size, flip);
await webcam.setup();
await webcam.play();
window.requestAnimationFrame(loop);
// Setup UI
const canvas = document.getElementById("canvas");
canvas.width = size; canvas.height = size;
ctx = canvas.getContext("2d");
labelContainer = document.getElementById("label-container");
labelContainer.innerHTML = ""; // Bersihkan container
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() {
const { pose, posenetOutput } = await model.estimatePose(webcam.canvas);
const prediction = await model.predict(posenetOutput);
for (let i = 0; i < maxPredictions; i++) {
const className = prediction[i].className; // Nama class asli: peace, mantap, metal
const probability = prediction[i].probability;
const element = labelContainer.childNodes[i];
element.innerHTML = `${className}: ${(probability * 100).toFixed(0)}%`;
// Logika Suara dan Highlight UI
if (probability > 0.90) { // Ambang batas 90% yakin
element.classList.add("active-pose");
// Mainkan suara jika pose berubah
if (lastPlayedPose !== className) {
playAudio(className);
}
} else {
element.classList.remove("active-pose");
}
}
drawPose(pose);
}
function playAudio(poseName) {
const soundKey = poseName.toLowerCase();
if (sounds[soundKey]) {
// Stop suara lain yang sedang main (opsional)
Object.values(sounds).forEach(s => {
s.pause();
s.currentTime = 0;
});
// Putar suara baru
sounds[soundKey].play().catch(e => console.log("Izin audio diperlukan"));
lastPlayedPose = poseName;
// Reset 'lastPlayedPose' setelah 3 detik diam agar bisa bunyi lagi
clearTimeout(silenceTimer);
silenceTimer = setTimeout(() => {
lastPlayedPose = "";
}, 3000);
}
}
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>