录音文件识别Restful API
功能介绍
录音文件识别时针对已经录制的音频文件,进行文字转写。录音文件识别是非实时的,通过接口提交录音文件或可以直接下载的文件URL,系统接收后进行识别转文字。
录音文件识别采用异步调用(非实时),音频文件上传成功后进入等待队列,识别成功后可以采用主动轮询或者回调的方式获得识别结果,返回结果时间受音频时长以及排队任务量的影响。 如遇识别耗时比平时延长,大概率表示当前时间段出现识别高峰,请耐心等待,免费用户在24小时内完成并返回识别结果;付费用户在3小时内完成并返回识别结果。
音频要求
- 直接上传音频数据方式一次最多不能超过64MB
- 通过提交音频URL方式文件大小不超过512MB
- 单声道:wav,pcm,mp3,ogg,flac
- 双声道:wav,mp3,ogg,flac
- 音频采样率:8000Hz,16000Hz(音频采样率如果大于16000,会强制降采样到参数指定采样率,再进行识别)
- 位深:16bits
使用方法
1. 创建账号和应用,详见平台新手指引,通过标贝开放平台/应用/服务获取client_id,client_secret
2. 发送请求获取access_token,详见获取访问令牌
3. 发送新建任务请求:发送新建任务请求,具体参数详见请求参数。
4. 接收返回结果:发送请求成功后会立即收到返回响应,采用JSON格式封装,在“taskid"字段中获取任务id,具体参数详见新建任务响应结果
5. 发送查询识别结果请求:使用“taskid”发送查询识别结果请求,具体参数详见查询识别结果。
6. 接收识别结果:发送请求成功后会立即收到返回响应,采用JSON格式封装,识别结果在“text"字段内,具体参数详见响应识别结果。
服务地址
访问类型 | 说明 | URL | Host |
---|---|---|---|
外网访问 | 新建任务 | https://openapi.data-baker.com/asr/starttask? | openapi.data-baker.com |
外网访问 |
查询结果
(主动轮询) | https://openapi.data-baker.com/asr/taskresult? | openapi.data-baker.com |
交互流程
测试音频
请求参数
参数名称 | 名称 | 是否必填 | 说明 |
---|---|---|---|
access_token | String | Yes | 通过client_id,client_secret调用授权服务获得见获取访问令牌 |
file_url | String | No | 录音文件URL,外网可访问。 如未指定该参数,则把音频方与请求体中上传 |
callback_url | String | No |
识别结果回调URL
如有,则识别结束后通过回调通知 否则,则通过查询结果进行轮询 |
channel | Integer | No |
录音文件声道数
1:单声道 2:双声道 |
audio_format | String | Yes |
音频格式 单声道:wav,pcm,mp3,ogg,flac 双声道:wav,mp3,ogg,flac |
sample_rate | String | Yes | 音频采样率支持 8000Hz 16000Hz (音频采样率如果大于16000,会强制降采样到参数指定采样率,再进行识别) |
domain | String | no |
模型名称 16k采样率支持模型: 中文通用模型 "common",默认值 中英自由说模型 "cn-en-mixed" 英文模型 "english", 粤语模型 "cantonese", 维语模型 "uighur", 8k采样率支持模型: 中文客服模型 "kefu" |
add_pct | String | no | true: 加标点,默认值 false:不添加标点 |
hotwordid | String | no | 配置的热词组的id |
diylmid | String | no | asr个性化模型的id |
enable_itn | String | no |
中文数字转换为阿拉伯数字(仅支持3位及以上数字串) ‘true’: 开启 ‘false’: 关闭 |
auto_split | String | no |
开启说话人分离(该功能处于测试阶段,支持2个说话人分离,效果持续优化中) ‘true’: 开启 ‘false’: 关闭 |
当未指定file_url参数时,请将二进制音频数据放到HTTP请求体中;
当指定file_url参数时,服务端将忽略HTTP请求体,并从指定的url处下载音频文件
请求示例
curl -X POST \ -H "access_token:xxxxxxxxxx" \ -H "audio_format:wav" \ -H "sample_rate:16000" \ --data-binary "@wav_16k.wav" \ "https://openapi.data-baker.com/asr/starttask?"
Python示例代码
代码地址:Github
Python3示例如下:
#!/usr/bin/env python # coding: utf-8 import argparse import time import requests import json # 获取access_token用于鉴权 def get_access_token(client_secret, client_id): grant_type = "client_credentials" url = "https://openapi.data-baker.com/oauth/2.0/token?grant_type={}&client_secret={}&client_id={}".format( grant_type, client_secret, client_id) response = requests.post(url) access_token = json.loads(response.text).get('access_token') return access_token # 查询识别结果 def get_text(headers): url = "https://asr.data-baker.com/asr/taskresult" response = requests.post(url, headers=headers) text = json.loads(response.text).get("text") code = json.loads(response.text).get("code") if code == 20000 or code == 20001 or code == 20005: return text else: raise Exception(response.text) # 创建识别任务,发送识别文件 def create_task(file, headers): url = "https://asr.data-baker.com/asr/starttask?" response = requests.post(url, data=file, headers=headers) task_id = json.loads(response.text).get("taskid") code = json.loads(response.text).get("code") if code != 20000: raise Exception(response.text) return task_id # 获取命令行输入参数 def get_args(): parser = argparse.ArgumentParser(description='ASR') parser.add_argument('-client_secret', type=str, required=True) parser.add_argument('-client_id', type=str, required=True) parser.add_argument('-file_path', type=str, required=True) parser.add_argument('--audio_format', type=str, default='wav') parser.add_argument('--sample_rate', type=str, default='16000') args = parser.parse_args() return args if __name__ == '__main__': try: args = get_args() # 获取access_token client_secret = args.client_secret client_id = args.client_id access_token = get_access_token(client_secret, client_id) # 新建任务 file = open(args.file_path, 'rb') audio_format = args.audio_format sample_rate = args.sample_rate headers = {'access_token': access_token, 'audio_format': audio_format, 'sample_rate': sample_rate, 'domain': 'common'} task_id = create_task(file, headers) # 主动轮询查询识别结果 recognition_headers = {'access_token': access_token, 'taskid': task_id} while True: text = get_text(recognition_headers) if text: break else: time.sleep(2) print('task is processing') print(text['left_result']) except Exception as e: print(e)
命令行执行: 默认wav格式,16000采样率
python audio_file_recognition.py -client_secret=你的client_secret -client_id=你的client_secret -file_path=test.wav
如有主要可自行修改参数
python audio_file_recognition.py -client_secret=你的client_secret -client_id=你的client_id -file_path=test.wav --audio_format=wavmple_rate=16000
PHP示例代码
<?php //获取访问令牌 $client_secret = '***'; //应用secret $client_id = '***'; //应用id $grant_type = 'client_credentials'; //固定格式 //1.获取token $url = 'https://openapi.data-baker.com/oauth/2.0/token?grant_type='.$grant_type.'&client_id='.$client_id.'&client_secret='.$client_secret; //curl get请求 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //信任任何证书 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 检查证书中是否设置域名,0不验证 $token_res = curl_exec($ch); //如果错误 查看错误信息 if(curl_errno($ch)) { print curl_error($ch); } curl_close($ch); //进行token信息解析 $token_info = json_decode($token_res,1); $access_token = $token_info['access_token']; //获取到的token信息 //var_dump($access_token);die; //$access_token = '***'; //2.录音文件新建任务 说明(支持录音文件url方式,支持识别结果回调方式。本demo采用本地文件发送请求体识别,主动轮询识别结果方式。) $url = 'https://openapi.data-baker.com/asr/starttask?'; //curl post请求 $audio_format = 'wav'; //音频格式 $sample_rate = 16000; //采样率 $Content_Type = 'application/json; charset=utf-8'; $headers = array( 'access_token:'.$access_token, 'audio_format:'.$audio_format, 'sample_rate:'.$sample_rate, 'Content-Type:'.$Content_Type ); $file_path = './test.wav'; //第一种方式读取 $post_audio = file_get_contents($file_path); //第二种方式读取 //$file_size = filesize($file_path); //$post_audio = fread(fopen($file_path, "r"), $file_size); $ch = curl_init(); curl_setopt($ch, CURLINFO_HEADER_OUT, true); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_audio); $audio_res = curl_exec($ch); //$request_header = curl_getinfo($ch, CURLINFO_HEADER_OUT); if(curl_errno($ch)) { print curl_error($ch); } curl_close($ch); $audio_info = json_decode($audio_res,1); $task_id = $audio_info['taskid']; //新建任务后返回的全局唯一任务ID //3.查询识别结果 function queryRes($access_token,$task_id){ sleep(10); //等待10s后查询识别结果(可以队列方式) $url = 'https://openapi.data-baker.com/asr/taskresult?'; //curl post请求 $Content_Type = 'application/json; charset=utf-8'; $headers = array( 'access_token:'.$access_token, 'taskid:'.$task_id, 'Content-Type:'.$Content_Type ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if(curl_errno($ch)) { print curl_error($ch); } curl_close($ch); $result_info = json_decode($result,1); //如果响应结果不成功递归调用 if($result_info['code']!=20000){ queryRes($access_token,$task_id); }else{ $text = $result_info['text']; //录音文件识别结果 json 类型 var_dump($text);die; } } queryRes($access_token,$task_id);
C示例代码
代码地址:Github
JAVA示例代码
package com.databaker.web.asr; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import okhttp3.*; import org.apache.commons.lang3.StringUtils; import java.io.File; import java.io.FileInputStream; /** * 录音文件识别RESTFUL API接口调用示例 * 附:录音文件识别RESTFUL API文档 【https://www.data-baker.com/specs/file/asr_file_api_restful】 * * 注意: * 1.仅作为demo示例,失败重试、token过期重新获取、日志打印等优化工作需要开发者自行完成 * 2.录音文件识别中的录音文件有两种提交方式:A.在header中通过音频下载链接方式提交 B.在body中通过音频文件流方式提交。服务端优先使用方式A提供的音频。 * 3.录音文件识别是非实时接口,提供了两种方式获取结果:A.开发者提供回调接口 B.开发者主动查询进度接口。开发者可自由选择,主动查询时注意频率不要太高。 * * @author data-baker */ public class AsrFileRestApiDemo { /** * 授权:需要在开放平台获取【https://ai.data-baker.com/】 */ private static final String clientId = "YOUR_CLIENT_ID"; private static final String clientSecret = "YOUR_CLIENT_SECRET"; /** * 获取token的地址信息 */ public static String tokenUrl = "https://openapi.data-baker.com/oauth/2.0/token?grant_type=client_credentials&client_secret=%s&client_id=%s"; /** * 录音文件识别API地址 */ public static String asrSubmitTaskUrl = "https://openapi.data-baker.com/asr/starttask"; /** * 录音文件识别API地址 */ public static String asrQueryTaskUrl = "https://openapi.data-baker.com/asr/taskresult"; /** * 文件流方式上传音频,最大支持64M;音频URL方式上传,最大支持512M */ public static Integer MAX_FILE_SIZE = 64 * 1024 * 1024; /** * 仅作为demo示例 * 失败重试、token过期重新获取、日志打印等优化工作需要开发者自行完成 **/ public static void main(String[] args) { String accessToken = getAccessToken(); if (StringUtils.isNotEmpty(accessToken)) { //支持两种上传音频方式:url或文件流;支持三种音频格式:pcm、wav、mp3 //1.url方式 //String audioFileInfo = "YOUR_AUDIO_FILE_URL"; //String taskId = submitFileAsrTask(accessToken, audioFileInfo, AudioFileTypeEnum.UrlType, "mp3", 16000, ""); //2.文件流方式 String audioFileInfo = "YOUR_AUDIO_FILE_FULL_PATH"; String taskId = submitFileAsrTask(accessToken, audioFileInfo, AudioFileTypeEnum.FileType, "pcm", 16000, ""); //查询识别结果 try { if (StringUtils.isNotEmpty(taskId)) { Thread.sleep(10 * 1000); queryFileAsrTaskResult(accessToken, taskId); } } catch (Exception e) { e.printStackTrace(); } } } /** * 提交录音文件识别任务 */ public static String submitFileAsrTask(String accessToken, String audioFileInfo, AudioFileTypeEnum fileType, String audioFormat, Integer sampleRate, String callback_url) { try { OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/octet-stream"); //requestBody默认为空 RequestBody requestBody = RequestBody.create(null, new byte[0]); //如果以文件流方式上传,文件流放在requestBody里面 if (AudioFileTypeEnum.FileType.equals(fileType)) { File audioFile = new File(audioFileInfo); if (!audioFile.exists() || audioFile.length() > MAX_FILE_SIZE) { return ""; } FileInputStream in = new FileInputStream(audioFile); byte[] fileByte = new byte[(int) audioFile.length()]; int realLen = in.read(fileByte); //确保音频文件内容全部被读取 if (realLen == (int) audioFile.length()) { requestBody = RequestBody.create(mediaType, fileByte); } } //构造完整request Request request = new Request.Builder() .url(asrSubmitTaskUrl) .addHeader("access_token", accessToken) .addHeader("file_url", AudioFileTypeEnum.UrlType.equals(fileType) ? audioFileInfo : "") .addHeader("audio_format", audioFormat) .addHeader("sample_rate", String.valueOf(sampleRate)) .addHeader("domain", "common") .addHeader("callback_url", callback_url) .method("POST", requestBody) .build(); Response response = client.newCall(request).execute(); if (response.isSuccessful()) { JSONObject jsonObject = JSON.parseObject(response.body().string()); System.out.println("提交识别任务成功,任务id:" + (jsonObject == null ? "" : jsonObject.getString("taskid"))); return jsonObject == null ? "" : jsonObject.getString("taskid"); } else { System.out.println("提交识别任务失败,错误信息:" + response.body().string()); } } catch (Exception e) { e.printStackTrace(); } return ""; } /** * 查询录音文件识别任务的结果 */ public static void queryFileAsrTaskResult(String accessToken, String taskId) { try { OkHttpClient client = new OkHttpClient(); //requestBody默认为空 RequestBody requestBody = RequestBody.create(null, new byte[0]); Request request = new Request.Builder() .url(asrQueryTaskUrl) .addHeader("access_token", accessToken) .addHeader("taskid", taskId) .method("POST", requestBody) .build(); Response response = client.newCall(request).execute(); if (response.isSuccessful()) { JSONObject jsonObject = JSON.parseObject(response.body().string()); // 返回的结构开发者可参考接口文档【https://www.data-baker.com/specs/file/asr_file_api_restful】中的“响应识别结果”部分。 // 本demo测试时使用的是单声道音频,故仅获取left_result作为示例。开发者请根据音频情况自行解析。 if (jsonObject == null) { System.out.println("查询识别任务成功,结果信息:null"); } else { jsonObject = jsonObject.getJSONObject("text"); System.out.println("查询识别任务成功,结果信息:" + (jsonObject == null ? "null" : jsonObject.getString("left_result"))); } } else { System.out.println("查询识别任务失败,错误信息:" + response.body().string()); } } catch (Exception e) { e.printStackTrace(); } } public static String getAccessToken() { String accessToken = ""; OkHttpClient client = new OkHttpClient(); //request 默认是get请求 String url = String.format(tokenUrl, clientSecret, clientId); Request request = new Request.Builder().url(url).build(); JSONObject jsonObject; try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { //解析 String resultJson = response.body().string(); jsonObject = JSON.parseObject(resultJson); accessToken = jsonObject.getString("access_token"); } } catch (Exception e) { e.printStackTrace(); } return accessToken; } public enum AudioFileTypeEnum { UrlType(1), FileType(2); private int type; AudioFileTypeEnum(int type) { this.type = type; } } }
GO示例代码
package main import ( "bytes" "encoding/json" "errors" "flag" "fmt" "io/ioutil" "net/http" "net/url" "os" "strconv" "time" ) type AuthInfo struct { AccessToken string `json:"access_token"` ExpiresIn int `json:"expires_in"` Scope string `json:"scope"` } type ReqTtsParams struct { AccessToken string AudioFormat string SampleRate int domain string hotwordId string diylmId string Channel int } type Response struct { Code int `json:"code"` Taskid string `json:"taskid"` TraceId string `json:"trace_id"` } type RecognitionText struct { LeftResult string `json:"left_result"` RightResult string `json:"right_result"` } type RecognitionResult struct { Code int `json:"code"` Taskid string `json:"taskid"` TraceId string `json:"trace_id"` Info string `json:"info"` Text RecognitionText `json:"text"` } const grantType string = "client_credentials" func GetToken(reqUrl, clientId, clientSecret string) (string, error) { // 超时时间:60秒 client := &http.Client{Timeout: 60 * time.Second} urlParams := url.Values{} urlParams.Add("grant_type", grantType) urlParams.Add("client_id", clientId) urlParams.Add("client_secret", clientSecret) httpUrl := reqUrl httpUrl += "?" httpUrl += urlParams.Encode() fmt.Printf("httpUrl: %s\n\n", httpUrl) resp, err := client.Get(httpUrl) if err != nil { fmt.Printf("send http get token request failed, err: %s\n", err) return "", err } defer resp.Body.Close() result, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("http get token request, readall body failed, err: %s\n", err) return "", err } authInfo := AuthInfo{} err = json.Unmarshal(result, &authInfo) if err != nil { fmt.Printf("auth info json.Unmarshal err: %s \n", err) return "", err } if len(authInfo.AccessToken) <= 0 { return "", errors.New("access token is null") } fmt.Printf("get token success. info: %#v \n", authInfo) return authInfo.AccessToken, nil } func CreateTask(reqUrl, file string, reqParam ReqTtsParams) (string, error) { // 超时时间:60秒 client := &http.Client{Timeout: 60 * time.Second} fmt.Printf("reqUrl: %s\n\n", reqUrl) fileContent, err := ioutil.ReadFile(file) if err != nil { return "", err } req, err := http.NewRequest(http.MethodPost, reqUrl, bytes.NewReader(fileContent)) if err != nil { return "", err } req.Header.Add("access_token", reqParam.AccessToken) req.Header.Add("audio_format", reqParam.AudioFormat) req.Header.Add("sample_rate", strconv.Itoa(reqParam.SampleRate)) if len(reqParam.domain) > 0 { req.Header.Add("domain", reqParam.domain) } if len(reqParam.hotwordId) > 0 { req.Header.Add("hotwordid", reqParam.hotwordId) } if len(reqParam.diylmId) > 0 { req.Header.Add("diylmid", reqParam.diylmId) } if reqParam.Channel > 0 { req.Header.Add("channel", strconv.Itoa(reqParam.Channel)) } resp, err := client.Do(req) if err != nil { fmt.Printf("send http request failed, err: %s \n", err) return "", err } defer resp.Body.Close() if resp.StatusCode != 200 { fmt.Printf("send http request return status code != 200\n") return "", errors.New("status code is not 200") } result, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("readall http body failed, err: %s \n", err) return "", err } response := Response{} if err = json.Unmarshal(result, &response); err != nil { return "", err } if response.Code != 20000 { return string(result), errors.New("request failed code != 20000") } return response.Taskid, nil } func QueryResult(reqUrl, taskId, access_token string) (int, error) { client := &http.Client{Timeout: 60 * time.Second} req, err := http.NewRequest(http.MethodPost, reqUrl, nil) if err != nil { return 0, err } req.Header.Add("access_token", access_token) req.Header.Add("taskid", taskId) resp, err := client.Do(req) if err != nil { return 0, err } defer resp.Body.Close() if resp.StatusCode != 200 { fmt.Printf("send http request return status code != 200\n") return 0, errors.New("status code is not 200") } resultJson, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("readall http body failed, err: %s \n", err) return 0, err } result := RecognitionResult{} if err = json.Unmarshal(resultJson, &result); err != nil { return 0, err } if 20000 != result.Code { return result.Code, fmt.Errorf("code:%d, traceId:%s info:%s", result.Code, result.TraceId, result.Info) } fmt.Printf("code:\t\t%d\ntraceId:\t%s\nleft_result:\t%s\nright_result:\t%s\n", result.Code, result.TraceId, result.Text.LeftResult, result.Text.RightResult) return result.Code, nil } func main() { var ( clientId, clientSecret, file, audio_format, domain string sample_rate, channel int ) flag.StringVar(&clientId, "cid", "", "client id") flag.StringVar(&clientSecret, "cs", "", "client secret") flag.StringVar(&file, "f", "", "识别文件") flag.IntVar(&sample_rate, "sample_rate", 16000, "音频采样率") flag.IntVar(&channel, "channel", 1, "录音文件声道数") flag.StringVar(&domain, "domain", "", "模型名称") flag.StringVar(&audio_format, "audio_format", "wav", "音频格式") flag.Parse() if len(os.Args) < 2 { flag.Usage() return } if len(clientId) <= 0 || len(clientSecret) <= 0 || len(file) <= 0 || len(audio_format) <= 0 { fmt.Println("parameter error!!!") return } // 获取令牌 accessToken, err := GetToken("https://openapi.data-baker.com/oauth/2.0/token", clientId, clientSecret, ) if err != nil { fmt.Println("get access token failed!!!! please check your client_id and client_secret.") return } param := ReqTtsParams{ AccessToken: accessToken, SampleRate: sample_rate, AudioFormat: audio_format, Channel: channel, domain: domain, } // 创建识别任务 result, err := CreateTask("https://openapi.data-baker.com/asr/starttask?", file, param) if err != nil { fmt.Printf("send request failed. result: %s \n", result) return } fmt.Printf("create task success. traceId: %s\n", result) for { // 查询识别结果 code, err := QueryResult("https://openapi.data-baker.com/asr/taskresult?", result, accessToken) if err == nil { break } if code != 20001 && code != 20005 { fmt.Printf("query result failed. error: %s\n", err.Error()) break } fmt.Printf("query result failed. %s\n", err.Error()) time.Sleep(time.Second) } fmt.Println("request finish...") }
新建任务响应结果
字段名 | 描述 |
---|---|
trace_id | 日志id,如遇到问题,可反馈此id给开发,用于跟踪问题 |
code | 请求结果码,请参考错误码一节 |
info | 任务结果描述,如请求失败请根据该字段内容分析问题 |
taskid | 任务id,后面请求方可携带此taskid去查询是否识别结束 |
{ "trace_id":" 1571988259683020 ", "code":20000, "info":"Success", "taskid":" f0c58fc9************90e3ebfdb653" }2. 请求失败
{ "trace_id":" 1571988883381595 ", "code":40007, "info":"Invalid body" }
查询识别结果
参数名称 | 类型 | 是否必填 | 说明 |
---|---|---|---|
access_token | String | Yes | 通过client_id,client_secret调用授权服务获得见获取访问令牌 |
taskid | string | yes | 识别任务的taskid |
curl -X POST \ -H "access_token:xxxxxxxxxx" \ -H "taskid:f0c58fc9************90e3ebfdb653" \ "https://openapi.data-baker.com/asr/taskresult"
响应结果参数
字段名 | 类型 | 描述 |
---|---|---|
trace_id | string | 日志id,如遇到问题,可反馈此id给开发,用于跟踪问题 |
code | int | 请求结果码,请参考错误码一节 |
info | string | 任务结果描述,如请求失败请根据该字段内容分析问题 |
text | jsonObject | 识别结果,josn对象,任务失败则为空 |
taskid | string | 任务id,后面请求方可携带此taskid去查询是否识别结束 |
left_duration | int | 左声道时长,单位:ms |
right_duration | int | 右声道时长,单位:ms |
text内部结构:
字段名 | 类型 | 描述 |
---|---|---|
left_result_array | jsonArray | 左声道分段识别结果 |
right_result_array | jsonArray | 右声道分段识别结果 |
left_result | string | 左声道全部识别结果 |
right_result | string | 右声道全部识别结果 |
left_result_array和right_result_array内部结构:
参数名称 | 类型 | 描述 |
---|---|---|
result | string | 识别结果 |
text | string | 语音识别结果,失败时为空 |
confidence | string | 整句置信度[0-100],值越大表示置信度越高。 |
speed | int | 语速,取值[0-2000] |
speakerid | int | 说话人id,开启后值为1和2,关闭后值为-1 |
sos | string | 该句在音频中的绝对开始时间点 单位:秒 |
eos | string | 该句在音频中的绝对结束时间点 单位:秒 |
segment_code | int | 分段任务code,暂时固定为 20000,忽略该字段 |
speed_label | string |
语速标签: 15以下:FAST 快 15-30 : MEDIUM 适中 30-2000:SLOW 慢 |
volume | int | 音量,取值[0-100] |
volume_label | string |
音量标签: SILENT:0-15 静音 XSOFT:15-30 音量很小 SOFT:30-50 音量小 MEDIUM:50-70 音量适中 LOAD:70-85 音量大 XLOUD:85-100 音量很大 |
words | array | 词级别识别结果 |
words内部结构:
字段名 | 类型 | 描述 |
---|---|---|
confidence | string | 词置信度[0-1],值越大表示置信度越高。 |
sos | string | 词在音频中的绝对开始时间点 单位:秒 |
eos | string | 词在音频中的绝对结束时间点 单位:秒 |
word | string | 词 |
响应结果示例
{ "code": 20000, "info": "Success", "left_duration": 4992, "right_duration": 4992, "taskid": "1b3eb3b4-9a04-4804-87af-170bffdd21bf", "text": { "left_result": "欢迎使用标贝科技开放平台。", "left_result_array": [ { "confidence": "58.33", "eos": "4.42", "result": "欢迎使用标贝科技开放平台。", "segment_code": 20000, "sos": "0.38", "speed": 33, "speakerid": -1, "speedlabel": "SLOW", "success": "yes", "volume": 43, "volume_label": "SOFT", "words": [ { "confidence": "0.33", "eos": "1.52", "sos": "1.07", "word": "欢迎" }, { "confidence": "0.67", "eos": "2.06", "sos": "1.52", "word": "使用" }, { "confidence": "0.50", "eos": "2.53", "sos": "2.06", "word": "标贝" }, { "confidence": "0.50", "eos": "2.96", "sos": "2.53", "word": "科技" }, { "confidence": "0.50", "eos": "3.41", "sos": "2.96", "word": "开放" }, { "confidence": "1.00", "eos": "4.38", "sos": "3.41", "word": "平台" } ] } ], "right_result": "欢迎使用标贝科技开放平台。", "right_result_array": [ { "confidence": "58.33", "eos": "4.42", "result": "欢迎使用标贝科技开放平台。", "segment_code": 20000, "sos": "0.38", "speed": 33, "speakerid": -1, "speed_label": "SLOW", "success": "yes", "volume": 43, "volume_label": "SOFT", "words": [ { "confidence": "0.33", "eos": "1.52", "sos": "1.07", "word": "欢迎" }, { "confidence": "0.67", "eos": "2.06", "sos": "1.52", "word": "使用" }, { "confidence": "0.50", "eos": "2.53", "sos": "2.06", "word": "标贝" }, { "confidence": "0.50", "eos": "2.96", "sos": "2.53", "word": "科技" }, { "confidence": "0.50", "eos": "3.41", "sos": "2.96", "word": "开放" }, { "confidence": "1.00", "eos": "4.38", "sos": "3.41", "word": "平台" } ] } ] }, "trace_id": "1652152016088962" }
回调通知
录音文件识别支持回调接口发送识别结果,在调用创建任务接口时,填写callback_url可以将识别结果直接发送到该接口。(如果长时间未收到回调通知,仍可以根据taskid调用识别接口进行查询)
回调通知Python3示例代码
from flask import Flask, request import json app = Flask(__name__) @app.route("/", methods=['GET', 'POST']) def get_text(): with open('test.txt', 'w') as f: text = json.loads(request.get_data())['text']['left_result'] f.write(text) return "finished"
将上述代码保存为server.py
命令行执行
export FLASK_APP=server flask run -p 端口号 --host=服务器IP
回调示例
{'left_result': '欢迎使用标贝科技开放平台!', 'left_result_array': [{'eos': '4.97', 'result': '欢迎使用标贝科技开放平台!', 'segment_code': 20000, 'sos': '0.23', 'success': 'yes'}]}
错误码
code | 描述 | 解决方案 |
---|---|---|
20000 | 请求成功 | |
20001 | 任务正在处理 | 等待10分钟再查询 |
20002 | taskid无效 | 使用新建识别任务时返回的taskid |
20005 | 任务在队列中等待被调度执行 | 之前任务结束后自动进行 |
20006 | 音频分割后,部分识别失败 | 重新发送识别请求,或联系技术人员 |
20007 | 音频分割后,全部识别失败 | 重新发送识别请求,或联系技术人员 |
30001 | HTTP请求参数错误 | 服务器内部错误,提交traceid,标贝后台进行排查。 |
30002 | 服务内部错误 | |
30003 | 识别结果解析出错 | |
30004 | 应用包名未知 | |
30005 | 语音质量问题 | |
30006 | 输入语音过长 | |
30007 | 连接识别引擎失败 | |
30008 | 会话id不存在 | |
30009 | Rpc调用非法 | |
30010 | redis rpop操作返回空 | |
30011 | redis rpop值不合法 | |
30012 | rpc调用识别引擎失败 | |
30013 | Redis rpop操作失败 | |
30014 | redis lpush操作失败 | |
30015 | 单个语音分片过长 | |
30016 | 回调url失败 | |
50002 | 内部rpc调用失败 | |
50009 | 其他内部错误 |