TNOT commited on
Commit
00a56c1
·
1 Parent(s): 2221103

fix: 完善云端UI日志,以便追踪错误;添加更多文本

Browse files
Files changed (1) hide show
  1. src/gui_cloud.py +75 -6
src/gui_cloud.py CHANGED
@@ -27,6 +27,46 @@ logging.basicConfig(
27
  )
28
  logger = logging.getLogger(__name__)
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  # 项目根目录
31
  BASE_DIR = Path(__file__).parent.parent.absolute()
32
 
@@ -75,19 +115,23 @@ def cleanup_workspace(workspace: str):
75
  def create_zip(source_dir: str, zip_name: str) -> Optional[str]:
76
  """打包目录为 zip(使用 uuid 避免多用户冲突)"""
77
  if not os.path.isdir(source_dir):
 
78
  return None
79
  try:
80
  unique_id = str(uuid.uuid4())[:8]
81
  zip_path = os.path.join(CloudConfig.TEMP_BASE, f"{zip_name}_{unique_id}.zip")
82
  with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
 
83
  for root, dirs, files in os.walk(source_dir):
84
  for file in files:
85
  file_path = os.path.join(root, file)
86
  arcname = os.path.relpath(file_path, source_dir)
87
  zf.write(file_path, arcname)
 
 
88
  return zip_path
89
  except Exception as e:
90
- logger.error(f"打包失败: {e}")
91
  return None
92
 
93
 
@@ -147,6 +191,7 @@ def validate_audio_upload(files) -> Tuple[bool, str, List[str]]:
147
  return True, f"找到 {len(valid_files)} 个音频文件", valid_files
148
 
149
 
 
150
  def process_make_voicebank(
151
  audio_files,
152
  source_name: str,
@@ -159,13 +204,20 @@ def process_make_voicebank(
159
 
160
  返回: (状态, 日志, 下载文件路径, 会话存储的音源包路径)
161
  """
162
- from src.pipeline import PipelineConfig, VoiceBankPipeline
163
-
164
  logs = []
 
 
165
  def log(msg):
166
  logs.append(msg)
167
  logger.info(msg)
168
 
 
 
 
 
 
 
 
169
  # 验证输入
170
  if not source_name or not source_name.strip():
171
  return "❌ 请输入音源名称", "", None, None
@@ -191,10 +243,23 @@ def process_make_voicebank(
191
 
192
  # 复制音频文件到输入目录
193
  progress(0.05, desc="复制音频文件...")
 
194
  for src_path in file_paths:
195
- dst_path = os.path.join(input_dir, os.path.basename(src_path))
196
- shutil.copy2(src_path, dst_path)
197
- log(f"📋复制 {len(file_paths)} 个文件到工作目录")
 
 
 
 
 
 
 
 
 
 
 
 
198
 
199
  # 获取 MFA 模型路径
200
  mfa_models = scan_mfa_models()
@@ -374,6 +439,7 @@ def validate_voicebank_zip(zip_file) -> Tuple[bool, str, Optional[str]]:
374
  return validate_voicebank_zip_path(zip_path)
375
 
376
 
 
377
  def process_export_voicebank(
378
  zip_file,
379
  plugin_name: str,
@@ -736,6 +802,7 @@ def create_cloud_ui():
736
  with gr.Tab("🎵 制作音源"):
737
  gr.Markdown("### 上传音频文件")
738
  gr.Markdown("支持格式: WAV, MP3, FLAC, OGG, M4A")
 
739
 
740
  audio_upload = gr.File(
741
  label="上传音频文件",
@@ -776,6 +843,8 @@ def create_cloud_ui():
776
 
777
  gr.Markdown("""
778
  > ⏱️ **模型速度参考**:small 约 4 秒/句,medium 约 12 秒/句(medium 慢 2-3 倍但更准确)
 
 
779
  """)
780
 
781
  make_btn = gr.Button("🚀 开始制作", variant="primary", size="lg", interactive=False)
 
27
  )
28
  logger = logging.getLogger(__name__)
29
 
30
+
31
+ def safe_gradio_handler(func):
32
+ """
33
+ Gradio 处理函数的安全包装器
34
+
35
+ 捕获所有异常并返回友好的错误信息,避免 Gradio 显示默认的"错误"状态
36
+ """
37
+ import functools
38
+ import traceback
39
+
40
+ @functools.wraps(func)
41
+ def wrapper(*args, **kwargs):
42
+ try:
43
+ return func(*args, **kwargs)
44
+ except Exception as e:
45
+ # 记录完整的异常堆栈
46
+ error_trace = traceback.format_exc()
47
+ logger.error(f"处理函数 {func.__name__} 发生异常:\n{error_trace}")
48
+
49
+ # 根据函数返回值数量返回错误信息
50
+ # 检查函数的类型注解来确定返回值数量
51
+ annotations = getattr(func, '__annotations__', {})
52
+ return_type = annotations.get('return', None)
53
+
54
+ error_msg = f"❌ 系统错误: {str(e)}"
55
+ error_detail = f"异常类型: {type(e).__name__}\n详情: {str(e)}"
56
+
57
+ # 根据函数名判断返回值数量
58
+ if func.__name__ == 'process_make_voicebank':
59
+ return error_msg, error_detail, None, None
60
+ elif func.__name__ == 'process_export_voicebank':
61
+ return error_msg, error_detail, None
62
+ elif func.__name__ == 'collect_and_export':
63
+ return error_msg, error_detail, None
64
+ else:
65
+ # 默认返回单个错误消息
66
+ return error_msg
67
+
68
+ return wrapper
69
+
70
  # 项目根目录
71
  BASE_DIR = Path(__file__).parent.parent.absolute()
72
 
 
115
  def create_zip(source_dir: str, zip_name: str) -> Optional[str]:
116
  """打包目录为 zip(使用 uuid 避免多用户冲突)"""
117
  if not os.path.isdir(source_dir):
118
+ logger.warning(f"打包失败: 目录不存在 {source_dir}")
119
  return None
120
  try:
121
  unique_id = str(uuid.uuid4())[:8]
122
  zip_path = os.path.join(CloudConfig.TEMP_BASE, f"{zip_name}_{unique_id}.zip")
123
  with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
124
+ file_count = 0
125
  for root, dirs, files in os.walk(source_dir):
126
  for file in files:
127
  file_path = os.path.join(root, file)
128
  arcname = os.path.relpath(file_path, source_dir)
129
  zf.write(file_path, arcname)
130
+ file_count += 1
131
+ logger.info(f"打包完成: {zip_path} ({file_count} 个文件)")
132
  return zip_path
133
  except Exception as e:
134
+ logger.error(f"打包失败: {e}", exc_info=True)
135
  return None
136
 
137
 
 
191
  return True, f"找到 {len(valid_files)} 个音频文件", valid_files
192
 
193
 
194
+ @safe_gradio_handler
195
  def process_make_voicebank(
196
  audio_files,
197
  source_name: str,
 
204
 
205
  返回: (状态, 日志, 下载文件路径, 会话存储的音源包路径)
206
  """
 
 
207
  logs = []
208
+ workspace = None
209
+
210
  def log(msg):
211
  logs.append(msg)
212
  logger.info(msg)
213
 
214
+ try:
215
+ # 导入依赖(放在 try 块内以捕获导入错误)
216
+ from src.pipeline import PipelineConfig, VoiceBankPipeline
217
+ except Exception as e:
218
+ logger.error(f"导入模块失败: {e}", exc_info=True)
219
+ return f"❌ 系统错误: 模块加载失败", str(e), None, None
220
+
221
  # 验证输入
222
  if not source_name or not source_name.strip():
223
  return "❌ 请输入音源名称", "", None, None
 
243
 
244
  # 复制音频文件到输入目录
245
  progress(0.05, desc="复制音频文件...")
246
+ copied_count = 0
247
  for src_path in file_paths:
248
+ # 检查源文件是否存在
249
+ if not os.path.exists(src_path):
250
+ log(f"⚠️ 文件不存在或被清理: {src_path}")
251
+ continue
252
+ try:
253
+ dst_path = os.path.join(input_dir, os.path.basename(src_path))
254
+ shutil.copy2(src_path, dst_path)
255
+ copied_count += 1
256
+ except Exception as e:
257
+ log(f"⚠️ 复制文件失败 {os.path.basename(src_path)}: {e}")
258
+
259
+ if copied_count == 0:
260
+ return "❌ 无法访问上传的文件,请重新上传", "\n".join(logs), None, None
261
+
262
+ log(f"📋 已复制 {copied_count}/{len(file_paths)} 个文件到工作目录")
263
 
264
  # 获取 MFA 模型路径
265
  mfa_models = scan_mfa_models()
 
439
  return validate_voicebank_zip_path(zip_path)
440
 
441
 
442
+ @safe_gradio_handler
443
  def process_export_voicebank(
444
  zip_file,
445
  plugin_name: str,
 
802
  with gr.Tab("🎵 制作音源"):
803
  gr.Markdown("### 上传音频文件")
804
  gr.Markdown("支持格式: WAV, MP3, FLAC, OGG, M4A")
805
+ gr.Markdown("允许同时拖拽多个文件上传,也可点击上传框的右上角追加文件")
806
 
807
  audio_upload = gr.File(
808
  label="上传音频文件",
 
843
 
844
  gr.Markdown("""
845
  > ⏱️ **模型速度参考**:small 约 4 秒/句,medium 约 12 秒/句(medium 慢 2-3 倍但更准确)
846
+ >
847
+ > <span style="color: red;">**small完全够用的,medium费时还容易炸空间,除非实在识别不出来字再用**</span>
848
  """)
849
 
850
  make_btn = gr.Button("🚀 开始制作", variant="primary", size="lg", interactive=False)