mizzzuno commited on
Commit
62b7d8e
·
verified ·
1 Parent(s): a922c60

Update static/process.js

Browse files
Files changed (1) hide show
  1. static/process.js +222 -255
static/process.js CHANGED
@@ -1,255 +1,222 @@
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 = 5000; // 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
-
 
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 = 5000; // 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
+ // ページ読み込み時にチャート情報を更新
81
+ updateChartFrom();
82
+ // 録音ボタンの録音開始/停止処理
83
+ async function toggleRecording() {
84
+ const recordButton = document.getElementById("recordButton");
85
+ if (!isRecording) {
86
+ // 録音開始
87
+ isRecording = true;
88
+ recordButton.classList.add("recording");
89
+ try {
90
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
91
+ mediaRecorder = new MediaRecorder(stream);
92
+ audioChunks = [];
93
+ mediaRecorder.ondataavailable = (event) => {
94
+ if (event.data.size > 0) {
95
+ audioChunks.push(event.data);
96
+ }
97
+ };
98
+ mediaRecorder.onstop = () => {
99
+ sendAudioChunks([...audioChunks]);
100
+ audioChunks = [];
101
+ };
102
+ mediaRecorder.start();
103
+ // 5秒ごとに録音を停止して送信するインターバルを設定
104
+ recordingInterval = setInterval(() => {
105
+ if (mediaRecorder && mediaRecorder.state === "recording") {
106
+ mediaRecorder.stop();
107
+ mediaRecorder.start();
108
+ }
109
+ }, RECORDING_INTERVAL_MS);
110
+ } catch (error) {
111
+ console.error("マイクへのアクセスに失敗しました:", error);
112
+ isRecording = false;
113
+ recordButton.classList.remove("recording");
114
+ }
115
+ } else {
116
+ // 録音停止
117
+ isRecording = false;
118
+ recordButton.classList.remove("recording");
119
+ if (mediaRecorder && mediaRecorder.state === "recording") {
120
+ mediaRecorder.stop();
121
+ }
122
+ clearInterval(recordingInterval);
123
+ count_voice = 0;
124
+ //before_rate = [];
125
+ }
126
+ }
127
+ function sendAudioChunks(chunks) {
128
+ const audioBlob = new Blob(chunks, { type: "audio/wav" });
129
+ const reader = new FileReader();
130
+ reader.onloadend = () => {
131
+ const base64String = reader.result.split(",")[1];
132
+ const form = document.getElementById("recordForm");
133
+ const nameInput = form.querySelector('input[name="name"]');
134
+ const name = nameInput ? nameInput.value : "unknown";
135
+ fetch("/upload_audio", {
136
+ method: "POST",
137
+ headers: { "Content-Type": "application/json" },
138
+ body: JSON.stringify({ audio_data: base64String, name: name }),
139
+ })
140
+ .then((response) => response.json())
141
+ .then((data) => {
142
+ if (data.error) {
143
+ alert("エラー: " + data.error);
144
+ console.error(data.details);
145
+ } else if (data.rate !== undefined) {
146
+ updateChartData(data.rate);
147
+ } else if (data.rates !== undefined) {
148
+ updateChartData(data.rates);
149
+ }
150
+ })
151
+ .catch((error) => {
152
+ console.error("エラー:", error);
153
+ });
154
+ };
155
+ reader.readAsDataURL(audioBlob);
156
+ }
157
+ function getMemberColors(memberCount) {
158
+ // 一人モードの場合は特別な処理をしない(updateChartで処理するため)
159
+ if (memberCount <= 1) {
160
+ return ["#4caf50", "#757575"];
161
+ } else {
162
+ let colors = [];
163
+ for (let i = 0; i < memberCount; i++) {
164
+ colors.push(baseMemberColors[i % baseMemberColors.length]);
165
+ }
166
+ return colors;
167
+ }
168
+ }
169
+ function updateChartData(newRate) {
170
+ // 一人モードの時の処理
171
+ if (members.length === 1) {
172
+ if (count_voice === 0) {
173
+ speechChart.data.datasets[0].data = [newRate, 100 - newRate];
174
+ before_rate = [newRate];
175
+ } else {
176
+ // 一人モードでは、過去のデータと現在のデータを加重平均する
177
+ let tmp_rate = (newRate + before_rate[0] * count_voice) / (count_voice + 1);
178
+ speechChart.data.datasets[0].data = [tmp_rate, 100 - tmp_rate];
179
+ before_rate = [tmp_rate];
180
+ }
181
+ count_voice++;
182
+ // 一人モードでは常に緑色とグレーの組み合わせを使用
183
+ speechChart.data.labels = [members[0], "無音"];
184
+ speechChart.data.datasets[0].backgroundColor = ["#4caf50", "#757575"];
185
+ } else {
186
+ console.log(before_rate)
187
+ // 複数人モードの処理
188
+ if (!Array.isArray(newRate)) {
189
+ console.error("newRate is not an array:", newRate);
190
+ return;
191
+ }
192
+ if (newRate.length !== members.length) {
193
+ console.error(
194
+ "newRate length does not match members length:",
195
+ newRate,
196
+ members
197
+ );
198
+ return;
199
+ }
200
+ let averagedRates = new Array(newRate.length);
201
+ for (let i = 0; i < newRate.length; i++) {
202
+ let tmp_rate;
203
+ if (count_voice === 0) {
204
+ // 初回はそのまま
205
+ tmp_rate = newRate[i];
206
+ } else {
207
+ // 2回目以降は、過去の平均値と現在の値を加重平均する
208
+ tmp_rate = (newRate[i] + before_rate[i] * count_voice) / (count_voice + 1);
209
+ }
210
+ averagedRates[i] = tmp_rate;
211
+ }
212
+ // before_rateを更新
213
+ before_rate = averagedRates;
214
+ //グラフに反映
215
+ speechChart.data.datasets[0].data = averagedRates;
216
+ count_voice++;
217
+ speechChart.data.datasets[0].backgroundColor = getMemberColors(
218
+ members.length
219
+ );
220
+ }
221
+ speechChart.update();
222
+ }