80 lines
3.1 KiB
Python
80 lines
3.1 KiB
Python
# app.py(你的 Flask 主文件)
|
||
from flask import Flask, request, jsonify
|
||
import wave
|
||
import io # 新增:处理字节流
|
||
from funasr_client_api import Funasr_websocket_recognizer # 现在能正常导入了
|
||
|
||
app = Flask(__name__)
|
||
|
||
|
||
@app.route('/asr', methods=['POST'])
|
||
def asr():
|
||
# 获取上传的音频文件
|
||
print('请求文件:', request.files)
|
||
if 'audio' not in request.files:
|
||
return jsonify({'error': 'No audio file provided'}), 400
|
||
|
||
audio_file = request.files['audio']
|
||
# 验证文件格式(确保是 WAV)
|
||
if not audio_file.filename.endswith('.wav'):
|
||
return jsonify({'error': 'Only WAV files are supported'}), 400
|
||
|
||
try:
|
||
# 读取音频并解析 WAV 格式(确保是 16k 16bit 单声道)
|
||
audio_bytes = audio_file.read()
|
||
with io.BytesIO(audio_bytes) as wav_buffer:
|
||
with wave.open(wav_buffer, 'rb') as wf:
|
||
channels = wf.getnchannels()
|
||
sample_width = wf.getsampwidth()
|
||
framerate = wf.getframerate()
|
||
# 验证音频参数(FunASR 要求 16k 16bit 单声道)
|
||
if channels != 1 or sample_width != 2 or framerate != 16000:
|
||
return jsonify({
|
||
'error': 'Audio format not supported',
|
||
'hint': 'Need 16kHz, 16bit, mono WAV'
|
||
}), 400
|
||
|
||
# 计算分片参数(优化:按 200ms 分片,更适配 FunASR)
|
||
chunk_duration = 0.2 # 200ms 每片
|
||
stride = int(chunk_duration * framerate * sample_width) # 每片字节数
|
||
chunk_num = (len(audio_bytes) - 1) // stride + 1
|
||
print(f'分片参数:每片字节数={stride}, 总分片数={chunk_num}')
|
||
|
||
# 创建识别器(注意:is_ssl=False 先测试,避免证书问题)
|
||
# 若 FunASR 服务端未配置 SSL,is_ssl 必须为 False
|
||
rcg = Funasr_websocket_recognizer(
|
||
host="192.168.109.129",
|
||
port="10096",
|
||
is_ssl=False, # 先改为 False 测试,确认服务端是否开启 SSL
|
||
mode="online",
|
||
chunk_size="0,10,5"
|
||
)
|
||
|
||
# 发送分片并收集结果
|
||
results = []
|
||
for i in range(chunk_num):
|
||
beg = i * stride
|
||
end = beg + stride
|
||
chunk_data = audio_bytes[beg:end]
|
||
text = rcg.feed_chunk(chunk_data, wait_time=0.05) # 增加等待时间,提高识别率
|
||
if text and text.strip():
|
||
results.append(text.strip())
|
||
print(f'第{i + 1}片识别结果:{text}')
|
||
|
||
# 获取最后结果
|
||
final_text = rcg.close(timeout=5) # 延长超时时间
|
||
if final_text and final_text.strip():
|
||
results.append(final_text.strip())
|
||
|
||
return jsonify({
|
||
'result': results,
|
||
'final_result': "".join(results) # 新增:合并后的最终结果
|
||
})
|
||
|
||
except Exception as e:
|
||
print(f'识别失败:{e}')
|
||
return jsonify({'error': f'ASR failed: {str(e)}'}), 500
|
||
|
||
|
||
if __name__ == '__main__':
|
||
app.run(host='0.0.0.0', port=5000, debug=True) # 开启 debug,方便排查错误 |