小米AI语音识别需通过HTTP API对接PHP后端,核心是上传PCM/WAV音频、生成HMAC-SHA256签名(含UTC时间戳与multipart/form-data头)、解析words数组校验置信度,而非依赖text字段。

小米AI语音识别API怎么对接PHP后端
不能直接在PHP里“调用语音指令识别”,小米AI语音能力必须走HTTP API(https://ai.api.xiaomi.com/v1/asr),PHP只负责发请求、传音频、收JSON结果。核心是把用户录音转成PCM/WAV,再按小米要求签名、上传。
- 必须用POST,
Content-Type: multipart/form-data,不是JSON体;音频文件字段名固定为audio,不是file或voice - 鉴权靠
X-XIAOMI-DATE和Authorization两个Header,其中Authorization是HMAC-SHA256签名,密钥来自小米开放平台申请的secret_key,不是Access Token - 音频格式必须是单声道、16bit、16kHz的
PCM(.raw)或WAV;用MP3或AMR会直接返回{"code":400,"msg":"invalid audio format"}
PHP怎么生成小米ASR必需的Authorization签名
签名错是50%以上失败的根源——不是算法写错,而是拼接顺序或编码不一致。小米要求签名原文是:POST\n/v1/asr\nX-XIAOMI-DATE:<timestamp>\ncontent-type:multipart/form-data; boundary=xxx\n</timestamp>(注意换行符是\n,不是\r\n,且content-type小写、带空格和boundary值)。
-
$timestamp必须是UTC时间RFC1123格式,用gmdate('D, d M Y H:i:s \G\M\T'),不是date() - 计算HMAC时,
hash_hmac('sha256', $string_to_sign, $secret_key, true)第三个参数true不能漏,否则返回的是hex字符串而非二进制,Base64编码会错 - 最终
Authorization头格式为:HMAC-SHA256 <access_key>:<base64_encoded_signature></base64_encoded_signature></access_key>,<access_key></access_key>是你在小米后台看到的AK,不是APP ID
解析小米返回的语音命令结果要注意什么
小米ASR返回的JSON里,有效文本在data.result.text,但实际业务中90%的坑不在这里,而在data.result.words和置信度处理上。
- 如果用户说“打开客厅灯”,返回可能是
{"text":"打开客厅等","words":[{"word":"打开","score":0.92},{"word":"客厅","score":0.87},{"word":"等","score":0.41}]}——最后字明显是“灯”识别成“等”,但text字段已合并,无法直接修正 - 真正可控的是
words数组:每个词带score,低于0.7就该怀疑;别无脑取text,建议对words逐个校验,score < 0.65的词替换成通配符或丢弃 - 小米不返回标点,也不分句。如果用户说“关掉空调,打开加湿器”,
text是连在一起的,需自己用逗号/句号切分,再走NLU规则或关键词匹配
PHP处理用户自定义语音命令的典型流程
所谓“自定义命令”,本质是把ASR输出的文本映射到你自己的动作逻辑,不是让小米做语义理解——它只管转文字,后面全靠你写if/else或正则。
立即学习“PHP免费学习笔记(深入)”;
- 先清洗:去掉空格、全角符号、语气词(如“嗯”、“啊”),用
preg_replace('/[^\p{Han}\w\s,。!?;:]+/u', '', $text) - 再匹配:用
stripos($text, '打开') !== false && stripos($text, '灯') !== false比正则更稳;避免写/(开|启动|点亮).*灯/这种过度泛化规则,容易误触发 - 最后兜底:当
data.result.score < 0.75(小米返回的整体置信度)时,直接返回“没听清,请再说一遍”,别强行执行
音频采样、签名生成、结果置信度这三处出问题,基本就卡死整个链路。小米文档里藏了很多默认值和边界条件,比如timeout默认15秒,超时就收不到响应,但错误码还是200——得看data.code字段才能判断真失败。



















