Download index.html from punab3/pyut: direct link, hf CLI and curl.
- Browser
- Download file 4.8 kB
-
https://huggingface.co/spaces/punab3/pyut/resolve/main/index.html
- Command line
-
hf download hf://spaces/punab3/pyut/index.html
-
curl -L -o index.html https://huggingface.co/spaces/punab3/pyut/resolve/main/index.html
4.8 kB
| <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> |