Choultion-Rudas commited on
Commit
d8717d3
·
verified ·
1 Parent(s): 481c829

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +46 -23
app.py CHANGED
@@ -128,27 +128,42 @@ def ms_to_srt_time(ms):
128
  return f"{hours:02d}:{minutes:02d}:{seconds:02d},{milliseconds:03d}"
129
 
130
 
131
- def generate_srt(sentence_info, clean=True):
132
  if not sentence_info:
133
  return ""
134
  srt_lines = []
135
  for i, seg in enumerate(sentence_info, 1):
136
  start = ms_to_srt_time(seg.get("start", 0))
137
  end = ms_to_srt_time(seg.get("end", 0))
138
- text = seg.get("text", "")
139
- if clean:
140
- text = re.sub(r"<\|[^>]*\|?>", "", text)
141
- text = text.strip()
142
  if text:
143
  srt_lines.append(f"{i}\n{start} --> {end}\n{text}\n")
144
  return "\n".join(srt_lines).strip()
145
 
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  def model_inference(
148
  audio_input, language, output_format, use_itn, merge_vad, merge_length, ban_emo_unk
149
  ):
150
  if audio_input is None:
151
- return "错误:请上传或录制音频。"
152
  fs, input_wav = audio_input
153
  if input_wav.dtype in [np.int16, np.int32]:
154
  input_wav = input_wav.astype(np.float32) / np.iinfo(input_wav.dtype).max
@@ -159,6 +174,7 @@ def model_inference(
159
  if fs != 16000:
160
  resampler = torchaudio.transforms.Resample(orig_freq=fs, new_freq=16000)
161
  input_wav = resampler(torch.from_numpy(input_wav).to(torch.float32)).numpy()
 
162
  res = model.generate(
163
  input=input_wav,
164
  cache={},
@@ -172,25 +188,21 @@ def model_inference(
172
  )
173
  raw_text = res[0].get("text", "")
174
  if not raw_text:
175
- return "未能识别出文本。"
176
 
177
  sentence_info = res[0].get("sentence_info", [])
 
178
 
179
- if output_format == "纯净文本":
180
- return re.sub(r"<\|[^>]*\|?>", "", raw_text).strip()
181
- elif output_format == "原始富文本":
182
- return raw_text
183
- elif output_format == "Emoji 格式":
184
- return format_to_emoji(raw_text)
185
- elif output_format == "SRT 字幕":
186
- srt_result = generate_srt(sentence_info, clean=True)
187
- return (
188
- srt_result if srt_result else re.sub(r"<\|[^>]*\|?>", "", raw_text).strip()
189
- )
190
- elif output_format == "MASTER_DATA":
191
- srt_raw = generate_srt(sentence_info, clean=False)
192
- return srt_raw if srt_raw else raw_text
193
- return raw_text
194
 
195
 
196
  html_intro = """<div style="text-align: center; font-family: var(--font-sans);"><h1 style="font-size: 28px;">SenseVoice-Small 语音识别模型</h1><p>SenseVoice 是具有音频理解能力的音频基础模型,包括语音识别(ASR)、语种识别(LID)、语音情感识别(SER)和声学事件分类(AEC)或声学事件检测(AED)。</p><p style="font-size: small; color: #888;">支持 MP3, WAV, FLAC, M4A 等常见音频格式。</p></div>"""
@@ -231,6 +243,8 @@ lang_options = [
231
 
232
  with gr.Blocks(theme=gr.themes.Soft(), css=custom_css) as demo:
233
  gr.HTML(html_intro)
 
 
234
  with gr.Row():
235
  with gr.Column(scale=2):
236
  audio_inputs = gr.Audio(label="上传/录制音频")
@@ -258,6 +272,8 @@ with gr.Blocks(theme=gr.themes.Soft(), css=custom_css) as demo:
258
  fn_button = gr.Button("开始识别", variant="primary")
259
  with gr.Column(scale=3):
260
  text_outputs = gr.Textbox(label="识别结果", lines=25, show_copy_button=True)
 
 
261
  fn_button.click(
262
  fn=model_inference,
263
  inputs=[
@@ -269,8 +285,15 @@ with gr.Blocks(theme=gr.themes.Soft(), css=custom_css) as demo:
269
  merge_length_slider,
270
  ban_emo_unk_checkbox,
271
  ],
272
- outputs=text_outputs,
273
  api_name="model_inference",
274
  )
275
 
 
 
 
 
 
 
 
276
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
128
  return f"{hours:02d}:{minutes:02d}:{seconds:02d},{milliseconds:03d}"
129
 
130
 
131
+ def generate_srt(sentence_info):
132
  if not sentence_info:
133
  return ""
134
  srt_lines = []
135
  for i, seg in enumerate(sentence_info, 1):
136
  start = ms_to_srt_time(seg.get("start", 0))
137
  end = ms_to_srt_time(seg.get("end", 0))
138
+ text = re.sub(r"<\|[^>]*\|?>", "", seg.get("text", "")).strip()
 
 
 
139
  if text:
140
  srt_lines.append(f"{i}\n{start} --> {end}\n{text}\n")
141
  return "\n".join(srt_lines).strip()
142
 
143
 
144
+ def apply_format(raw_text, sentence_info, output_format):
145
+ if output_format == "纯净文本":
146
+ return re.sub(r"<\|[^>]*\|?>", "", raw_text).strip()
147
+ elif output_format == "原始富文本":
148
+ return raw_text
149
+ elif output_format == "Emoji 格式":
150
+ return format_to_emoji(raw_text)
151
+ elif output_format == "SRT 字幕":
152
+ srt_result = generate_srt(sentence_info)
153
+ return (
154
+ srt_result if srt_result else re.sub(r"<\|[^>]*\|?>", "", raw_text).strip()
155
+ )
156
+ elif output_format == "ALL_IN_ONE":
157
+ srt_text = generate_srt(sentence_info)
158
+ return f"{raw_text}\n===SRT_DELIMITER===\n{srt_text}"
159
+ return raw_text
160
+
161
+
162
  def model_inference(
163
  audio_input, language, output_format, use_itn, merge_vad, merge_length, ban_emo_unk
164
  ):
165
  if audio_input is None:
166
+ return "错误:请上传或录制音频。", None
167
  fs, input_wav = audio_input
168
  if input_wav.dtype in [np.int16, np.int32]:
169
  input_wav = input_wav.astype(np.float32) / np.iinfo(input_wav.dtype).max
 
174
  if fs != 16000:
175
  resampler = torchaudio.transforms.Resample(orig_freq=fs, new_freq=16000)
176
  input_wav = resampler(torch.from_numpy(input_wav).to(torch.float32)).numpy()
177
+
178
  res = model.generate(
179
  input=input_wav,
180
  cache={},
 
188
  )
189
  raw_text = res[0].get("text", "")
190
  if not raw_text:
191
+ return "未能识别出文本。", None
192
 
193
  sentence_info = res[0].get("sentence_info", [])
194
+ cache_state = {"raw_text": raw_text, "sentence_info": sentence_info}
195
 
196
+ result_text = apply_format(raw_text, sentence_info, output_format)
197
+ return result_text, cache_state
198
+
199
+
200
+ def on_format_change(output_format, cache_state):
201
+ if not cache_state or "raw_text" not in cache_state:
202
+ return gr.update()
203
+ return apply_format(
204
+ cache_state["raw_text"], cache_state.get("sentence_info", []), output_format
205
+ )
 
 
 
 
 
206
 
207
 
208
  html_intro = """<div style="text-align: center; font-family: var(--font-sans);"><h1 style="font-size: 28px;">SenseVoice-Small 语音识别模型</h1><p>SenseVoice 是具有音频理解能力的音频基础模型,包括语音识别(ASR)、语种识别(LID)、语音情感识别(SER)和声学事件分类(AEC)或声学事件检测(AED)。</p><p style="font-size: small; color: #888;">支持 MP3, WAV, FLAC, M4A 等常见音频格式。</p></div>"""
 
243
 
244
  with gr.Blocks(theme=gr.themes.Soft(), css=custom_css) as demo:
245
  gr.HTML(html_intro)
246
+ cached_data = gr.State(value=None)
247
+
248
  with gr.Row():
249
  with gr.Column(scale=2):
250
  audio_inputs = gr.Audio(label="上传/录制音频")
 
272
  fn_button = gr.Button("开始识别", variant="primary")
273
  with gr.Column(scale=3):
274
  text_outputs = gr.Textbox(label="识别结果", lines=25, show_copy_button=True)
275
+
276
+ # 点击识别跑 GPU 模型,并将识别结果缓存到 cached_data
277
  fn_button.click(
278
  fn=model_inference,
279
  inputs=[
 
285
  merge_length_slider,
286
  ban_emo_unk_checkbox,
287
  ],
288
+ outputs=[text_outputs, cached_data],
289
  api_name="model_inference",
290
  )
291
 
292
+ # 识别完成后直接切下拉框,0.001 秒即时切换格式(不重新跑 GPU)
293
+ output_format_dropdown.change(
294
+ fn=on_format_change,
295
+ inputs=[output_format_dropdown, cached_data],
296
+ outputs=text_outputs,
297
+ )
298
+
299
  demo.launch(server_name="0.0.0.0", server_port=7860)