173 lines
5.0 KiB
Python
173 lines
5.0 KiB
Python
|
|
#!/usr/bin/env python
|
|||
|
|
# -*- coding: utf-8 -*-
|
|||
|
|
"""
|
|||
|
|
百度语音识别服务(超级简单,不需要ffmpeg)
|
|||
|
|
免费额度:每天50000次
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
from flask import Flask, request, jsonify
|
|||
|
|
from flask_cors import CORS
|
|||
|
|
import base64
|
|||
|
|
import json
|
|||
|
|
from difflib import SequenceMatcher
|
|||
|
|
|
|||
|
|
app = Flask(__name__)
|
|||
|
|
CORS(app)
|
|||
|
|
|
|||
|
|
# 百度语音识别配置(需要申请)
|
|||
|
|
# 免费申请地址:https://console.bce.baidu.com/ai/#/ai/speech/overview/index
|
|||
|
|
BAIDU_APP_ID = "你的APP_ID" # ← 需要替换
|
|||
|
|
BAIDU_API_KEY = "你的API_KEY" # ← 需要替换
|
|||
|
|
BAIDU_SECRET_KEY = "你的SECRET_KEY" # ← 需要替换
|
|||
|
|
|
|||
|
|
# 懒加载客户端
|
|||
|
|
asr_client = None
|
|||
|
|
|
|||
|
|
def get_asr_client():
|
|||
|
|
"""获取百度语音识别客户端"""
|
|||
|
|
global asr_client
|
|||
|
|
if asr_client is None:
|
|||
|
|
try:
|
|||
|
|
from aip import AipSpeech
|
|||
|
|
asr_client = AipSpeech(BAIDU_APP_ID, BAIDU_API_KEY, BAIDU_SECRET_KEY)
|
|||
|
|
print("✓ 百度语音客户端初始化成功")
|
|||
|
|
except ImportError:
|
|||
|
|
print("✗ 未安装百度SDK,请运行: pip install baidu-aip")
|
|||
|
|
return None
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"✗ 初始化失败: {str(e)}")
|
|||
|
|
return None
|
|||
|
|
return asr_client
|
|||
|
|
|
|||
|
|
def recognize_audio_baidu(audio_data, format='mp3'):
|
|||
|
|
"""使用百度API识别音频"""
|
|||
|
|
try:
|
|||
|
|
client = get_asr_client()
|
|||
|
|
if not client:
|
|||
|
|
return None, "百度语音客户端未初始化"
|
|||
|
|
|
|||
|
|
# 百度API识别
|
|||
|
|
result = client.asr(audio_data, format, 16000, {
|
|||
|
|
'dev_pid': 1537, # 中文普通话
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if result['err_no'] == 0:
|
|||
|
|
text = ''.join(result['result'])
|
|||
|
|
return text, None
|
|||
|
|
else:
|
|||
|
|
return None, f"识别失败: {result.get('err_msg', '未知错误')}"
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
return None, str(e)
|
|||
|
|
|
|||
|
|
def calculate_similarity(text1, text2):
|
|||
|
|
"""计算文本相似度(0-100分)"""
|
|||
|
|
if not text1 or not text2:
|
|||
|
|
return 0
|
|||
|
|
|
|||
|
|
text1 = text1.replace(" ", "")
|
|||
|
|
text2 = text2.replace(" ", "")
|
|||
|
|
|
|||
|
|
if not text1 or not text2:
|
|||
|
|
return 0
|
|||
|
|
|
|||
|
|
similarity = SequenceMatcher(None, text1, text2).ratio()
|
|||
|
|
return round(similarity * 100, 2)
|
|||
|
|
|
|||
|
|
@app.route('/api/speech/recognize', methods=['POST'])
|
|||
|
|
def recognize():
|
|||
|
|
"""语音识别接口"""
|
|||
|
|
try:
|
|||
|
|
# 检查文件
|
|||
|
|
if 'audio' not in request.files:
|
|||
|
|
return jsonify({
|
|||
|
|
'code': 400,
|
|||
|
|
'msg': '未上传音频文件'
|
|||
|
|
}), 400
|
|||
|
|
|
|||
|
|
audio_file = request.files['audio']
|
|||
|
|
reference_text = request.form.get('referenceText', '')
|
|||
|
|
|
|||
|
|
# 读取音频数据
|
|||
|
|
audio_data = audio_file.read()
|
|||
|
|
|
|||
|
|
print(f"收到音频: {len(audio_data)} bytes")
|
|||
|
|
print(f"参考文本: {reference_text}")
|
|||
|
|
|
|||
|
|
# 识别音频(百度API自动处理格式)
|
|||
|
|
recognized_text, error = recognize_audio_baidu(audio_data, format='mp3')
|
|||
|
|
|
|||
|
|
if error:
|
|||
|
|
return jsonify({
|
|||
|
|
'code': 500,
|
|||
|
|
'msg': f'识别失败: {error}'
|
|||
|
|
}), 500
|
|||
|
|
|
|||
|
|
if not recognized_text:
|
|||
|
|
return jsonify({
|
|||
|
|
'code': 500,
|
|||
|
|
'msg': '未识别到有效语音'
|
|||
|
|
}), 500
|
|||
|
|
|
|||
|
|
# 计算评分
|
|||
|
|
score = calculate_similarity(recognized_text, reference_text)
|
|||
|
|
pronunciation_score = max(0, score - 5)
|
|||
|
|
fluency_score = max(0, score - 3)
|
|||
|
|
|
|||
|
|
print(f"识别结果: {recognized_text}")
|
|||
|
|
print(f"相似度: {score}分")
|
|||
|
|
|
|||
|
|
return jsonify({
|
|||
|
|
'code': 200,
|
|||
|
|
'msg': '成功',
|
|||
|
|
'data': {
|
|||
|
|
'recognizedText': recognized_text,
|
|||
|
|
'score': score,
|
|||
|
|
'pronunciationScore': pronunciation_score,
|
|||
|
|
'fluencyScore': fluency_score,
|
|||
|
|
'status': 'completed'
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"处理错误: {str(e)}")
|
|||
|
|
return jsonify({
|
|||
|
|
'code': 500,
|
|||
|
|
'msg': f'处理失败: {str(e)}'
|
|||
|
|
}), 500
|
|||
|
|
|
|||
|
|
@app.route('/api/speech/health', methods=['GET'])
|
|||
|
|
def health():
|
|||
|
|
"""健康检查"""
|
|||
|
|
client = get_asr_client()
|
|||
|
|
return jsonify({
|
|||
|
|
'code': 200,
|
|||
|
|
'msg': '服务正常',
|
|||
|
|
'data': {
|
|||
|
|
'engine': 'baidu',
|
|||
|
|
'client_ready': client is not None
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if __name__ == '__main__':
|
|||
|
|
print("=" * 50)
|
|||
|
|
print("百度语音识别服务(超简单,无需ffmpeg)")
|
|||
|
|
print("=" * 50)
|
|||
|
|
print("")
|
|||
|
|
print("1. 安装依赖: pip install baidu-aip")
|
|||
|
|
print("2. 申请百度API: https://console.bce.baidu.com/ai/#/ai/speech/overview/index")
|
|||
|
|
print("3. 填写 APP_ID, API_KEY, SECRET_KEY")
|
|||
|
|
print("")
|
|||
|
|
|
|||
|
|
if BAIDU_APP_ID == "你的APP_ID":
|
|||
|
|
print("⚠️ 请先配置百度API密钥!")
|
|||
|
|
print("")
|
|||
|
|
|
|||
|
|
print("=" * 50)
|
|||
|
|
print("服务启动成功!")
|
|||
|
|
print("访问地址: http://localhost:5000")
|
|||
|
|
print("=" * 50)
|
|||
|
|
print("")
|
|||
|
|
|
|||
|
|
app.run(host='0.0.0.0', port=5000, debug=False)
|