buletomato25 commited on
Commit
a2d1919
·
2 Parent(s): a776d5a 1804233
__pycache__/process.cpython-310.pyc CHANGED
Binary files a/__pycache__/process.cpython-310.pyc and b/__pycache__/process.cpython-310.pyc differ
 
app.py CHANGED
@@ -101,6 +101,7 @@ def analyze():
101
  # 音声アップロード&解析エンドポイント
102
  @app.route('/upload_audio', methods=['POST'])
103
  def upload_audio():
 
104
  try:
105
  data = request.get_json()
106
  # name か users のいずれかが必須。どちらも無い場合はエラー
@@ -129,13 +130,13 @@ def upload_audio():
129
  # 複数人の場合は参照パスのリストを、1人の場合は単一のパスを渡す
130
  if len(users) > 1:
131
  print("複数人の場合の処理")
132
- matched_times = process.process_multi_audio(reference_paths, audio_path, threshold=0.05)
133
  # 各メンバーのrateを計算
134
  total_time = sum(matched_times)
135
  rates = [(time / total_time) * 100 if total_time > 0 else 0 for time in matched_times]
136
  return jsonify({"rates": rates}), 200
137
  else:
138
- matched_time, unmatched_time = process.process_audio(reference_paths[0], audio_path, threshold=0.05)
139
  total_time = matched_time + unmatched_time
140
  rate = (matched_time / total_time) * 100 if total_time > 0 else 0
141
  return jsonify({"rate": rate}), 200
 
101
  # 音声アップロード&解析エンドポイント
102
  @app.route('/upload_audio', methods=['POST'])
103
  def upload_audio():
104
+ global segments_dir
105
  try:
106
  data = request.get_json()
107
  # name か users のいずれかが必須。どちらも無い場合はエラー
 
130
  # 複数人の場合は参照パスのリストを、1人の場合は単一のパスを渡す
131
  if len(users) > 1:
132
  print("複数人の場合の処理")
133
+ matched_times, segments_dir = process.process_multi_audio(reference_paths, audio_path, threshold=0.05)
134
  # 各メンバーのrateを計算
135
  total_time = sum(matched_times)
136
  rates = [(time / total_time) * 100 if total_time > 0 else 0 for time in matched_times]
137
  return jsonify({"rates": rates}), 200
138
  else:
139
+ matched_time, unmatched_time, segments_dir = process.process_audio(reference_paths[0], audio_path, threshold=0.05)
140
  total_time = matched_time + unmatched_time
141
  rate = (matched_time / total_time) * 100 if total_time > 0 else 0
142
  return jsonify({"rate": rate}), 200
process.py CHANGED
@@ -89,7 +89,7 @@ class AudioProcessor():
89
  matched_time_ms += len(AudioSegment.from_file(segment_file))
90
 
91
  unmatched_time_ms = total_duration_ms - matched_time_ms
92
- return matched_time_ms, unmatched_time_ms
93
 
94
 
95
  def process_multi_audio(self, reference_pathes, input_path, output_folder='/tmp/data/matched_multi_segments', seg_duration=1.0, threshold=0.5):
@@ -141,7 +141,7 @@ class AudioProcessor():
141
  if match is not None:
142
  matched_time[match] += seg_duration
143
 
144
- return matched_time
145
 
146
 
147
  def save_audio_from_base64(self,base64_audio,output_dir,output_filename,temp_format='webm'):
 
89
  matched_time_ms += len(AudioSegment.from_file(segment_file))
90
 
91
  unmatched_time_ms = total_duration_ms - matched_time_ms
92
+ return matched_time_ms, unmatched_time_ms,output_folder
93
 
94
 
95
  def process_multi_audio(self, reference_pathes, input_path, output_folder='/tmp/data/matched_multi_segments', seg_duration=1.0, threshold=0.5):
 
141
  if match is not None:
142
  matched_time[match] += seg_duration
143
 
144
+ return matched_time, segmented_path
145
 
146
 
147
  def save_audio_from_base64(self,base64_audio,output_dir,output_filename,temp_format='webm'):
static/process.js CHANGED
@@ -4,7 +4,7 @@ let audioChunks = [];
4
  let recordingInterval;
5
  let count_voice = 0;
6
  let before_rate = [];
7
- const RECORDING_INTERVAL_MS = 1000; // 5秒
8
  // メンバーとチャートの初期化
9
  let members = [];
10
  let voiceData = [];
 
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 = [];
templates/index.html CHANGED
@@ -3,27 +3,165 @@
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
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
8
  <script src="https://cdn.tailwindcss.com"></script>
9
  <link
10
  rel="stylesheet"
11
  href="https://use.fontawesome.com/releases/v5.10.0/css/all.css"
12
  />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  </head>
14
- <body
15
- class="flex items-center justify-center h-screen bg-gray-900 text-white"
16
- onclick="closeMenu(event)"
17
- >
18
- <!-- 全体を囲む枠 -->
19
- <div
20
- class="border-4 border-gray-400 p-8 rounded-lg w-full sm:w-auto relative"
21
- >
22
- <!-- タイトル -->
23
- <div class="text-center text-4xl font-bold mb-5">JustTalk</div>
24
-
25
- <!-- ハンバーガーメニュー -->
26
- <div class="absolute top-4 right-4">
27
  <button
28
  id="menuButton"
29
  class="text-white text-2xl focus:outline-none"
@@ -32,51 +170,36 @@
32
  <i class="fas fa-bars"></i>
33
  </button>
34
 
35
- <!-- メニューの本体 -->
36
  <div
37
  id="menu"
38
- class="absolute top-0 right-0 h-full w-64 bg-gray-800 text-white transform translate-x-full transition-transform duration-300 ease-in-out opacity-0 visibility-hidden"
39
  >
40
  <div class="px-4 py-2 text-lg font-semibold">メニュー</div>
41
- <button
42
- onclick="showUserRegister()"
43
- class="block px-4 py-2 text-sm hover:bg-gray-700"
44
- >
45
- メンバーを追加
46
  </button>
47
- <button
48
- onclick="showResults()"
49
- class="block px-4 py-2 text-sm hover:bg-gray-700"
50
- >
51
- フィードバックを表示
52
  </button>
53
- <button
54
- onclick="showTalkdetail()"
55
- class="block px-4 py-2 text-sm hover:bg-gray-700"
56
- >
57
- 会話詳細を表示
58
  </button>
59
- <button
60
- onclick="resetAction()"
61
- class="block px-4 py-2 text-sm hover:bg-gray-700"
62
- >
63
- リセット
64
  </button>
65
- <button
66
- onclick="toggleMenu(event)"
67
- class="block px-4 py-2 text-sm hover:bg-gray-700"
68
- >
69
- 閉じる
70
  </button>
71
  </div>
72
  </div>
73
 
74
- <!-- チャート表示部 -->
75
- <div class="chart w-72 h-72 mb-5">
76
  <canvas id="speechChart"></canvas>
77
  </div>
78
 
79
- <!-- 録音フォーム -->
80
  <form
81
  id="recordForm"
82
  action="/submit"
@@ -84,7 +207,7 @@
84
  class="flex items-center justify-center space-x-2 w-full sm:w-auto"
85
  onsubmit="event.preventDefault();"
86
  >
87
- <!-- 録音ボタン -->
88
  <button
89
  type="button"
90
  class="record-button"
@@ -96,66 +219,6 @@
96
  </form>
97
  </div>
98
 
99
- <style>
100
- .record-button {
101
- width: 80px;
102
- height: 80px;
103
- background-color: transparent;
104
- border-radius: 50%;
105
- border: 4px solid white;
106
- display: flex;
107
- justify-content: center;
108
- align-items: center;
109
- cursor: pointer;
110
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
111
- transition: all 0.2s ease;
112
- }
113
- .record-icon {
114
- width: 60px;
115
- height: 60px;
116
- background-color: #d32f2f;
117
- border-radius: 50%;
118
- transition: all 0.2s ease;
119
- }
120
- .recording .record-icon {
121
- width: 40px;
122
- height: 40px;
123
- border-radius: 10%;
124
- }
125
- .icon i {
126
- font-size: 20px;
127
- }
128
- /* ハンバーガーメニュー */
129
- #menu {
130
- position: absolute;
131
- top: 0;
132
- right: 0;
133
- z-index: 10;
134
- transform: translateX(100%); /* 初期状態で画面外 */
135
- visibility: hidden; /* 非表示 */
136
- opacity: 0; /* 非表示 */
137
- background-color: rgba(31, 41, 55, 1); /* 不透明な背景色 */
138
- transition: transform 0.3s ease-in-out, visibility 0s 0.3s,
139
- opacity 0.3s ease-in-out; /* スライド後に表示 */
140
- }
141
- #menu.open {
142
- transform: translateX(0); /* メニューが開く */
143
- visibility: visible; /* 表示 */
144
- opacity: 1; /* 完全に表示 */
145
- transition: transform 0.3s ease-in-out, visibility 0s 0s,
146
- opacity 0.3s ease-in-out; /* すぐに表示 */
147
- }
148
- /* レスポンシブデザイン */
149
- @media (max-width: 640px) {
150
- .w-72 {
151
- width: 90%;
152
- }
153
- .h-72 {
154
- height: 300px;
155
- }
156
- }
157
- </style>
158
- <script src="{{ url_for('static', filename='process.js') }}"></script>
159
-
160
  </body>
161
- </html>
 
3
  <head>
4
  <meta charset="UTF-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>JustTalk - Voice Analysis</title>
7
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
8
  <script src="https://cdn.tailwindcss.com"></script>
9
  <link
10
  rel="stylesheet"
11
  href="https://use.fontawesome.com/releases/v5.10.0/css/all.css"
12
  />
13
+ <style>
14
+ /* Custom Chart.js Styles */
15
+ #speechChart {
16
+ background-color: rgba(255, 255, 255, 0.05);
17
+ border-radius: 10px;
18
+ padding: 10px;
19
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
20
+ }
21
+
22
+ /* Record Button Styles */
23
+ .record-button {
24
+ width: 90px;
25
+ height: 90px;
26
+ background-color: transparent;
27
+ border-radius: 50%;
28
+ border: 5px solid white;
29
+ display: flex;
30
+ justify-content: center;
31
+ align-items: center;
32
+ cursor: pointer;
33
+ box-shadow: 0 6px 10px rgba(0, 0, 0, 0.5);
34
+ transition: all 0.2s ease;
35
+ }
36
+
37
+ .record-icon {
38
+ width: 70px;
39
+ height: 70px;
40
+ background-color: #e53e3e;
41
+ border-radius: 50%;
42
+ transition: all 0.2s ease;
43
+ }
44
+
45
+ .recording .record-icon {
46
+ width: 50px;
47
+ height: 50px;
48
+ border-radius: 15%;
49
+ background-color: #c53030;
50
+ }
51
+
52
+ .icon i {
53
+ font-size: 24px;
54
+ }
55
+
56
+ /* Hamburger Menu Styles */
57
+ #menu {
58
+ position: absolute;
59
+ top: 0;
60
+ left: 0;
61
+ z-index: 10;
62
+ transform: translateX(-100%);
63
+ visibility: hidden;
64
+ opacity: 0;
65
+ background-color: rgb(31, 41, 55);
66
+ transition: transform 0.3s ease-in-out, visibility 0s 0.3s,
67
+ opacity 0.3s ease-in-out;
68
+ backdrop-filter: blur(10px);
69
+ border-right: 1px solid rgba(255, 255, 255, 0.2);
70
+ }
71
+
72
+ #menu.open {
73
+ transform: translateX(0);
74
+ visibility: visible;
75
+ opacity: 1;
76
+ transition: transform 0.3s ease-in-out, visibility 0s 0s,
77
+ opacity 0.3s ease-in-out;
78
+ }
79
+
80
+ #menu button {
81
+ transition: background-color 0.2s ease;
82
+ background-color: rgba(0, 0, 0, 0.1); /* 変更点: 透明度を 10% に変更 */
83
+ margin: 2px;
84
+ border-radius: 5px;
85
+ display: flex;
86
+ align-items: center;
87
+ justify-content: flex-start;
88
+ gap: 10px;
89
+ padding: 0.75rem 1rem;
90
+ width: 100%;
91
+ text-align: left;
92
+ border: none;
93
+ color: #fff;
94
+ font-size: 1rem;
95
+ cursor: pointer;
96
+ }
97
+
98
+ #menu button:hover {
99
+ background-color: rgba(55, 65, 81, 0.7);
100
+ }
101
+
102
+ /* Responsive Design */
103
+ @media (max-width: 640px) {
104
+ .w-72 {
105
+ width: 95%;
106
+ }
107
+ .h-72 {
108
+ height: 350px;
109
+ }
110
+ }
111
+ /* Main Container */
112
+ body {
113
+ background: linear-gradient(135deg, #2c3e50, #1f2937);
114
+ display: flex;
115
+ align-items: center;
116
+ justify-content: center;
117
+ min-height: 100vh;
118
+ font-family: 'Arial', sans-serif;
119
+ }
120
+
121
+ /* Main Content Wrapper */
122
+ .main-content {
123
+ border: 5px solid rgba(255, 255, 255, 0.2);
124
+ padding: 2rem;
125
+ border-radius: 1rem;
126
+ width: 90%;
127
+ max-width: 500px;
128
+ background-color: rgba(0, 0, 0, 0.3);
129
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.4);
130
+ text-align: center;
131
+ }
132
+
133
+ /* Title */
134
+ .main-title {
135
+ font-size: 2.5rem;
136
+ font-weight: bold;
137
+ margin-bottom: 1.5rem;
138
+ color: #fff;
139
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
140
+ }
141
+
142
+ /* Hamburger Menu Button */
143
+ #menuButton {
144
+ background-color: rgba(255, 255, 255, 0.1);
145
+ border: none;
146
+ border-radius: 50%;
147
+ padding: 0.5rem;
148
+ cursor: pointer;
149
+ transition: background-color 0.2s ease;
150
+ }
151
+
152
+ #menuButton:hover {
153
+ background-color: rgba(255, 255, 255, 0.2);
154
+ }
155
+ </style>
156
  </head>
157
+ <body onclick="closeMenu(event)">
158
+ <!-- Main Content Wrapper -->
159
+ <div class="main-content relative">
160
+ <!-- Title -->
161
+ <div class="main-title">JustTalk</div>
162
+
163
+ <!-- Hamburger Menu -->
164
+ <div class="absolute top-4 left-4">
 
 
 
 
 
165
  <button
166
  id="menuButton"
167
  class="text-white text-2xl focus:outline-none"
 
170
  <i class="fas fa-bars"></i>
171
  </button>
172
 
173
+ <!-- Menu Content -->
174
  <div
175
  id="menu"
176
+ class="absolute top-0 left-0 h-full w-64 bg-gray-800 text-white transform -translate-x-full transition-transform duration-300 ease-in-out opacity-0 visibility-hidden"
177
  >
178
  <div class="px-4 py-2 text-lg font-semibold">メニュー</div>
179
+ <button onclick="showUserRegister()">
180
+ <i class="fas fa-user-plus"></i> メンバーを追加
 
 
 
181
  </button>
182
+ <button onclick="showResults()">
183
+ <i class="fas fa-chart-bar"></i> フィードバックを表示
 
 
 
184
  </button>
185
+ <button onclick="showTalkdetail()">
186
+ <i class="fas fa-comments"></i> 会話詳細を表示
 
 
 
187
  </button>
188
+ <button onclick="resetAction()">
189
+ <i class="fas fa-redo"></i> リセット
 
 
 
190
  </button>
191
+ <button onclick="toggleMenu(event)">
192
+ <i class="fas fa-times"></i> 閉じる
 
 
 
193
  </button>
194
  </div>
195
  </div>
196
 
197
+ <!-- Chart Display -->
198
+ <div class="chart w-72 h-72 mb-5 mx-auto">
199
  <canvas id="speechChart"></canvas>
200
  </div>
201
 
202
+ <!-- Record Form -->
203
  <form
204
  id="recordForm"
205
  action="/submit"
 
207
  class="flex items-center justify-center space-x-2 w-full sm:w-auto"
208
  onsubmit="event.preventDefault();"
209
  >
210
+ <!-- Record Button -->
211
  <button
212
  type="button"
213
  class="record-button"
 
219
  </form>
220
  </div>
221
 
222
+ <script src="{{ url_for('static', filename='process.js') }}"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  </body>
224
+ </html>