A-yum1 commited on
Commit
7c2137d
·
1 Parent(s): a49984b

Update process.py

Browse files
Files changed (1) hide show
  1. static/process.js +248 -258
static/process.js CHANGED
@@ -1,265 +1,255 @@
1
- let isRecording = false;
2
- let mediaRecorder;
3
- let audioChunks = [];
4
- let recordingInterval;
5
- let count_voice = 0;
6
- let before_rate = [];
7
- const RECORDING_INTERVAL_MS = 5000; // 5秒
8
- // メンバーとチャートの初期化
9
- let members = [];
10
- let voiceData = [];
11
- let baseMemberColors = [
12
- "#4caf50",
13
- "#007bff",
14
- "#ffc107",
15
- "#dc3545",
16
- "#28a745",
17
- "#9c27b0",
18
- "#ff9800",
19
- ];
20
- // Chart.js の初期化
21
- const ctx = document.getElementById("speechChart").getContext("2d");
22
- const speechChart = new Chart(ctx, {
23
- type: "doughnut",
24
- data: {
25
- labels: members,
26
- datasets: [
27
- {
28
- data: voiceData,
29
- backgroundColor: getMemberColors(members.length),
30
- },
31
- ],
32
- },
33
- options: {
34
- responsive: true,
35
- plugins: {
36
- legend: {
37
- display: true,
38
- position: "bottom",
39
- labels: { color: "white" },
40
- },
41
- },
42
- },
43
- });
44
- // サーバーからメンバー情報を取得してチャートを更新する関数
45
- async function updateChartFrom() {
46
- try {
47
- const response = await fetch("/confirm");
48
- if (!response.ok) {
49
- throw new Error(`HTTP error! status: ${response.status}`);
50
- }
51
- const data = await response.json();
52
- if (!data || !data.members || !Array.isArray(data.members)) {
53
- console.error("Invalid member data received:", data);
54
- members = ["member1"];
55
- voiceData = [50, 50];
56
- updateChart();
57
- return;
58
- }
59
- members = data.members;
60
- voiceData = [];
61
- for (let i = 0; i < members.length; i++) {
62
- voiceData.push(100 / members.length);
63
- }
64
- updateChart();
65
- } catch (error) {
66
- console.error("Failed to fetch member data:", error);
67
- members = ["member1"];
68
- voiceData = [50, 50];
69
- updateChart();
70
- }
71
- }
72
- function updateChart() {
73
- // 一人モードの場合は、ユーザーとグレー(無音)の比率をチャートに表示
74
- if (members.length === 1) {
75
- const userName = members[0];
76
- speechChart.data.labels = [userName, "無音"];
77
- speechChart.data.datasets[0].backgroundColor = ["#4caf50", "#757575"];
78
- } else {
79
- // 複数メンバーの場合は通常通りの処理
80
- speechChart.data.labels = members;
81
- speechChart.data.datasets[0].backgroundColor = getMemberColors(
82
- members.length
83
- );
84
- }
85
- speechChart.data.datasets[0].data = voiceData;
86
- speechChart.update();
87
- }
88
- // メニューの表示・非表示
89
- function toggleMenu(event) {
90
- event.stopPropagation();
91
- const menu = document.getElementById("menu");
92
- menu.classList.toggle("open");
93
- }
94
 
95
- function closeMenu(event) {
96
- const menu = document.getElementById("menu");
97
- if (
98
- menu.classList.contains("open") &&
99
- !menu.contains(event.target) &&
100
- !event.target.closest("#menuButton")
101
- ) {
102
- menu.classList.remove("open");
103
- }
104
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
- // リセットボタンの処理
107
- function resetAction() {
108
- window.location.href = "reset_html";
109
- }
 
 
 
 
 
 
110
 
111
- // ページ読み込み時にチャート情報を更新
112
- updateChartFrom();
113
- // 録音ボタンの録音開始/停止処理
114
- async function toggleRecording() {
115
- const recordButton = document.getElementById("recordButton");
116
- if (!isRecording) {
117
- // 録音開始
118
- isRecording = true;
119
- recordButton.classList.add("recording");
120
- try {
121
- const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
122
- mediaRecorder = new MediaRecorder(stream);
123
- audioChunks = [];
124
- mediaRecorder.ondataavailable = (event) => {
125
- if (event.data.size > 0) {
126
- audioChunks.push(event.data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  }
128
- };
129
- mediaRecorder.onstop = () => {
130
- sendAudioChunks([...audioChunks]);
131
- audioChunks = [];
132
- };
133
- mediaRecorder.start();
134
- // 5秒ごとに録音を停止して送信するインターバルを設定
135
- recordingInterval = setInterval(() => {
136
- if (mediaRecorder && mediaRecorder.state === "recording") {
137
- mediaRecorder.stop();
138
- mediaRecorder.start();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
- }, RECORDING_INTERVAL_MS);
141
- } catch (error) {
142
- console.error("マイクへのアクセスに失敗しました:", error);
143
- isRecording = false;
144
- recordButton.classList.remove("recording");
145
- }
146
- } else {
147
- // 録音停止
148
- isRecording = false;
149
- recordButton.classList.remove("recording");
150
- if (mediaRecorder && mediaRecorder.state === "recording") {
151
- mediaRecorder.stop();
152
- }
153
- clearInterval(recordingInterval);
154
- count_voice = 0;
155
- //before_rate = [];
156
- }
157
- }
158
- function sendAudioChunks(chunks) {
159
- const audioBlob = new Blob(chunks, { type: "audio/wav" });
160
- const reader = new FileReader();
161
- reader.onloadend = () => {
162
- const base64String = reader.result.split(",")[1];
163
- const form = document.getElementById("recordForm");
164
- const nameInput = form.querySelector('input[name="name"]');
165
- const name = nameInput ? nameInput.value : "unknown";
166
- fetch("/upload_audio", {
167
- method: "POST",
168
- headers: { "Content-Type": "application/json" },
169
- body: JSON.stringify({ audio_data: base64String, name: name }),
170
- })
171
- .then((response) => response.json())
172
- .then((data) => {
173
- if (data.error) {
174
- alert("エラー: " + data.error);
175
- console.error(data.details);
176
- } else if (data.rate !== undefined) {
177
- updateChartData(data.rate);
178
- } else if (data.rates !== undefined) {
179
- updateChartData(data.rates);
 
 
 
 
 
 
 
 
 
 
 
 
180
  }
181
- })
182
- .catch((error) => {
183
- console.error("エラー:", error);
184
- });
185
- };
186
- reader.readAsDataURL(audioBlob);
187
- }
188
- function getMemberColors(memberCount) {
189
- // 一人モードの場合は特別な処理をしない(updateChartで処理するため)
190
- if (memberCount <= 1) {
191
- return ["#4caf50", "#757575"];
192
- } else {
193
- let colors = [];
194
- for (let i = 0; i < memberCount; i++) {
195
- colors.push(baseMemberColors[i % baseMemberColors.length]);
196
- }
197
- return colors;
198
- }
199
- }
200
- function updateChartData(newRate) {
201
- // 一人モードの時の処理
202
- if (members.length === 1) {
203
- if (count_voice === 0) {
204
- speechChart.data.datasets[0].data = [newRate, 100 - newRate];
205
- before_rate = [newRate];
206
- } else {
207
- // 一人モードでは、過去のデータと現在のデータを加重平均する
208
- let tmp_rate =
209
- (newRate + before_rate[0] * count_voice) / (count_voice + 1);
210
- speechChart.data.datasets[0].data = [tmp_rate, 100 - tmp_rate];
211
- before_rate = [tmp_rate];
212
- }
213
- count_voice++;
214
- // 一人モードでは常に緑色とグレーの組み合わせを使用
215
- speechChart.data.labels = [members[0], "無音"];
216
- speechChart.data.datasets[0].backgroundColor = ["#4caf50", "#757575"];
217
- } else {
218
- console.log(before_rate);
219
- // 複数人モードの処理
220
- if (!Array.isArray(newRate)) {
221
- console.error("newRate is not an array:", newRate);
222
- return;
223
- }
224
- if (newRate.length !== members.length) {
225
- console.error(
226
- "newRate length does not match members length:",
227
- newRate,
228
- members
229
- );
230
- return;
231
- }
232
- let averagedRates = new Array(newRate.length);
233
- for (let i = 0; i < newRate.length; i++) {
234
- let tmp_rate;
235
- if (count_voice === 0) {
236
- // 初回はそのまま
237
- tmp_rate = newRate[i];
238
- } else {
239
- // 2回目以降は、過去の平均値と現在の値を加重平均する
240
- tmp_rate =
241
- (newRate[i] + before_rate[i] * count_voice) / (count_voice + 1);
242
  }
243
- averagedRates[i] = tmp_rate;
244
- }
245
- // before_rateを更新
246
- before_rate = averagedRates;
247
- //グラフに反映
248
- speechChart.data.datasets[0].data = averagedRates;
249
- count_voice++;
250
- speechChart.data.datasets[0].backgroundColor = getMemberColors(
251
- members.length
252
- );
253
- }
254
- speechChart.update();
255
- }
256
- function showTalkdetail() {
257
- window.location.href = "talk_detail";
258
- }
259
- function showResults() {
260
- window.location.href = "feedback";
261
- }
262
- function showUserRegister() {
263
- fetch("/reset");
264
- window.location.href = "userregister";
265
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
+ let isRecording = false;
3
+ let mediaRecorder;
4
+ let audioChunks = [];
5
+ let recordingInterval;
6
+ let count_voice = 0;
7
+ let before_rate = [];
8
+ const RECORDING_INTERVAL_MS = 1000; // 5秒
9
+ // メンバーとチャートの初期化
10
+ let members = [];
11
+ let voiceData = [];
12
+ let baseMemberColors = ["#4caf50", "#007bff", "#ffc107", "#dc3545", "#28a745", "#9c27b0", "#ff9800"];
13
+ // Chart.js の初期化
14
+ const ctx = document.getElementById("speechChart").getContext("2d");
15
+ const speechChart = new Chart(ctx, {
16
+ type: "doughnut",
17
+ data: {
18
+ labels: members,
19
+ datasets: [
20
+ {
21
+ data: voiceData,
22
+ backgroundColor: getMemberColors(members.length),
23
+ },
24
+ ],
25
+ },
26
+ options: {
27
+ responsive: true,
28
+ plugins: {
29
+ legend: {
30
+ display: true,
31
+ position: "bottom",
32
+ labels: { color: "white" },
33
+ },
34
+ },
35
+ },
36
+ });
37
+ // サーバーからメンバー情報を取得してチャートを更新する関数
38
+ async function updateChartFrom() {
39
+ try {
40
+ const response = await fetch("/confirm");
41
+ if (!response.ok) {
42
+ throw new Error(`HTTP error! status: ${response.status}`);
43
+ }
44
+ const data = await response.json();
45
+ if (!data || !data.members || !Array.isArray(data.members)) {
46
+ console.error("Invalid member data received:", data);
47
+ members = ["member1"];
48
+ voiceData = [50, 50];
49
+ updateChart();
50
+ return;
51
+ }
52
+ members = data.members;
53
+ voiceData = [];
54
+ for (let i = 0; i < members.length; i++) {
55
+ voiceData.push(100 / members.length);
56
+ }
57
+ updateChart();
58
+ } catch (error) {
59
+ console.error("Failed to fetch member data:", error);
60
+ members = ["member1"];
61
+ voiceData = [50, 50];
62
+ updateChart();
63
+ }
64
+ }
65
+ function updateChart() {
66
+ // 一人モードの場合は、ユーザーとグレー(無音)の比率をチャートに表示
67
+ if (members.length === 1) {
68
+ const userName = members[0];
69
+ speechChart.data.labels = [userName, "無音"];
70
+ speechChart.data.datasets[0].backgroundColor = ["#4caf50", "#757575"];
71
+ } else {
72
+ // 複数メンバーの場合は通常通りの処理
73
+ speechChart.data.labels = members;
74
+ speechChart.data.datasets[0].backgroundColor = getMemberColors(members.length);
75
+ }
76
+ speechChart.data.datasets[0].data = voiceData;
77
+ speechChart.update();
78
+ }
79
+ // メニューの表示・非表示
80
+ function toggleMenu(event) {
81
+ event.stopPropagation();
82
+ const menu = document.getElementById("menu");
83
+ menu.classList.toggle("open");
84
+ }
85
 
86
+ function closeMenu(event) {
87
+ const menu = document.getElementById("menu");
88
+ if (
89
+ menu.classList.contains("open") &&
90
+ !menu.contains(event.target) &&
91
+ !event.target.closest("#menuButton")
92
+ ) {
93
+ menu.classList.remove("open");
94
+ }
95
+ }
96
 
97
+ // リセットボタンの処理
98
+ function resetAction() {
99
+ window.location.href = "reset_html";
100
+ }
101
+
102
+ // ページ読み込み時にチャート情報を更新
103
+ updateChartFrom();
104
+ // 録音ボタンの録音開始/停止処理
105
+ async function toggleRecording() {
106
+ const recordButton = document.getElementById("recordButton");
107
+ if (!isRecording) {
108
+ // 録音開始
109
+ isRecording = true;
110
+ recordButton.classList.add("recording");
111
+ try {
112
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
113
+ mediaRecorder = new MediaRecorder(stream);
114
+ audioChunks = [];
115
+ mediaRecorder.ondataavailable = (event) => {
116
+ if (event.data.size > 0) {
117
+ audioChunks.push(event.data);
118
+ }
119
+ };
120
+ mediaRecorder.onstop = () => {
121
+ sendAudioChunks([...audioChunks]);
122
+ audioChunks = [];
123
+ };
124
+ mediaRecorder.start();
125
+ // 5秒ごとに録音を停止して送信するインターバルを設定
126
+ recordingInterval = setInterval(() => {
127
+ if (mediaRecorder && mediaRecorder.state === "recording") {
128
+ mediaRecorder.stop();
129
+ mediaRecorder.start();
130
+ }
131
+ }, RECORDING_INTERVAL_MS);
132
+ } catch (error) {
133
+ console.error("マイクへのアクセスに失敗しました:", error);
134
+ isRecording = false;
135
+ recordButton.classList.remove("recording");
136
+ }
137
+ } else {
138
+ // 録音停止
139
+ isRecording = false;
140
+ recordButton.classList.remove("recording");
141
+ if (mediaRecorder && mediaRecorder.state === "recording") {
142
+ mediaRecorder.stop();
143
+ }
144
+ clearInterval(recordingInterval);
145
+ count_voice = 0;
146
+ //before_rate = [];
147
  }
148
+ }
149
+ function sendAudioChunks(chunks) {
150
+ const audioBlob = new Blob(chunks, { type: "audio/wav" });
151
+ const reader = new FileReader();
152
+ reader.onloadend = () => {
153
+ const base64String = reader.result.split(",")[1];
154
+ const form = document.getElementById("recordForm");
155
+ const nameInput = form.querySelector('input[name="name"]');
156
+ const name = nameInput ? nameInput.value : "unknown";
157
+ fetch("/upload_audio", {
158
+ method: "POST",
159
+ headers: { "Content-Type": "application/json" },
160
+ body: JSON.stringify({ audio_data: base64String, name: name }),
161
+ })
162
+ .then((response) => response.json())
163
+ .then((data) => {
164
+ if (data.error) {
165
+ alert("エラー: " + data.error);
166
+ console.error(data.details);
167
+ } else if (data.rate !== undefined) {
168
+ updateChartData(data.rate);
169
+ } else if (data.rates !== undefined) {
170
+ updateChartData(data.rates);
171
+ }
172
+ })
173
+ .catch((error) => {
174
+ console.error("エラー:", error);
175
+ });
176
+ };
177
+ reader.readAsDataURL(audioBlob);
178
+ }
179
+ function getMemberColors(memberCount) {
180
+ // 一人モードの場合は特別な処理をしない(updateChartで処理するため)
181
+ if (memberCount <= 1) {
182
+ return ["#4caf50", "#757575"];
183
+ } else {
184
+ let colors = [];
185
+ for (let i = 0; i < memberCount; i++) {
186
+ colors.push(baseMemberColors[i % baseMemberColors.length]);
187
+ }
188
+ return colors;
189
  }
190
+ }
191
+ function updateChartData(newRate) {
192
+ // 一人モードの時の処理
193
+ if (members.length === 1) {
194
+ if (count_voice === 0) {
195
+ speechChart.data.datasets[0].data = [newRate, 100 - newRate];
196
+ before_rate = [newRate];
197
+ } else {
198
+ // 一人モードでは、過去のデータと現在のデータを加重平均する
199
+ let tmp_rate = (newRate + before_rate[0] * count_voice) / (count_voice + 1);
200
+ speechChart.data.datasets[0].data = [tmp_rate, 100 - tmp_rate];
201
+ before_rate = [tmp_rate];
202
+ }
203
+ count_voice++;
204
+ // 一人モードでは常に緑色とグレーの組み合わせを使用
205
+ speechChart.data.labels = [members[0], "無音"];
206
+ speechChart.data.datasets[0].backgroundColor = ["#4caf50", "#757575"];
207
+ } else {
208
+ console.log(before_rate)
209
+ // 複数人モードの処理
210
+ if (!Array.isArray(newRate)) {
211
+ console.error("newRate is not an array:", newRate);
212
+ return;
213
+ }
214
+ if (newRate.length !== members.length) {
215
+ console.error(
216
+ "newRate length does not match members length:",
217
+ newRate,
218
+ members
219
+ );
220
+ return;
221
+ }
222
+ let averagedRates = new Array(newRate.length);
223
+ for (let i = 0; i < newRate.length; i++) {
224
+ let tmp_rate;
225
+ if (count_voice === 0) {
226
+ // 初回はそのまま
227
+ tmp_rate = newRate[i];
228
+ } else {
229
+ // 2回目以降は、過去の平均値と現在の値を加重平均する
230
+ tmp_rate = (newRate[i] + before_rate[i] * count_voice) / (count_voice + 1);
231
+ }
232
+ averagedRates[i] = tmp_rate;
233
+ }
234
+ // before_rateを更新
235
+ before_rate = averagedRates;
236
+ //グラフに反映
237
+ speechChart.data.datasets[0].data = averagedRates;
238
+ count_voice++;
239
+ speechChart.data.datasets[0].backgroundColor = getMemberColors(
240
+ members.length
241
+ );
242
  }
243
+ speechChart.update();
244
+ }
245
+ function showTalkdetail() {
246
+ window.location.href = "talk_detail";
247
+ }
248
+ function showResults() {
249
+ window.location.href = "feedback";
250
+ }
251
+ function showUserRegister() {
252
+ fetch("/reset");
253
+ window.location.href = "userregister";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  }
255
+