rein0421 commited on
Commit
37782cb
·
verified ·
1 Parent(s): 99daaaf

Upload index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +67 -92
templates/index.html CHANGED
@@ -1,8 +1,8 @@
1
  <!DOCTYPE html>
2
  <html lang="ja">
3
  <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
  <title>Voice Recorder Interface</title>
7
  <style>
8
  body {
@@ -19,14 +19,12 @@
19
  .chart {
20
  width: 300px;
21
  height: 300px;
22
- margin-bottom: 20px; /* 円グラフとボタンの間隔を狭く */
23
- }
24
- .controls {
25
- display: flex;
26
- flex-direction: column;
27
- align-items: center;
28
  }
 
29
  .record-button {
 
 
30
  width: 80px;
31
  height: 80px;
32
  background-color: transparent;
@@ -54,10 +52,13 @@
54
  border-radius: 10%;
55
  }
56
 
57
- .result-button {
58
- margin-left: 10px;
 
 
 
59
 
60
- margin-top: 20px;
61
  padding: 10px 20px;
62
  background-color: #4caf50;
63
  border: none;
@@ -65,10 +66,9 @@
65
  color: white;
66
  cursor: pointer;
67
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
 
68
  }
69
- .result {
70
- display: flex;
71
- }
72
  .result-button:hover {
73
  background-color: #388e3c;
74
  }
@@ -85,12 +85,8 @@
85
  </button>
86
 
87
  <div class="result-buttons">
88
- <button class="result-button" id="historyButton" onclick="showHistory()">
89
- 会話履歴を表示
90
- </button>
91
- <button class="result-button" id="feedbackButton" onclick="showResults()">
92
- フィードバック画面を表示
93
- </button>
94
  </div>
95
 
96
  <script>
@@ -100,45 +96,41 @@
100
  let recordingInterval;
101
 
102
  // Chart.js の初期化
103
- const ctx = document.getElementById("speechChart").getContext("2d");
104
  const speechChart = new Chart(ctx, {
105
- type: "doughnut",
106
  data: {
107
- labels: ["自分", "他の人"],
108
- datasets: [
109
- {
110
- data: [30, 70],
111
- backgroundColor: ["#4caf50", "#757575"],
112
- },
113
- ],
114
  },
115
  options: {
116
  responsive: true,
117
  plugins: {
118
  legend: {
119
  display: true,
120
- position: "bottom",
121
- labels: { color: "white" },
122
- },
123
- },
124
- },
125
  });
126
 
127
  async function toggleRecording() {
128
- const recordButton = document.getElementById("recordButton");
129
 
130
  if (!isRecording) {
131
  // 録音開始
132
  isRecording = true;
133
- recordButton.classList.add("recording");
134
  try {
135
- const stream = await navigator.mediaDevices.getUserMedia({
136
- audio: true,
137
- });
138
  mediaRecorder = new MediaRecorder(stream);
139
  audioChunks = [];
140
 
141
- mediaRecorder.ondataavailable = (event) => {
142
  if (event.data.size > 0) {
143
  audioChunks.push(event.data);
144
  }
@@ -157,14 +149,14 @@
157
  }
158
  }, 10000);
159
  } catch (error) {
160
- console.error("マイクへのアクセスに失敗しました:", error);
161
  isRecording = false;
162
- recordButton.classList.remove("recording");
163
  }
164
  } else {
165
  // 手動停止
166
  isRecording = false;
167
- recordButton.classList.remove("recording");
168
  clearInterval(recordingInterval);
169
  if (mediaRecorder && mediaRecorder.state === "recording") {
170
  mediaRecorder.stop();
@@ -173,58 +165,41 @@
173
  }
174
 
175
  function sendAudioChunks(chunks) {
176
- const audioBlob = new Blob(chunks, { type: "audio/wav" });
177
  const reader = new FileReader();
178
  reader.onloadend = () => {
179
- const base64String = reader.result.split(",")[1]; // Base64エンコードされた音声データ
180
- fetch("/upload_audio", {
181
- method: "POST",
182
  headers: {
183
- "Content-Type": "application/json",
184
  },
185
  body: JSON.stringify({ audio_data: base64String }),
186
  })
187
- .then((response) => response.json())
188
- .then((data) => {
189
- if (data.error) {
190
- alert("エラー: " + data.error);
191
- console.error(data.details);
192
- } else if (data.rate !== undefined) {
193
- // 解析結果が返ってきた場合はチャートを更新
194
- speechChart.data.datasets[0].data = [
195
- data.rate,
196
- 100 - data.rate,
197
- ];
198
- speechChart.update();
199
- alert(
200
- "音声の解析が完了しました。自分の音声: " +
201
- data.rate.toFixed(2) +
202
- "%, 他の人: " +
203
- (100 - data.rate).toFixed(2) +
204
- "%"
205
- );
206
- } else {
207
- alert("音声がバックエンドに送信されました。");
208
- }
209
- // 録音が継続中であれば、再度録音を開始(自動録音の連続処理)
210
- if (
211
- isRecording &&
212
- mediaRecorder &&
213
- mediaRecorder.state === "inactive"
214
- ) {
215
- mediaRecorder.start();
216
- }
217
- })
218
- .catch((error) => {
219
- console.error("エラー:", error);
220
- if (
221
- isRecording &&
222
- mediaRecorder &&
223
- mediaRecorder.state === "inactive"
224
- ) {
225
- mediaRecorder.start();
226
- }
227
- });
228
  };
229
  reader.readAsDataURL(audioBlob);
230
  }
@@ -232,13 +207,13 @@
232
  function showHistory() {
233
  // 会話履歴表示の画面があれば、そのページへ遷移する例
234
  // window.location.href = 'history';
235
- alert("会話履歴を表示する機能は未実装です。");
236
  }
237
 
238
  function showResults() {
239
  // フィードバック画面へ遷移
240
- window.location.href = "feedback";
241
  }
242
  </script>
243
  </body>
244
- </html>
 
1
  <!DOCTYPE html>
2
  <html lang="ja">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Voice Recorder Interface</title>
7
  <style>
8
  body {
 
19
  .chart {
20
  width: 300px;
21
  height: 300px;
22
+ margin-bottom: 50px; /* 円グラフとボタンの間隔を狭く */
 
 
 
 
 
23
  }
24
+
25
  .record-button {
26
+ position: fixed;
27
+ bottom: 30px;
28
  width: 80px;
29
  height: 80px;
30
  background-color: transparent;
 
52
  border-radius: 10%;
53
  }
54
 
55
+ .result-buttons {
56
+ margin-top: 5px; /* ボタン間の距離を少し縮める */
57
+ display: flex;
58
+ gap: 10px;
59
+ }
60
 
61
+ .result-button {
62
  padding: 10px 20px;
63
  background-color: #4caf50;
64
  border: none;
 
66
  color: white;
67
  cursor: pointer;
68
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
69
+ transition: background-color 0.2s ease;
70
  }
71
+
 
 
72
  .result-button:hover {
73
  background-color: #388e3c;
74
  }
 
85
  </button>
86
 
87
  <div class="result-buttons">
88
+ <button class="result-button" id="historyButton" onclick="showHistory()">会話履歴を表示</button>
89
+ <button class="result-button" id="feedbackButton" onclick="showResults()">フィードバック画面を表示</button>
 
 
 
 
90
  </div>
91
 
92
  <script>
 
96
  let recordingInterval;
97
 
98
  // Chart.js の初期化
99
+ const ctx = document.getElementById('speechChart').getContext('2d');
100
  const speechChart = new Chart(ctx, {
101
+ type: 'doughnut',
102
  data: {
103
+ labels: ['自分', '他の人'],
104
+ datasets: [{
105
+ data: [30, 70],
106
+ backgroundColor: ['#4caf50', '#757575'],
107
+ }],
 
 
108
  },
109
  options: {
110
  responsive: true,
111
  plugins: {
112
  legend: {
113
  display: true,
114
+ position: 'bottom',
115
+ labels: { color: 'white' }
116
+ }
117
+ }
118
+ }
119
  });
120
 
121
  async function toggleRecording() {
122
+ const recordButton = document.getElementById('recordButton');
123
 
124
  if (!isRecording) {
125
  // 録音開始
126
  isRecording = true;
127
+ recordButton.classList.add('recording');
128
  try {
129
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
 
 
130
  mediaRecorder = new MediaRecorder(stream);
131
  audioChunks = [];
132
 
133
+ mediaRecorder.ondataavailable = event => {
134
  if (event.data.size > 0) {
135
  audioChunks.push(event.data);
136
  }
 
149
  }
150
  }, 10000);
151
  } catch (error) {
152
+ console.error('マイクへのアクセスに失敗しました:', error);
153
  isRecording = false;
154
+ recordButton.classList.remove('recording');
155
  }
156
  } else {
157
  // 手動停止
158
  isRecording = false;
159
+ recordButton.classList.remove('recording');
160
  clearInterval(recordingInterval);
161
  if (mediaRecorder && mediaRecorder.state === "recording") {
162
  mediaRecorder.stop();
 
165
  }
166
 
167
  function sendAudioChunks(chunks) {
168
+ const audioBlob = new Blob(chunks, { type: 'audio/wav' });
169
  const reader = new FileReader();
170
  reader.onloadend = () => {
171
+ const base64String = reader.result.split(',')[1]; // Base64エンコードされた音声データ
172
+ fetch('/upload_audio', {
173
+ method: 'POST',
174
  headers: {
175
+ 'Content-Type': 'application/json',
176
  },
177
  body: JSON.stringify({ audio_data: base64String }),
178
  })
179
+ .then(response => response.json())
180
+ .then(data => {
181
+ if (data.error) {
182
+ alert('エラー: ' + data.error);
183
+ console.error(data.details);
184
+ } else if (data.rate !== undefined) {
185
+ // 解析結果が返ってきた場合はチャートを更新
186
+ speechChart.data.datasets[0].data = [data.rate, 100 - data.rate];
187
+ speechChart.update();
188
+ //lert('音声の解析が完了しました。自分の音声: ' + data.rate.toFixed(2) + '%, 他の人: ' + (100 - data.rate).toFixed(2) + '%');
189
+ } else {
190
+ alert('音声がバックエンドに送信されました。');
191
+ }
192
+ // 録音が継続中であれば、再度録音を開始(自動録音の連続処理)
193
+ if (isRecording && mediaRecorder && mediaRecorder.state === "inactive") {
194
+ mediaRecorder.start();
195
+ }
196
+ })
197
+ .catch(error => {
198
+ console.error('エラー:', error);
199
+ if (isRecording && mediaRecorder && mediaRecorder.state === "inactive") {
200
+ mediaRecorder.start();
201
+ }
202
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  };
204
  reader.readAsDataURL(audioBlob);
205
  }
 
207
  function showHistory() {
208
  // 会話履歴表示の画面があれば、そのページへ遷移する例
209
  // window.location.href = 'history';
210
+ alert('会話履歴を表示する機能は未実装です。');
211
  }
212
 
213
  function showResults() {
214
  // フィードバック画面へ遷移
215
+ window.location.href = 'feedback';
216
  }
217
  </script>
218
  </body>
219
+ </html>