Files
aistream-test/python/test/测试连接funAsr.py
2025-12-01 03:42:34 +08:00

80 lines
3.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 服务端未配置 SSLis_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,方便排查错误