147 lines
5.0 KiB
Python
147 lines
5.0 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
测试 ASR 修复是否有效
|
||
"""
|
||
import sys
|
||
import os
|
||
sys.path.append('.')
|
||
|
||
import requests
|
||
import base64
|
||
import wave
|
||
import struct
|
||
import math
|
||
import logging
|
||
|
||
# 设置日志
|
||
logging.basicConfig(level=logging.INFO)
|
||
logger = logging.getLogger(__name__)
|
||
|
||
def create_speech_like_audio():
|
||
"""创建类似语音的音频数据"""
|
||
sample_rate = 16000
|
||
duration = 3 # 3 秒
|
||
|
||
# 生成更复杂的音频,模拟语音特征
|
||
samples = []
|
||
for i in range(sample_rate * duration):
|
||
t = i / sample_rate
|
||
|
||
# 基频(模拟人声基频)
|
||
f0 = 150 + 50 * math.sin(2 * math.pi * 0.5 * t) # 变化的基频
|
||
|
||
# 多个谐波分量
|
||
sample = 0
|
||
for harmonic in range(1, 6): # 前5个谐波
|
||
amplitude = 1.0 / harmonic # 谐波幅度递减
|
||
sample += amplitude * math.sin(2 * math.pi * f0 * harmonic * t)
|
||
|
||
# 添加包络(模拟语音的动态变化)
|
||
envelope = 0.5 * (1 + math.sin(2 * math.pi * 2 * t)) # 2Hz 的包络变化
|
||
|
||
# 添加一些噪声(模拟语音的复杂性)
|
||
noise = 0.1 * (math.sin(2 * math.pi * 1000 * t) + 0.5 * math.sin(2 * math.pi * 2000 * t))
|
||
|
||
# 组合所有分量
|
||
final_sample = (sample + noise) * envelope * 0.3 # 控制总体音量
|
||
|
||
# 转换为 16-bit 整数
|
||
sample_int = int(16000 * final_sample)
|
||
sample_int = max(-32767, min(32767, sample_int))
|
||
samples.append(sample_int)
|
||
|
||
# 转换为字节数据
|
||
audio_bytes = bytearray()
|
||
for sample in samples:
|
||
audio_bytes.extend(struct.pack('<h', sample))
|
||
|
||
logger.info(f"创建类语音音频数据,大小: {len(audio_bytes)} 字节,时长: {duration} 秒")
|
||
return bytes(audio_bytes)
|
||
|
||
def test_asr_endpoint():
|
||
"""测试 ASR 端点"""
|
||
|
||
# 创建测试音频数据
|
||
audio_data = create_speech_like_audio()
|
||
|
||
# 转换为 base64
|
||
audio_base64 = base64.b64encode(audio_data).decode('utf-8')
|
||
logger.info(f"Base64 编码长度: {len(audio_base64)}")
|
||
|
||
# 准备请求数据
|
||
request_data = {
|
||
'audio_data': audio_base64,
|
||
'format': 'mp3' # 虽然实际是PCM,但测试格式处理
|
||
}
|
||
|
||
# 发送请求到后端
|
||
url = "http://192.168.1.141:30102/voice/call/asr"
|
||
headers = {
|
||
'Content-Type': 'application/json',
|
||
'Authorization': 'Bearer test_token'
|
||
}
|
||
|
||
logger.info(f"发送 ASR 请求到: {url}")
|
||
|
||
try:
|
||
response = requests.post(url, json=request_data, headers=headers, timeout=60)
|
||
|
||
logger.info(f"响应状态码: {response.status_code}")
|
||
logger.info(f"响应头: {response.headers}")
|
||
logger.info(f"响应内容: {response.text}")
|
||
|
||
if response.status_code == 200:
|
||
try:
|
||
result = response.json()
|
||
logger.info(f"✅ ASR 请求成功")
|
||
logger.info(f"识别结果: {result}")
|
||
|
||
if 'data' in result and 'text' in result['data']:
|
||
text = result['data']['text']
|
||
logger.info(f"🎯 识别文本: {text}")
|
||
|
||
# 检查是否是预期的错误消息
|
||
if "音频格式解码失败" in text:
|
||
logger.info("✅ 收到格式错误提示,说明 ASR 流程正常工作")
|
||
return True
|
||
elif "未识别到语音内容" in text:
|
||
logger.info("✅ 收到无语音提示,说明 ASR 流程正常工作")
|
||
return True
|
||
elif "OSS" in text:
|
||
logger.info("✅ 收到 OSS 相关提示,说明流程到达了 OSS 阶段")
|
||
return True
|
||
else:
|
||
logger.info("✅ 收到其他响应,ASR 流程正常")
|
||
return True
|
||
else:
|
||
logger.warning("响应格式不符合预期")
|
||
return False
|
||
|
||
except Exception as json_error:
|
||
logger.error(f"解析 JSON 响应失败: {json_error}")
|
||
return False
|
||
else:
|
||
logger.error(f"❌ ASR 请求失败: {response.status_code}")
|
||
logger.error(f"错误内容: {response.text}")
|
||
return False
|
||
|
||
except requests.exceptions.Timeout:
|
||
logger.error("❌ 请求超时")
|
||
return False
|
||
except requests.exceptions.ConnectionError:
|
||
logger.error("❌ 连接失败,请确保后端服务正在运行")
|
||
return False
|
||
except Exception as e:
|
||
logger.error(f"❌ 请求异常: {e}")
|
||
return False
|
||
|
||
if __name__ == "__main__":
|
||
logger.info("开始测试 ASR 修复...")
|
||
success = test_asr_endpoint()
|
||
|
||
if success:
|
||
logger.info("🎉 ASR 修复测试成功!")
|
||
logger.info("现在可以在前端测试录音功能了")
|
||
else:
|
||
logger.error("💥 ASR 修复测试失败")
|
||
sys.exit(1) |