录音文件识别-旧版

最近更新时间:2019-09-04 18:54:46

接口描述

本接口服务对一小时之内的录音文件进行识别,异步返回识别全部结果,支持语音 URL 和本地语音文件两种请求方式。接口是 HTTP RESTful 形式,在使用该接口前,需要在 语音识别控制台 开通服务,并进入 API 密钥管理页面 新建密钥,生成 AppID、SecretID 和 SecretKey ,用于 API 调用时生成签名,签名将用来进行接口鉴权。

接口要求

集成录音文件识别 API 时,需按照以下要求。

内容 说明
请求协议 HTTP
请求地址 https://aai.qcloud.com/asr/v1/<appid>? {请求参数}
接口鉴权 签名机制,详见 签名生成
响应格式 统一采用 JSON 格式
开发语言 任意,只要可以向腾讯云服务发起HTTP请求的均可
音频属性 采样率16k或8k、位长16bits、单声道或双声道
音频格式 支持 wav、pcm、mp3、silk、speex、amr、m4a 等主流音频格式
数据长度 若采用直接上传音频数据方式,建议音频数据不能大于5MB
若采用上传音频 url 方式,建议音频时长不能大于1小时。
语言种类 中文普通话、带有一定方言口音的普通话

请求结构

请求结构主要由请求方法、请求 URL、请求头部、请求正文组成。

请求方法

HTTPS 请求方法,录音文件识别的请求方法为 POST

请求 URL

RESTful 形式的 URL 结构示例如下:

https://aai.qcloud.com/asr/v1/<appid>? 
projectid=xxx&
sub_service_type=xxx& 
engine_model_type=xxx& 
callback_url=xxx& 
channel_num=xxx& 
res_text_format=xxx&
res_type=xxx&  
source_type=xxx&
url=xxx&
secretid=xxx&
timestamp=xxx& 
expired=xxx& 
nonce=xxx

URL 中各字段含义如下:

参数名称 必选 类型 描述
AppID Int 用户在腾讯云注册账号的 AppID,可以进入 API 密钥管理页面 获取
projectid Int 腾讯云项目 ID,语音识别目前不区分项目,所以填0即可。
secretid String 用户在腾讯云注册账号 AppId 对应的 SecretId,可以进入 API 密钥管理页面 获取
sub_service_type Int 子服务类型。0:录音文件识别
engine_model_type String 引擎类型。8k_0:电话 8k 通用模型;16k_0:16k 通用模型;8k_6: 电话场景下单声道话者分离模型
res_text_format Int 识别结果文本编码方式。0:UTF-8;1:GB2312;2:GBK;3:BIG5
res_type Int 结果返回方式。 1:同步返回;0:尾包返回
callback_url String 回调 URL,用户自行搭建的用于接收识别结果的服务器地址, 长度小于2048字节
channel_num Int 语音声道数,1:单声道;2:双声道(仅在电话 8k 通用模型下支持)
source_type Int 语音数据来源。0:语音 URL;1:语音数据(post body)
url String 语音的 URL 地址,需要公网可下载。长度小于2048字节,当 source_type 值为 0 时须填写该字段,为 1 时不需要填写
timestamp Int 当前 UNIX 时间戳,可记录发起 API 请求的时间。如果与当前时间相差过大,会引起签名过期错误。可以取值为当前请求的系统时间戳即可
expired Int 签名的有效期,是一个符合 UNIX Epoch 时间戳规范的数值,单位为秒;Expired 必须大于 Timestamp 且 Expired - Timestamp 小于90天。
nonce Int 随机正整数。用户需自行生成,最长10位。

请求头部

请求头部,包括 Host,Authorization,Content-Type,Content-Length 四个参数。

参数名称 必选 类型 描述
Host String 语音识别服务域名,固定为 aai.qcloud.com
Authorization String 用户的有效签名,用于鉴权。对应签名鉴权中得到的签名字符串
Content-Type String application/octet-stream
Content-Length Int 请求长度,此处对应语音数据字节数,单位:字节

请求正文

语音数据,当 SourceType 值为1(语音数据上传)时必须填写,当 SourceType 值为0(语音 URL 上传)可不写。要使用base64编码(采用 Python 语言时注意读取文件应该为 string 而不是 byte,以 byte 格式读取后要 decode()。编码后的数据不可带有回车换行符)。音频数据要小于5MB。

请求示例

请求示例如下,示例生成请参考下面 PHP 代码

示例1

用户通过语音 URL 地址方式请求。
用户通过 签名生成 的签名 5Zb1hKd8uo4H+AgpMbktZhHqqjY=,通过语音 URL(https://xuhai2-1255824371.cos.ap-chengdu.myqcloud.com/test.wav) 的方式请求录音文件识别服务,服务的引擎模型为8k_0,识别的录音文件为单声道,采样率为8k。

curl -sv -H 'Authorization:5Zb1hKd8uo4H+AgpMbktZhHqqjY=' 'https://aai.qcloud.com/asr/v1/1259228442?callback_url=http://test.qq.com&channel_num=1&engine_model_type=8k_0&expired=1561464926&nonce=6666&projectid=0&res_text_format=0&res_type=1&secretid=AKIDoQq1zhZMN8dv0psmvud6OUKuGPO7pu0r&source_type=0&sub_service_type=0&timestamp=1561461326&url=https://xuhai2-1255824371.cos.ap-chengdu.myqcloud.com/test.wav'

示例2

用户通过本地语音上传方式请求。
用户通过 签名生成 的签名 j8AY1RkedGSoDxCjAEtT2pq/r1w=,通过本地上传语音(voicedata 为用户实际上传的从音频文件读取的音频数据)的方式请求录音文件识别服务,服务的引擎模型为8k_0,识别的录音文件为单声道,采样率为8k。

curl -sv -H 'Authorization:j8AY1RkedGSoDxCjAEtT2pq/r1w=' 'https://aai.qcloud.com/asr/v1/1259228442?callback_url=http://test.qq.com&channel_num=1&engine_model_type=8k_0&expired=1561465286&nonce=6666&projectid=0&res_text_format=0&res_type=1&secretid=AKIDoQq1zhZMN8dv0psmvud6OUKuGPO7pu0r&source_type=1&sub_service_type=0&timestamp=1561461686' -d 'voicedata'

签名生成

这里以 Appid = 1259228442, SecretId = AKIDoQq1zhZMN8dv0psmvud6OUKuGPO7pu0r 为例拼接签名原文,则拼接的签名原文为:

POSTaai.qcloud.com/asr/v1/1259228442?callback_url=http://test.qq.com&channel_num=1&engine_model_type=8k_0&expired=1561464926&nonce=6666&projectid=0&res_text_format=0&res_type=1&secretid=AKIDoQq1zhZMN8dv0psmvud6OUKuGPO7pu0r&source_type=0&sub_service_type=0&timestamp=1561461326&url=https://xuhai2-1255824371.cos.ap-chengdu.myqcloud.com/test.wav

对签名原文和 SecretKey= kFpwoX5RYQ2SkqpeHgqmSzHK7h3A2fni,使用 HmacSha1 算法进行加密处理:

签名串=Base64Encode(HmacSha1(签名原文,SecretKey))

最终得到签名串为:

5Zb1hKd8uo4H+AgpMbktZhHqqjY=

返回结构

返回结果

录音文件识别的 RESTful API 请求返回结果如下表所示:

参数名称 类型 描述
code Int 服务器错误码,0 为成功
message String 服务器返回的信息
requestId Int 如果成功,返回任务 ID

返回示例

返回消息示例如下:

 { "code":0, "message":"success", "requestId":500 }

结果回调

当语音识别系统完成识别后,会将结果通过 HTTP POST 请求的形式通知到用户,用户需要在自身业务服务器上搭建服务接收回调。

服务端返回结果

语音识别系统通过回调接口形式将识别结果回调通知客户,接口 Body 各字段说明如下:

字段 类型 描述
code Int 服务器错误码,0 为成功,其他:失败
message String 成功或者失败原因文字描述
requestId Int 请求 ID,与后台任务 ID 一一对应
appid Int 腾讯云应用 ID
projectid Int 腾讯云项目 ID
audioUrl String 语音下载 ur。如果语音源非公网可下载 URL,则不包含该字段
text String 识别出的结果文本。对于双声道文件,左声道标记为1,右声道标记为0
audioTime Double 语音总时长
注意:

为了防止某些字段中,出现诸如 “&” 等特殊字符,导致解包失败,所有字段的 value 值都将进行 url_encode 之后发送给用户业务服务器,在获取 value 之后,需要先对 value 进行 url_decode 以获取原始 value 值。

客户端确认返回

用户业务服务器在接收到语音识别系统发起的 HTTP POST 回调请求后,需要按照如下约定,返回结果:

参数名称 类型 描述
code Int 错误码,0 为成功,其他值代表失败
message String 失败原因说明,例如业务服务器过载。 如果业务服务器返回失败,会间隔一段时间重新通知

回调示例

服务端返回 FormData 示例:

code=0&requestId=500&appid=12000001&projectid=0&text=%e6%82%a8%e5%a5%bd&audioUrl=http%3a%2f%2ftest.qq.com%2fvoice_url&audioTime=2.5&message=success

语音识别系统发起请求,收到请求后,用户侧需要以 JSON 格式回以响应:

{ "code" : 0, "message" : "成功" }

请求错误码

数值 返回码 说明
1000 ERROR_BAD_REQ 请求的参数不符合要求
1001 ERROR_PARSE_DATA_FAILED 解析请求参数时失败
1002 ERROR_HAS_NO_VALID_PROJECTID 没有提供 projectid,或者值不合法
1003 ERROR_HAS_NO_VALID_RES_TEXT_FORMAT 没有提供 res_text_format,或者值不合法
1004 ERROR_HAS_NO_VALID_SUB_SERVICE_TYPE 没有提供 sub_service_type,或者值不合法
1005 ERROR_HAS_NO_VALID_ENGINE_MODEL_TYPE 没有提供 engine_model_type,或者值不合法
1006 ERROR_HAS_NO_VALID_CALLBACK_URL 没有提供 callback_url,或者值不合法
1007 ERROR_HAS_NO_VALID_RES_TYPE 没有提供 res_type,或者值不合法
1008 ERROR_HAS_NO_VALID_SOURCE_TYPE 没有提供 source_type,或者值不合法
1009 ERROR_HAS_NO_VALID_URL 没有提供下载语音的 url,或者值不合法
1010 ERROR_HAS_NO_VALID_SECRET_ID 没有提供 SecretId,或者值不合法
1011 ERROR_HAS_NO_VALID_TIMESTAMP 没有提供 timestamp,或者值不合法
1012 ERROR_HAS_NO_VALID_EXPIRED 没有提供 expired,或者值不合法
1013 ERROR_HAS_NO_VALID_NONCE 没有提供 nonce,或者值不合法
1014 ERROR_HAS_NO_VALID_TEMPLATENAME 提供的 template_name 不合法
1015 ERROR_HAS_NO_BUCKET 没有提供 bucket,或者值不合法
1016 ERROR_HAS_NO_AMOUNT 没有剩余的免费用量
1017 ERROR_URL_TOO_LONG 提供的 url 长度大于 2048
1018 ERROR_FILEID_TOO_LONG 提供的文件名长度大于 2048
1019 ERROR_APPID_NOT_REGISTER 提供的 APPID 未注册
1020 ERROR_APPID_PROJECTID_TEMPLATENAME_MISMATCH 提供的 APPID,ProjectId 与 template_name 不匹配
1021 ERROR_PROCESS_FAILED 服务端处理出现内部错误
1022 ERROR_PROXY_BAD_AUTH 签名不符合规则
1024 ERROR_PROXY_AUTH_TOO_LONG_EXPIRED 签名的有效期设置太长
1025 ERROR_PROXY_AUTH_EXPIRED 签名过期
1026 ERROR_PROXY_AUTH_PROJECTID_NOEXIST 签名中的 ProjectId 错误
1027 ERROR_PROXY_AUTH_SECRETID_NOEXIST 签名中的 SecretId 错误
1028 ERROR_PROXY_AUTH_PROJECTID_MISMATCH 签名中的 ProjectId 不匹配
1029 ERROR_PROXY_AUTH_REPLAY_ATTACK 重放攻击
1030 ERROR_PROXY_AUTH_FAILED 签名验证不通过
1032 ERROR_AUDIO_TOO_LARGE 发送的语音数据过大(大于 5M)
1034 ERROR_UNKNOWN 其他未知错误

回调错误码

数值 说明
10000 语音非标准格式,转码失败
10001 识别不成功
10002 语音时长过长
10003 语音时长过长
10004 无效的语音文件
10005 其他失败
10006 音轨个数不匹配

PHP 代码示例

//filepath 音频文件路径
//callBackUrl 回调地址
//sourceUrl 语音 URL,只有filepath为空时生效
function sendvoice($filepath, $callBackUrl, $sourceUrl) {
    if (empty ($filepath) && empty ($sourceUrl)) {
        echo "filepath and sourceUrl can not be empty at the same time";
        return -1;
    }
    $reqArr = array ();
    $reqArr['appid'] = Config :: $APPID;
    $reqArr['secretid'] = Config :: $SECRET_ID;
    $reqArr['projectid'] = 0;
    $reqArr['sub_service_type'] = 0; //表示为录音文件识别
    $reqArr['engine_model_type'] = Config :: $ENGINE_MODEL_TYPE;
    $reqArr['callback_url'] = $callBackUrl;
    $reqArr['channel_num'] = Config :: $CHANNEL_NUM;
    $reqArr['res_text_format'] = Config :: $RESULT_TEXT_FORMAT;
    $reqArr['res_type'] = Config :: $RES_TYPE;
    $voicedata = '';
    if (empty ($filepath)) {
        $reqArr['source_type'] = 0; // 语音 URL;
        $reqArr['url'] = $sourceUrl;
    } else {
        $reqArr['source_type'] = 1; // 语音数据(post body)
        $voicedata = file_get_contents($filepath);
    }
    $reqArr['timestamp'] = time();
    $reqArr['expired'] = time() + 24 * 60 * 60;
    $reqArr['nonce'] = rand(1, 10000);

    $serverUrl = "http://aai.qcloud.com/asr/v1/";
    $serverUrl .= $reqArr['appid'] . "?";
    $serverUrl .= "secretid=" . $reqArr['secretid'] . "&";
    $serverUrl .= "projectid=" . $reqArr['projectid'] . "&";
    $serverUrl .= "sub_service_type=" . $reqArr['sub_service_type'] . "&";
    $serverUrl .= "engine_model_type=" . $reqArr['engine_model_type'] . "&";
    $serverUrl .= "callback_url=" . urlencode($reqArr['callback_url']) . "&";
    $serverUrl .= "channel_num=" . $reqArr['channel_num'] . "&";
    $serverUrl .= "res_text_format=" . $reqArr['res_text_format'] . "&";
    $serverUrl .= "res_type=" . $reqArr['res_type'] . "&";
    $serverUrl .= "source_type=" . $reqArr['source_type'] . "&";
    if ($reqArr['source_type'] == 0) {
        $serverUrl .= "url=" . urlencode($reqArr['url']) . "&";
    }
    $serverUrl .= "timestamp=" . $reqArr['timestamp'] . "&";
    $serverUrl .= "expired=" . $reqArr['expired'] . "&";
    $serverUrl .= "nonce=" . $reqArr['nonce'];

    $autho = createSign($reqArr, "POST", "aai.qcloud.com", "/asr/v1/", Config :: $SECRET_KEY);

    $header = array (
        'Authorization: ' . $autho,
        'Content-Length: ' . strlen($voicedata),
    );

    $rsp_str = "";
    $http_code = -1;

    $ret = http_curl_exec($serverUrl, $voicedata, $rsp_str, $http_code, 'POST', 10, array (), $header);
    if ($ret != 0) {
        echo "http_curl_exec failed \n";
        return false;
    }
    return $rsp_str;
}