File size: 4,799 Bytes
5a619f5
 
 
 
 
35c4a77
5a619f5
35c4a77
 
2fc6e32
35c4a77
 
 
5a619f5
 
 
 
35c4a77
2fc6e32
35c4a77
5a619f5
 
 
 
 
 
 
 
6732e34
5a619f5
 
2fc6e32
5a619f5
2fc6e32
 
 
 
 
5a619f5
 
 
 
 
35c4a77
2fc6e32
6732e34
 
2fc6e32
6732e34
 
2fc6e32
6732e34
 
 
2fc6e32
6732e34
5a619f5
2fc6e32
 
 
 
6732e34
35c4a77
6732e34
 
 
 
2fc6e32
6732e34
5a619f5
 
 
2fc6e32
5a619f5
 
 
 
 
 
 
 
 
 
 
2fc6e32
 
5a619f5
2fc6e32
5a619f5
 
 
 
 
 
 
 
2fc6e32
 
 
5a619f5
 
 
 
 
 
 
2fc6e32
 
5a619f5
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<!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>