1een commited on
Commit
d2ebecd
·
1 Parent(s): fba960c
Files changed (1) hide show
  1. fixed_app.py +106 -0
fixed_app.py CHANGED
@@ -80,6 +80,56 @@ def load_model(model_name: str):
80
  logger.error(f"找不到模型 {model_name},请确保模型文件存在")
81
  raise HTTPException(status_code=500, detail=f"Model {model_name} not found")
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  def decode_audio(audio_base64: str) -> str:
84
  """解码base64音频数据并保存为临时文件,返回文件路径"""
85
  try:
@@ -192,6 +242,12 @@ async def transcribe_audio(request: AudioRequest):
192
 
193
  logger.info(f"使用whisper二进制: {whisper_binary}")
194
 
 
 
 
 
 
 
195
  # 构建命令 - 根据二进制文件类型调整参数
196
  if "whisper-cli" in whisper_binary:
197
  # 新的whisper-cli命令格式 - 不输出到文件,直接输出到stdout
@@ -280,6 +336,11 @@ async def transcribe_audio(request: AudioRequest):
280
  # 清理临时文件
281
  if os.path.exists(audio_file):
282
  os.unlink(audio_file)
 
 
 
 
 
283
 
284
  return StreamingResponse(event_stream(), media_type="text/event-stream")
285
  except Exception as e:
@@ -355,6 +416,50 @@ async def test_audio_decode(request: AudioRequest):
355
  "error": str(e)
356
  }
357
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
  @app.get("/")
359
  async def root():
360
  """根路径"""
@@ -367,6 +472,7 @@ async def root():
367
  "transcribe": "/transcribe",
368
  "test": "/test",
369
  "test-audio": "/test-audio",
 
370
  "test-transcribe": "/test-transcribe"
371
  }
372
  }
 
80
  logger.error(f"找不到模型 {model_name},请确保模型文件存在")
81
  raise HTTPException(status_code=500, detail=f"Model {model_name} not found")
82
 
83
+ async def convert_audio_to_wav(input_file: str) -> str:
84
+ """使用ffmpeg将音频文件转换为WAV格式"""
85
+ try:
86
+ # 创建输出文件路径
87
+ output_file = input_file.rsplit('.', 1)[0] + '_converted.wav'
88
+
89
+ # 构建ffmpeg命令
90
+ cmd = [
91
+ 'ffmpeg',
92
+ '-i', input_file, # 输入文件
93
+ '-acodec', 'pcm_s16le', # 音频编码器:16位PCM
94
+ '-ar', '16000', # 采样率:16kHz(whisper推荐)
95
+ '-ac', '1', # 声道数:单声道
96
+ '-y', # 覆盖输出文件
97
+ output_file
98
+ ]
99
+
100
+ logger.info(f"开始音频转换: {' '.join(cmd)}")
101
+
102
+ # 执行ffmpeg命令
103
+ proc = await asyncio.create_subprocess_exec(
104
+ *cmd,
105
+ stdout=asyncio.subprocess.PIPE,
106
+ stderr=asyncio.subprocess.PIPE
107
+ )
108
+
109
+ stdout, stderr = await proc.communicate()
110
+
111
+ if proc.returncode != 0:
112
+ error_msg = stderr.decode() if stderr else "Unknown ffmpeg error"
113
+ logger.error(f"音频转换失败: {error_msg}")
114
+ raise HTTPException(status_code=500, detail=f"Audio conversion failed: {error_msg}")
115
+
116
+ # 验证输出文件是否存在
117
+ if not os.path.exists(output_file):
118
+ raise HTTPException(status_code=500, detail="Converted audio file not found")
119
+
120
+ # 删除原始文件
121
+ if os.path.exists(input_file):
122
+ os.unlink(input_file)
123
+
124
+ logger.info(f"音频转换成功: {output_file}, 大小: {os.path.getsize(output_file)} 字节")
125
+ return output_file
126
+
127
+ except HTTPException:
128
+ raise
129
+ except Exception as e:
130
+ logger.error(f"音频转换过程中出错: {e}")
131
+ raise HTTPException(status_code=500, detail=f"Audio conversion error: {str(e)}")
132
+
133
  def decode_audio(audio_base64: str) -> str:
134
  """解码base64音频数据并保存为临时文件,返回文件路径"""
135
  try:
 
242
 
243
  logger.info(f"使用whisper二进制: {whisper_binary}")
244
 
245
+ # 检查音频格式,如果不支持则转换为WAV
246
+ supported_formats = ('.wav', '.flac', '.mp3', '.ogg')
247
+ if not audio_file.endswith(supported_formats):
248
+ logger.info(f"音频格式不直接支持,将转换为WAV: {audio_file}")
249
+ audio_file = await convert_audio_to_wav(audio_file)
250
+
251
  # 构建命令 - 根据二进制文件类型调整参数
252
  if "whisper-cli" in whisper_binary:
253
  # 新的whisper-cli命令格式 - 不输出到文件,直接输出到stdout
 
336
  # 清理临时文件
337
  if os.path.exists(audio_file):
338
  os.unlink(audio_file)
339
+ # 如果有转换后的文件,也要清理
340
+ if audio_file.endswith('_converted.wav'):
341
+ original_file = audio_file.replace('_converted.wav', '.m4a')
342
+ if os.path.exists(original_file):
343
+ os.unlink(original_file)
344
 
345
  return StreamingResponse(event_stream(), media_type="text/event-stream")
346
  except Exception as e:
 
416
  "error": str(e)
417
  }
418
 
419
+ @app.post("/test-convert")
420
+ async def test_audio_conversion(request: AudioRequest):
421
+ """测试音频格式转换功能"""
422
+ try:
423
+ # 解码音频
424
+ audio_file = decode_audio(request.audio)
425
+ logger.info(f"原始音频文件: {audio_file}")
426
+
427
+ # 检查是否需要转换
428
+ if not audio_file.endswith(('.wav', '.flac', '.mp3', '.ogg')):
429
+ logger.info("需要转换格式")
430
+ converted_file = await convert_audio_to_wav(audio_file)
431
+
432
+ # 获取转换后的文件信息
433
+ converted_size = os.path.getsize(converted_file)
434
+
435
+ # 清理文件
436
+ os.unlink(converted_file)
437
+
438
+ return {
439
+ "status": "success",
440
+ "message": "音频转换成功",
441
+ "original_file": audio_file,
442
+ "converted_file": converted_file,
443
+ "converted_size": converted_size,
444
+ "conversion_needed": True
445
+ }
446
+ else:
447
+ # 清理文件
448
+ os.unlink(audio_file)
449
+
450
+ return {
451
+ "status": "success",
452
+ "message": "音频格式已支持,无需转换",
453
+ "original_file": audio_file,
454
+ "conversion_needed": False
455
+ }
456
+
457
+ except Exception as e:
458
+ return {
459
+ "status": "error",
460
+ "error": str(e)
461
+ }
462
+
463
  @app.get("/")
464
  async def root():
465
  """根路径"""
 
472
  "transcribe": "/transcribe",
473
  "test": "/test",
474
  "test-audio": "/test-audio",
475
+ "test-convert": "/test-convert",
476
  "test-transcribe": "/test-transcribe"
477
  }
478
  }