DeepLearning101 commited on
Commit
c6c5dd9
·
verified ·
1 Parent(s): dad0fd1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -28
app.py CHANGED
@@ -2,56 +2,95 @@ import gradio as gr
2
  import torch
3
  import os
4
  import soundfile as sf
5
- import numpy as np
6
  import librosa
7
- import warnings
8
  import tempfile
 
 
9
  from DPTNet_eval.DPTNet_quant_sep import load_dpt_model, dpt_sep_process
10
 
11
- # 過濾警告訊息
12
- warnings.filterwarnings("ignore", category=UserWarning)
13
- warnings.filterwarnings("ignore", category=FutureWarning)
14
-
15
- # 加載模型(全局變量)
16
- model = load_dpt_model()
 
 
 
 
 
 
 
 
 
 
17
 
18
  def separate_audio(input_wav):
19
- """處理音訊分離的主要函數"""
 
 
 
20
  try:
21
- # 步驟 1:讀取音訊並標準化格式
 
 
 
 
 
 
 
 
 
22
  data, sr = librosa.load(input_wav, sr=None, mono=True)
23
 
24
- # 步驟 2:強制重採樣到 16kHz
25
  if sr != 16000:
 
26
  data = librosa.resample(data, orig_sr=sr, target_sr=16000)
27
  sr = 16000
28
-
29
- # 步驟 3:生成唯一臨時檔案
30
  with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp_file:
31
  temp_wav = tmp_file.name
 
32
  sf.write(temp_wav, data, sr, subtype='PCM_16')
33
 
34
- # 步驟 4:執行語音分離
35
- outfilename = "output.wav"
 
 
 
36
  dpt_sep_process(temp_wav, model=model, outfilename=outfilename)
37
 
38
- # 步驟 5:清理臨時檔案
39
- os.remove(temp_wav)
40
-
41
- # 步驟 6:驗證輸出檔案存在
42
  output_files = [
43
  outfilename.replace('.wav', '_sep1.wav'),
44
  outfilename.replace('.wav', '_sep2.wav')
45
  ]
 
 
 
46
  if not all(os.path.exists(f) for f in output_files):
47
- raise gr.Error("分離過程中發生錯誤,請檢查輸入檔案格式!")
 
48
 
 
49
  return output_files
50
 
51
  except Exception as e:
52
- # 錯誤處理
53
- error_msg = f"處理失敗:{str(e)}"
54
- raise gr.Error(error_msg) from e
 
 
 
 
 
 
 
 
 
55
 
56
  # 🎯 你提供的 description 內容(已轉為 HTML)
57
  description_html = """
@@ -97,13 +136,13 @@ description_html = """
97
  """
98
 
99
  if __name__ == "__main__":
100
- # 配置 Gradio 介面
101
  interface = gr.Interface(
102
  fn=separate_audio,
103
  inputs=gr.Audio(
104
  type="filepath",
105
- label="請上傳混音音檔 (支援格式:mp3/wav/ogg)",
106
- max_length=300 # 限制 5 分鐘長度
107
  ),
108
  outputs=[
109
  gr.Audio(label="語音軌道 1"),
@@ -118,10 +157,13 @@ if __name__ == "__main__":
118
  ]
119
  )
120
 
121
- # 啟動服務
122
  interface.launch(
123
  server_name="0.0.0.0",
124
  server_port=7860,
125
  share=False,
126
- debug=False
 
 
 
127
  )
 
2
  import torch
3
  import os
4
  import soundfile as sf
 
5
  import librosa
6
+ import logging
7
  import tempfile
8
+ import traceback
9
+ from datetime import datetime
10
  from DPTNet_eval.DPTNet_quant_sep import load_dpt_model, dpt_sep_process
11
 
12
+ # 配置日志系统
13
+ logging.basicConfig(
14
+ filename='app.log',
15
+ level=logging.INFO,
16
+ format='%(asctime)s - %(levelname)s - %(message)s'
17
+ )
18
+ logger = logging.getLogger(__name__)
19
+
20
+ # 全局模型加载(避免重复加载)
21
+ try:
22
+ logger.info("開始加載語音分離模型...")
23
+ model = load_dpt_model()
24
+ logger.info("模型加載成功")
25
+ except Exception as e:
26
+ logger.error(f"模型加載失敗: {str(e)}")
27
+ raise RuntimeError("模型初始化失敗") from e
28
 
29
  def separate_audio(input_wav):
30
+ """處理音訊分離的主函數"""
31
+ process_id = datetime.now().strftime("%Y%m%d%H%M%S%f")
32
+ temp_wav = None
33
+
34
  try:
35
+ logger.info(f"[{process_id}] 開始處理檔案: {input_wav}")
36
+
37
+ # 1. 驗證輸入檔案
38
+ if not os.path.exists(input_wav):
39
+ raise gr.Error("檔案不存在,請重新上傳")
40
+ if os.path.getsize(input_wav) > 50 * 1024 * 1024: # 50MB限制
41
+ raise gr.Error("檔案大小超過50MB限制")
42
+
43
+ # 2. 讀取並標準化音訊
44
+ logger.info(f"[{process_id}] 讀取音訊檔案...")
45
  data, sr = librosa.load(input_wav, sr=None, mono=True)
46
 
47
+ # 3. 重採樣處理
48
  if sr != 16000:
49
+ logger.info(f"[{process_id}] 重採樣從 {sr}Hz 到 16000Hz...")
50
  data = librosa.resample(data, orig_sr=sr, target_sr=16000)
51
  sr = 16000
52
+
53
+ # 4. 創建臨時檔案
54
  with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp_file:
55
  temp_wav = tmp_file.name
56
+ logger.info(f"[{process_id}] 寫入臨時檔案: {temp_wav}")
57
  sf.write(temp_wav, data, sr, subtype='PCM_16')
58
 
59
+ # 5. 執行語音分離
60
+ logger.info(f"[{process_id}] 開始語音分離...")
61
+ out_dir = tempfile.mkdtemp() # 使用臨時目錄存放輸出
62
+ outfilename = os.path.join(out_dir, "output.wav")
63
+
64
  dpt_sep_process(temp_wav, model=model, outfilename=outfilename)
65
 
66
+ # 6. 獲取輸出檔案
 
 
 
67
  output_files = [
68
  outfilename.replace('.wav', '_sep1.wav'),
69
  outfilename.replace('.wav', '_sep2.wav')
70
  ]
71
+ logger.info(f"[{process_id}] 預期輸出檔案: {output_files}")
72
+
73
+ # 7. 驗證輸出
74
  if not all(os.path.exists(f) for f in output_files):
75
+ missing = [f for f in output_files if not os.path.exists(f)]
76
+ raise gr.Error(f"分離失敗,缺失檔案: {missing}")
77
 
78
+ logger.info(f"[{process_id}] 處理完成")
79
  return output_files
80
 
81
  except Exception as e:
82
+ error_msg = f"[{process_id}] 處理錯誤: {str(e)}\n{traceback.format_exc()}"
83
+ logger.error(error_msg)
84
+ raise gr.Error(f"處理失敗: {str(e)}") from e
85
+
86
+ finally:
87
+ # 清理臨時檔案
88
+ if temp_wav and os.path.exists(temp_wav):
89
+ try:
90
+ os.remove(temp_wav)
91
+ logger.info(f"[{process_id}] 已清理臨時檔案")
92
+ except Exception as clean_err:
93
+ logger.warning(f"[{process_id}] 清理失敗: {str(clean_err)}")
94
 
95
  # 🎯 你提供的 description 內容(已轉為 HTML)
96
  description_html = """
 
136
  """
137
 
138
  if __name__ == "__main__":
139
+ # 配置Gradio接口
140
  interface = gr.Interface(
141
  fn=separate_audio,
142
  inputs=gr.Audio(
143
  type="filepath",
144
+ label="請上傳混音音檔 (支援格式: mp3/wav/ogg)",
145
+ max_length=180 # 3分鐘限制
146
  ),
147
  outputs=[
148
  gr.Audio(label="語音軌道 1"),
 
157
  ]
158
  )
159
 
160
+ # 啟動服務(重要參數調整)
161
  interface.launch(
162
  server_name="0.0.0.0",
163
  server_port=7860,
164
  share=False,
165
+ debug=False,
166
+ max_threads=2, # 限制並行處理數
167
+ enable_queue=True, # 啟用隊列系統
168
+ auth=("user", "pass") if os.getenv("HF_SPACE") else None # 生產環境加權限
169
  )