jjf1999 commited on
Commit
4f6e4e1
·
verified ·
1 Parent(s): 45bc5d0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +15 -14
app.py CHANGED
@@ -6,6 +6,7 @@ import traceback
6
  import numpy as np
7
  import librosa
8
  import soundfile as sf
 
9
  from fastapi import FastAPI, UploadFile, File, Form, HTTPException, Depends, Security
10
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
11
  from fastapi.responses import JSONResponse, PlainTextResponse
@@ -28,13 +29,13 @@ def verify_token(credentials: HTTPAuthorizationCredentials = Security(security))
28
  )
29
  return True
30
 
31
- # 亲昵口语热词配置(保持原样)
32
  CUSTOM_HOTWORDS = os.getenv(
33
  "HOTWORDS",
34
  "爹地 Daddy 妈咪 学长 学姐 欧巴 欧尼 宝贝 亲爱的 哥哥 姐姐 弟弟 妹妹 师傅 老公 老婆 爹咪 小路 小路哥哥 因因 岚岚 甜甜 芝芝瓜 小选 小蛇 宝宝 叶瑄 艾因 路辰 罗夏 司岚 星星嘟嘟 牧首 教宗 虎先生 小叶哥哥"
35
  )
36
 
37
- # 口语错别字规则纠错映射(保持原样)
38
  COLLOQUIAL_CORRECTIONS = {
39
  r"跌地|跌弟|爹底|迭地|嗲地": "爹地",
40
  r"学掌|鞋长|薛长|雪长": "学长",
@@ -79,20 +80,20 @@ emo_model = AutoModel(
79
  disable_update=True
80
  )
81
 
82
- # ================= 3. 音频前处理 (动态增益无损优化) =================
83
  def preprocess_audio(input_path: str, target_sr: int = 16000):
 
84
  y, sr = librosa.load(input_path, sr=target_sr, mono=True)
85
  if len(y) == 0:
86
  return input_path, 0.0
87
 
88
  duration = float(len(y) / sr)
89
 
90
- # 动态增益补偿(轻微提亮吞音与弱音细节)
91
  try:
92
- y_comp = np.sign(y) * (np.log1p(np.abs(y) * 8.0) / np.log1p(8.0))
93
- y = 0.75 * y + 0.25 * y_comp
94
- except Exception:
95
- pass
96
 
97
  # 峰值归一化至 -0.5 dB
98
  max_val = float(np.max(np.abs(y)))
@@ -147,7 +148,7 @@ def parse_emotion_and_timeline(emo_res, total_duration: float, window_size: floa
147
 
148
  top_emotion = max(emotion_scores, key=emotion_scores.get)
149
 
150
- # 10 秒及以下直接整段输出
151
  if total_duration <= 10.0:
152
  timeline.append({
153
  "start": 0.0,
@@ -269,7 +270,7 @@ async def root():
269
  async def transcribe_audio(
270
  file: UploadFile = File(...),
271
  model_name: str = Form(default="whisper-1", alias="model"),
272
- language: str = Form(default="auto"), # 设为 auto,原生支持中英混合发音
273
  response_format: str = Form(default="json"),
274
  authenticated: bool = Depends(verify_token)
275
  ):
@@ -280,10 +281,10 @@ async def transcribe_audio(
280
 
281
  processed_path = None
282
  try:
283
- # 1. 动态增益无损前处理
284
  processed_path, duration = preprocess_audio(raw_path)
285
 
286
- # 2. SenseVoice 识别文本(支持中英混合,挂载原有中文热词)
287
  asr_lang = language if language in ["zh", "en", "yue", "ja", "ko", "auto"] else "auto"
288
  asr_res = asr_model.generate(
289
  input=processed_path,
@@ -294,7 +295,7 @@ async def transcribe_audio(
294
  raw_text = asr_res[0]["text"] if asr_res and len(asr_res) > 0 else ""
295
  clean_text = re.sub(r"<\|.*?\|>", "", raw_text).strip()
296
 
297
- # 3. 执行中文口语错别字纠错与中英文空格排版
298
  clean_text = correct_colloquial_words(clean_text)
299
  clean_text = format_cjk_spacing(clean_text)
300
 
@@ -309,7 +310,7 @@ async def transcribe_audio(
309
  window_size=5
310
  )
311
 
312
- # 5. 多模态语气裁决
313
  final_emotion, confidence = evaluate_tone_and_emotion(
314
  clean_text,
315
  emotion_scores,
 
6
  import numpy as np
7
  import librosa
8
  import soundfile as sf
9
+ import noisereduce as nr
10
  from fastapi import FastAPI, UploadFile, File, Form, HTTPException, Depends, Security
11
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
12
  from fastapi.responses import JSONResponse, PlainTextResponse
 
29
  )
30
  return True
31
 
32
+ # 亲昵口语热词配置
33
  CUSTOM_HOTWORDS = os.getenv(
34
  "HOTWORDS",
35
  "爹地 Daddy 妈咪 学长 学姐 欧巴 欧尼 宝贝 亲爱的 哥哥 姐姐 弟弟 妹妹 师傅 老公 老婆 爹咪 小路 小路哥哥 因因 岚岚 甜甜 芝芝瓜 小选 小蛇 宝宝 叶瑄 艾因 路辰 罗夏 司岚 星星嘟嘟 牧首 教宗 虎先生 小叶哥哥"
36
  )
37
 
38
+ # 口语错别字规则纠错映射
39
  COLLOQUIAL_CORRECTIONS = {
40
  r"跌地|跌弟|爹底|迭地|嗲地": "爹地",
41
  r"学掌|鞋长|薛长|雪长": "学长",
 
80
  disable_update=True
81
  )
82
 
83
+ # ================= 3. 音频前处理 (改回初始 noisereduce 降噪) =================
84
  def preprocess_audio(input_path: str, target_sr: int = 16000):
85
+ """强制 16kHz 单声道 -> noisereduce 频域降噪 (0.6 强度) -> 峰值归一化"""
86
  y, sr = librosa.load(input_path, sr=target_sr, mono=True)
87
  if len(y) == 0:
88
  return input_path, 0.0
89
 
90
  duration = float(len(y) / sr)
91
 
92
+ # 初始降噪方案:适度频谱降噪 (prop_decrease=0.6)
93
  try:
94
+ y = nr.reduce_noise(y=y, sr=sr, stationary=True, prop_decrease=0.6)
95
+ except Exception as e:
96
+ print(f"[Warn] 降噪跳过: {e}")
 
97
 
98
  # 峰值归一化至 -0.5 dB
99
  max_val = float(np.max(np.abs(y)))
 
148
 
149
  top_emotion = max(emotion_scores, key=emotion_scores.get)
150
 
151
+ # 10 秒及以下不切分
152
  if total_duration <= 10.0:
153
  timeline.append({
154
  "start": 0.0,
 
270
  async def transcribe_audio(
271
  file: UploadFile = File(...),
272
  model_name: str = Form(default="whisper-1", alias="model"),
273
+ language: str = Form(default="auto"),
274
  response_format: str = Form(default="json"),
275
  authenticated: bool = Depends(verify_token)
276
  ):
 
281
 
282
  processed_path = None
283
  try:
284
+ # 1. 降噪与标准化前处理
285
  processed_path, duration = preprocess_audio(raw_path)
286
 
287
+ # 2. SenseVoice 识别文本
288
  asr_lang = language if language in ["zh", "en", "yue", "ja", "ko", "auto"] else "auto"
289
  asr_res = asr_model.generate(
290
  input=processed_path,
 
295
  raw_text = asr_res[0]["text"] if asr_res and len(asr_res) > 0 else ""
296
  clean_text = re.sub(r"<\|.*?\|>", "", raw_text).strip()
297
 
298
+ # 3. 中文口语纠错与中英空格排版
299
  clean_text = correct_colloquial_words(clean_text)
300
  clean_text = format_cjk_spacing(clean_text)
301
 
 
310
  window_size=5
311
  )
312
 
313
+ # 5. 多模态综合语气裁决
314
  final_emotion, confidence = evaluate_tone_and_emotion(
315
  clean_text,
316
  emotion_scores,