punab3 commited on
Commit
facfaff
·
verified ·
1 Parent(s): d07e3ff

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +179 -19
index.html CHANGED
@@ -1,19 +1,179 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="id">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AI Pose Recognition - Suara</title>
7
+ <style>
8
+ body {
9
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10
+ display: flex;
11
+ flex-direction: column;
12
+ align-items: center;
13
+ background-color: #f0f2f5;
14
+ padding: 20px;
15
+ }
16
+ h2 { color: #333; }
17
+ #canvas {
18
+ border: 4px solid #fff;
19
+ border-radius: 10px;
20
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
21
+ background-color: #000;
22
+ }
23
+ #label-container {
24
+ margin-top: 20px;
25
+ width: 100%;
26
+ max-width: 300px;
27
+ }
28
+ #label-container div {
29
+ background: #fff;
30
+ padding: 10px;
31
+ margin-bottom: 5px;
32
+ border-radius: 5px;
33
+ font-weight: bold;
34
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
35
+ display: flex;
36
+ justify-content: space-between;
37
+ }
38
+ button {
39
+ padding: 12px 24px;
40
+ font-size: 18px;
41
+ background-color: #007bff;
42
+ color: white;
43
+ border: none;
44
+ border-radius: 5px;
45
+ cursor: pointer;
46
+ margin-bottom: 20px;
47
+ transition: background 0.3s;
48
+ }
49
+ button:hover { background-color: #0056b3; }
50
+ </style>
51
+ </head>
52
+ <body>
53
+
54
+ <h2>Deteksi Pose & Suara</h2>
55
+ <button type="button" onclick="init()">Mulai Kamera</button>
56
+
57
+ <div><canvas id="canvas"></canvas></div>
58
+ <div id="label-container"></div>
59
+
60
+ <!-- Elemen Audio (Pastikan nama file sesuai) -->
61
+ <audio id="audio-kicaw" src="kicaw_mania.mp3"></audio>
62
+ <audio id="audio-semangat" src="semangat.mp3"></audio>
63
+ <audio id="audio-berjuang" src="berjuang.mp3"></audio>
64
+ <audio id="audio-sukses" src="sukses.mp3"></audio>
65
+
66
+ <!-- Load TensorFlow.js dan Teachable Machine Pose Library -->
67
+ <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js"></script>
68
+ <script src="https://cdn.jsdelivr.net/npm/@teachablemachine/pose@0.8/dist/teachablemachine-pose.min.js"></script>
69
+
70
+ <script type="text/javascript">
71
+ // Link model kamu (Ganti jika menggunakan URL cloud dari Teachable Machine)
72
+ const URL = "./my_model/";
73
+ let model, webcam, ctx, labelContainer, maxPredictions;
74
+
75
+ // Variabel untuk mengontrol suara agar tidak spamming
76
+ let lastPlayedClass = "";
77
+
78
+ async function init() {
79
+ const modelURL = URL + "model.json";
80
+ const metadataURL = URL + "metadata.json";
81
+
82
+ // Load model dan metadata
83
+ model = await tmPose.load(modelURL, metadataURL);
84
+ maxPredictions = model.getTotalClasses();
85
+
86
+ // Setup webcam
87
+ const size = 400; // Ukuran diperbesar agar lebih jelas
88
+ const flip = true;
89
+ webcam = new tmPose.Webcam(size, size, flip);
90
+ await webcam.setup();
91
+ await webcam.play();
92
+ window.requestAnimationFrame(loop);
93
+
94
+ // Setup Canvas dan Label
95
+ const canvas = document.getElementById("canvas");
96
+ canvas.width = size; canvas.height = size;
97
+ ctx = canvas.getContext("2d");
98
+ labelContainer = document.getElementById("label-container");
99
+ labelContainer.innerHTML = ""; // Bersihkan kontainer
100
+ for (let i = 0; i < maxPredictions; i++) {
101
+ labelContainer.appendChild(document.createElement("div"));
102
+ }
103
+ }
104
+
105
+ async function loop(timestamp) {
106
+ webcam.update();
107
+ await predict();
108
+ window.requestAnimationFrame(loop);
109
+ }
110
+
111
+ async function predict() {
112
+ // Prediksi Pose
113
+ const { pose, posenetOutput } = await model.estimatePose(webcam.canvas);
114
+ const prediction = await model.predict(posenetOutput);
115
+
116
+ let highestProb = 0;
117
+ let currentClass = "";
118
+
119
+ for (let i = 0; i < maxPredictions; i++) {
120
+ const prob = prediction[i].probability.toFixed(2);
121
+ const className = prediction[i].className;
122
+
123
+ labelContainer.childNodes[i].innerHTML = `<span>${className}</span> <span>${(prob * 100).toFixed(0)}%</span>`;
124
+
125
+ // Cari class dengan probabilitas tertinggi
126
+ if (prediction[i].probability > highestProb) {
127
+ highestProb = prediction[i].probability;
128
+ currentClass = className;
129
+ }
130
+ }
131
+
132
+ // LOGIKA SUARA:
133
+ // Hanya putar jika probabilitas > 85% dan bukan pose yang sama berturut-turut
134
+ if (highestProb > 0.85 && currentClass !== lastPlayedClass) {
135
+ playSound(currentClass);
136
+ lastPlayedClass = currentClass;
137
+ }
138
+
139
+ drawPose(pose);
140
+ }
141
+
142
+ function playSound(className) {
143
+ // Hentikan suara lain yang sedang berjalan
144
+ const audios = document.querySelectorAll('audio');
145
+ audios.forEach(a => {
146
+ a.pause();
147
+ a.currentTime = 0;
148
+ });
149
+
150
+ // Mapping Class ke ID Audio (Sesuaikan dengan nama class di Teachable Machine kamu)
151
+ let id = "";
152
+ if (className === "kicaw kicaw mania") id = "audio-kicaw";
153
+ else if (className === "semangat") id = "audio-semangat";
154
+ else if (className === "berjuang") id = "audio-berjuang";
155
+ else if (className === "sukses") id = "audio-sukses";
156
+
157
+ if (id) {
158
+ const playPromise = document.getElementById(id).play();
159
+ if (playPromise !== undefined) {
160
+ playPromise.catch(error => {
161
+ console.log("Autoplay dicegah oleh browser, butuh interaksi user.");
162
+ });
163
+ }
164
+ }
165
+ }
166
+
167
+ function drawPose(pose) {
168
+ if (webcam.canvas) {
169
+ ctx.drawImage(webcam.canvas, 0, 0);
170
+ if (pose) {
171
+ const minPartConfidence = 0.5;
172
+ tmPose.drawKeypoints(pose.keypoints, minPartConfidence, ctx);
173
+ tmPose.drawSkeleton(pose.keypoints, minPartConfidence, ctx);
174
+ }
175
+ }
176
+ }
177
+ </script>
178
+ </body>
179
+ </html>