pyut / index.html
punab3's picture
Update index.html
2fc6e32 verified
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pose Recognition AI</title>
<style>
body { font-family: sans-serif; text-align: center; background: #f0f2f5; padding: 20px; }
#canvas { border: 5px solid #007bff; border-radius: 10px; background: #000; max-width: 100%; height: auto; }
button { padding: 15px 30px; font-size: 18px; font-weight: bold; cursor: pointer; background: #28a745; color: white; border: none; border-radius: 50px; margin: 10px; }
#label-container { margin-top: 20px; display: flex; flex-direction: column; align-items: center; }
#label-container div { background: white; margin: 5px; padding: 10px; width: 280px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-weight: bold; }
#status { color: #555; margin-bottom: 10px; font-style: italic; }
</style>
</head>
<body>
<h2>AI Pengenalan Pose + Suara</h2>
<div id="status">Harap upload file model.json, metadata.json, dan weights.bin</div>
<button type="button" onclick="init()">MULAI KAMERA</button>
<div><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">
const URL = "./";
let model, webcam, ctx, labelContainer, maxPredictions;
// Nama file disesuaikan dengan gambar daftar file kamu
const audioFiles = {
"semangat": new Audio('selamat.mp3'), // Kamu upload 'selamat.mp3', sesuaikan class-nya
"berjuang": new Audio('berjuang.mp3'),
"sukses": new Audio('sukses.mp3'),
"hidup jokowi": new Audio('hidup jokowi.mp3'),
"mp3kicaukicaw": new Audio('kicawkicaw.mp3')
};
let lastPlayedClass = "";
async function init() {
const statusDiv = document.getElementById("status");
statusDiv.innerHTML = "Memuat model...";
try {
model = await tmPose.load(URL + "model.json", URL + "metadata.json");
maxPredictions = model.getTotalClasses();
webcam = new tmPose.Webcam(400, 400, true);
await webcam.setup();
await webcam.play();
statusDiv.innerHTML = "Kamera Aktif!";
window.requestAnimationFrame(loop);
ctx = document.getElementById("canvas").getContext("2d");
document.getElementById("canvas").width = 400;
document.getElementById("canvas").height = 400;
labelContainer = document.getElementById("label-container");
labelContainer.innerHTML = "";
for (let i = 0; i < maxPredictions; i++) {
labelContainer.appendChild(document.createElement("div"));
}
} catch (e) {
statusDiv.innerHTML = "Error: File model tidak ditemukan atau kamera ditolak!";
console.error(e);
}
}
async function loop() {
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;
const prob = prediction[i].probability;
labelContainer.childNodes[i].innerHTML = className + ": " + (prob * 100).toFixed(0) + "%";
if (prob > 0.90 && lastPlayedClass !== className) {
playVoice(className);
lastPlayedClass = className;
}
}
drawPose(pose);
}
function playVoice(className) {
Object.values(audioFiles).forEach(a => { a.pause(); a.currentTime = 0; });
if (audioFiles[className]) {
audioFiles[className].play().catch(e => console.log("Audio diblokir browser"));
}
}
function drawPose(pose) {
if (webcam.canvas) {
ctx.drawImage(webcam.canvas, 0, 0);
if (pose) {
tmPose.drawKeypoints(pose.keypoints, 0.5, ctx);
tmPose.drawSkeleton(pose.keypoints, 0.5, ctx);
}
}
}
</script>
</body>
</html>