一句话识别Websocket API
功能介绍
识别不超过60s的语音,适用于语音交互、控制口令、对话聊天等场景。
- 支持语言:中文普通话、中英自由说、英文、粤语、维语
- 支持添加标点,支持将中文数字转换为阿拉伯数字进行输出
- 支持连续返回中间识别结果,实现连续上屏效果
音频要求
- 时长限制:60秒以内
- 支持音频格式:wav, pcm
- 音频采样率:8000Hz,16000Hz
- 位深:16bits
- 声道:单声道
使用方法
1. 创建账号和应用,详见平台新手指引,通过标贝开放平台/应用/服务获取client_id,client_secret
2. 发送请求获取access_token,详见获取访问令牌
3. 建立websocket连接
4. 实时发送需要识别的音频,具体参数详见 请求参数。
5. 接收返回结果,具体参数定义详见响应结果说明。
6. 关闭连接。
7. 注意:
1)、 开始识别时,websocket握手建立会话根据网络环境会有一定延迟,需根据实际测试进行处理
2)、 结束识别时,不要立刻关闭麦克风,可以再延迟几百毫秒,收一部分环境静音,有助于vad快速结束。
3)、 最后一个数据包发送出去后,等待最终识别结果返回,返回参数end_flag=1时为最后一个包,不要提前关闭会话。
服务地址
访问类型 | 说明 | URL | Host |
---|---|---|---|
外网访问 | 支持中文普通话、中英自由说、英文、粤语、维语 | wss://openapi.data-baker.com/asr/wsapi/ | openapi.data-baker.com |
交互流程
测试音频
请求参数
参数名称 | 类型 | 是否必填项 | 说明 |
---|---|---|---|
access_token | string | yes | 通过client_id,client_secret调用授权服务获得见 获取访问令牌 |
version | string | yes | 版本信息,目前为1.0 |
asr_params | jsonObject,其中 audio_data字段是必需字段且需使用base64进行编码 | yes | asr相关参数 |
asr相关参数如下:
参数名称 | 类型 | 是否必填项 | 说明 |
---|---|---|---|
audio_data | string | 是 |
流式接口需要将音频分包发送,具体步骤如下: 1. 除最后一包外,每包长度固定为5120字节,最后一包如音频长度不足5120字节时,可直接发送剩余全部数据 2. 对音频进行base64编码 |
audio_format | string | 是 | 音频编码格式 pcm wav |
sample_rate | int | 是 | 音频采样率 8000 16000 |
req_idx | int | 是 | 音频序号索引,步长为1递增 0:起始音频帧 >0:中间音频帧(如1 2 3 4 … 1000) -n:结束音频帧(如-1001) |
domain | string | 否 |
模型名称 16k采样率支持模型: 中文通用模型 "common",默认值 中英自由说模型 "cn-en-mixed" 英文模型 "english", 粤语模型 "cantonese", 维语模型 "uighur", 8k采样率支持模型: 中文客服模型 "kefu" |
add_pct | boolean | no | true: 加标点,默认值 false:不添加标点 |
hotwordid | string | no | 配置的热词组的id |
diylmid | string | no | asr个性化模型的id |
enable_vad | bool | 否 |
False: 关闭静音检测(默认) True:开启静音检测 |
max_begin_silence | int | 否 |
当enable_vad为true时有效,表示允许的最大开始静音时长 单位:毫秒,取值范围[200,60000],输入超过范围取临近值,该值是一个参考值,具体可能会根据音频不同有少量浮动。 超出规定范围后,即开始识别后多长时间没有检测到语音,服务端将会发送错误码90002,表示没有检测到语音,结束本次识别。 |
max_end_silence | int | 否 |
当enable_vad为true时有效,表示允许的最大结束静音时长 单位:毫秒,取值范围[200, 5000],输入超过范围取临近值,该值是一个参考值,具体可能会根据音频不同有少量浮动。 超出规定范围后,即在上句话识别后,间隔多长时间没有检测到语音,结束本次识别,间隔后如果还有后续语音则不会被识别。 |
enable_itn | boolean | 否 |
中文数字转换为阿拉伯数字(仅支持3位及以上数字串) ‘true’: 开启 ‘false’: 关闭 |
请求示例
{ "access_token":" 1ccbbc2d************0cfce63eec55", "version":"1.0", "asr_params":{ "audio_data":"AAAAAAAAAA", "audio_format":"pcm", "sample_rate":16000, "req_idx":0, "domain":"xxx" //非必填 } }
Python示例代码
代码地址:Github
Python3示例:
import argparse import json import base64 from threading import Thread import requests import websocket class Client: def __init__(self, data, uri): self.data = data self.uri = uri #建立连接 def connect(self): ws_app = websocket.WebSocketApp(uri, on_open=self.on_open, on_message=self.on_message, on_error=self.on_error, on_close=self.on_close) ws_app.run_forever() # 建立连接后发送消息 def on_open(self, ws): print("sending..") def run(*args): for i in range(len(self.data)): ws.send(self.data[i]) Thread(target=run).start() # 接收消息 def on_message(self, ws, message): code = json.loads(message).get("code") if code != 90000: # 打印接口错误 print(message) if json.loads(message).get('data')['end_flag'] == 1: print(json.loads(message).get('data')['nbest'][0]) # 打印错误 def on_error(slef, ws, error): print("error: ", str(error)) # 关闭连接 def on_close(ws): print("client closed.") # 准备数据 def prepare_data(args, access_token): # 读取音频文件 with open(args.file_path, 'rb') as f: file = f.read() # 填写Header信息 audio_format = args.audio_format sample_rate = args.sample_rate splited_data = [str(base64.b64encode(file[i:i + 5120]), encoding='utf-8') for i in range(0, len(file), 5120)] asr_params = {"audio_format": audio_format, "sample_rate": int(sample_rate), "speech_type": 1} json_list = [] for i in range(len(splited_data)): if i != len(splited_data) - 1: asr_params['req_idx'] = i else: asr_params['req_idx'] = -len(splited_data) + 1 asr_params["audio_data"] = splited_data[i] data = {"access_token": access_token, "version": "1.0", "asr_params": asr_params} json_list.append(json.dumps(data)) return json_list # 获取命令行输入参数 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 # 获取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) try: response = requests.post(url) response.raise_for_status() except Exception as e: print(response.text) raise Exception else: access_token = json.loads(response.text).get('access_token') return access_token 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) # 准备数据 data = prepare_data(args, access_token) uri = "wss://openapi.data-baker.com/asr/wsapi/" # 建立Websocket连接 client = Client(data, uri) client.connect() except Exception as e: print(e)
命令行执行:
默认wav格式,16000采样率
python single_sentence_recognition.py -client_secret=你的client_secret -client_id=你的client_id -file_path=test.wav
如有需要可自行修改参数
python single_sentence_recognition.py -client_secret=你的client_secret -client_id=你的client_id -file_path=test.wav --audio_format=wav --sample_rate=16000
JAVA示例代码
package com.databaker.web.asr; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import okhttp3.*; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Base64; import java.util.Date; /** * 一句话语音识别 webSocket接口调用示例 * 附:一句话识别Websocket API文档 【https://www.data-baker.com/specs/file/asr_word_api_websocket】 * * 注意: * 1.作为demo,进行了一些简化,采用直接从文件中读取的方式获取音频流,实际场景很可能是从麦克风获取音频流。 * 2.如果从麦克风获取音频流,请注意每次发送的数据流大小为52K,不足时补静音段。 * 3.本demo仅完成基本的接口调用,失败重试、token过期重新获取、日志打印等优化工作需要开发者自行完成。 * * @author data-baker */ public class AsrWebSocketDemo extends WebSocketListener { /** * 授权:需要在开放平台获取【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"; private static final String hostUrl = "wss://openapi.data-baker.com/asr/wsapi"; /** * 文件路径【开发者需要根据实际路径调整。支持的音频编码格式:PCM(无压缩的PCM文件或WAV文件),采样率8K或16K,位深16bit,单声道】 */ private static final String file = "/home/asr/16bit_16k.pcm"; private static final SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss.SSS"); // 开始时间 private static ThreadLocal<Date> timeBegin = ThreadLocal.withInitial(() -> new Date()); // 结束时间 private static ThreadLocal<Date> timeEnd = ThreadLocal.withInitial(() -> new Date()); private Date startTime; private String accessToken = getAccessToken(); private StringBuilder resultAsr = new StringBuilder(); @Override public void onOpen(WebSocket webSocket, Response response) { super.onOpen(webSocket, response); this.startTime = timeBegin.get(); //该demo直接从文件中读取音频流【实际场景可能是实时从麦克风获取音频流,开发者自行修改获取音频流的逻辑即可】 new Thread(() -> { //连接成功,开始发送数据 //每一帧音频的大小,固定值,具体参考接口文档 int frameSize = 5120; int interval = 40; // 音频的序号 int req_idx = 0; try (FileInputStream fs = new FileInputStream(file)) { byte[] buffer = new byte[frameSize]; // 发送音频 while (true) { int len = fs.read(buffer); if (len < frameSize) { //文件已读完 req_idx = -1 - req_idx; } //发送音频 JSONObject jsonObject = new JSONObject(); jsonObject.put("access_token", accessToken); jsonObject.put("version", "1.0"); //填充asr_params JSONObject asrParams = new JSONObject(); //domain非必填 asrParams.put("domain", "common"); asrParams.put("audio_format", "pcm"); asrParams.put("sample_rate", 16000); asrParams.put("req_idx", req_idx); asrParams.put("audio_data", Base64.getEncoder().encodeToString(Arrays.copyOf(buffer, len<0?0:len))); jsonObject.put("asr_params", asrParams); webSocket.send(jsonObject.toString()); if (req_idx >= 0) { req_idx++; }else { break; } //模拟音频采样延时【如果从麦克风获取音频流,可删除这句代码】 Thread.sleep(interval); } System.out.println("all data is send"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } @Override public void onMessage(WebSocket webSocket, String text) { super.onMessage(webSocket, text); ResponseData resp = JSON.parseObject(text, ResponseData.class); if (resp != null) { if (resp.getCode() != 90000) { System.out.println("code=>" + resp.getCode() + " error=>" + resp.getMessage() + " trace_id=" + resp.getTrace_id()); //关闭连接 webSocket.close(1000, ""); System.out.println("发生错误,关闭连接"); return; } if (resp.getData() != null) { if (Integer.valueOf(1).equals(resp.getData().getEnd_flag())) { resultAsr.append(resp.getData().nbest); System.out.println("当前句子识别结束,识别结果 ==》" + resp.getData().nbest); } else { System.out.println("当前句子识别未结束,中间识别结果 ==》" + resp.getData().nbest); } } else { // todo 根据返回的数据处理 } } } @Override public void onFailure(WebSocket webSocket, Throwable t, Response response) { super.onFailure(webSocket, t, response); try { if (null != response) { int code = response.code(); System.out.println("onFailure code:" + code); System.out.println("onFailure body:" + response.body().string()); if (101 != code) { System.out.println("connection failed"); System.exit(0); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 测试方法 * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { OkHttpClient client = new OkHttpClient.Builder().build(); Request request = new Request.Builder().url(hostUrl).build(); client.newWebSocket(request, new AsrWebSocketDemo()); } 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 static class ResponseData { /** * 状态码(4xxxx表示客户端参数错误,5xxxx表示服务端内部错误) */ private Integer code; /** * 错误描述 */ private String message; /** * 任务id */ private String trace_id; /** * 会话id */ private String sid; /** * payload数据 */ private Data data; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getTrace_id() { return trace_id; } public void setTrace_id(String trace_id) { this.trace_id = trace_id; } public String getSid() { return sid; } public void setSid(String sid) { this.sid = sid; } public Data getData() { return data; } public void setData(Data data) { this.data = data; } } /** * payload类 */ public static class Data{ /** * 数据块序列号,请求内容会以流式的数据块方式返回给客户端。服务器端生成,从1递增 */ private Integer res_idx; /** * 识别结果 */ private String nbest; /** * 识别结果预测 */ private String uncertain; /** * 是否是最后一个数据块,0:否,1:是 */ private Integer end_flag; public Integer getRes_idx() { return res_idx; } public void setRes_idx(Integer res_idx) { this.res_idx = res_idx; } public String getNbest() { return nbest; } public void setNbest(String nbest) { this.nbest = nbest; } public String getUncertain() { return uncertain; } public void setUncertain(String uncertain) { this.uncertain = uncertain; } public Integer getEnd_flag() { return end_flag; } public void setEnd_flag(Integer end_flag) { this.end_flag = end_flag; } } }
PHP示例代码
<?php ini_set("max_execution_time", "300"); require_once "websocket-php/vendor/autoload.php"; //1.获取token $client_secret = '***'; //应用secret $client_id = '***'; //应用id $grant_type = 'client_credentials'; //固定格式 $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 = 'wss://openapi.data-baker.com/asr/wsapi/'; $file_path = './test.wav';//文件路径 //定义请求方法 $data_param['access_token'] = $access_token; $data_param['version'] = '1.0'; $data_param['asr_params']['audio_format'] = 'wav'; $data_param['asr_params']['sample_rate'] = 16000; //读取文件 发送数据请求 $client = new \WebSocket\Client($url); //实例化 $file_size = filesize($file_path); //获取文件大小 if(!$file_size) die("文件大小不能为0"); $package_nums = ceil($file_size/5120); //计算要发送的包数量 $handle = fopen($file_path,'rb'); $i=0; //起始音频编号 while (!feof($handle)){ if($i == $package_nums-1){ $data_param['asr_params']['req_idx'] = -$i; }else{ $data_param['asr_params']['req_idx'] = $i; } $audio_info = fread($handle,5120); $data_param['asr_params']['audio_data'] = base64_encode($audio_info); $data = json_encode($data_param); $client->send($data); //发送数据 $i++; } //监听数据 $flag = true; while ($flag) { try { $message = $client->receive();//获取数据 $result_info = json_decode($message,1); if($result_info['code'] == 90000){ if($result_info['data']['end_flag']==1){ //(说明,根据业务逻辑情况使用,本示例对返回完整信息进行展示) $flag=false;//最后一包数据获取完成 停止获取数据 var_dump($result_info['data']['nbest']); } }else{ throw new Exception($result_info['message']); } } catch (\WebSocket\ConnectionException $e) { die($e->getMessage()); } }
GO示例代码
package main import ( "encoding/base64" "encoding/json" "errors" "flag" "fmt" "github.com/gorilla/websocket" "io/ioutil" "net/http" "net/url" "os" "time" ) type AuthInfo struct { AccessToken string `json:"access_token"` ExpiresIn int `json:"expires_in"` Scope string `json:"scope"` } type ReqParams struct { AudioData string `json:"audio_data"` AudioFormat string `json:"audio_format"` SampleRate int `json:"sample_rate"` ReqIdx int `json:"req_idx"` Domain string `json:"domain,omitempty"` AddPct bool `json:"add_pct"` Hotwordid string `json:"hotwordid,omitempty"` Diylmid string `json:"diylmid,omitempty"` EnableVad bool `json:"enable_vad"` MaxBeginSilence int `json:"max_begin_silence,omitempty"` MaxEndSilence int `json:"max_end_silence,omitempty"` } type WsReqParam struct { AccessToken string `json:"access_token"` Version string `json:"version"` Params ReqParams `json:"asr_params"` } type WsMsgData struct { ResIdx int `json:"res_idx"` Nbest []string `json:"nbest"` Uncertain []string `json:"uncertain"` EndFlag int `json:"end_flag"` } type WsMsg struct { Code int `json:"code"` Message string `json:"message"` TraceId string `json:"trace_id"` Data WsMsgData `json:"data"` } 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 RecvMsg(conn *websocket.Conn, chn chan error) { var err error for { msg := WsMsg{} err = conn.ReadJSON(&msg) if err != nil { fmt.Printf("websocket read json failed.\n") break } if msg.Code != 90000 { err = fmt.Errorf("error_code %d, msg: %s traceId: %s ", msg.Code, msg.Message, msg.TraceId) break } fmt.Printf("ResIdx:\t%d\nnbest:\t%v\n", msg.Data.ResIdx, msg.Data.Nbest) if len(msg.Data.Uncertain) > 0 { fmt.Printf("uncertain:\t%v\n", msg.Data.Uncertain) } fmt.Printf("endflag:\t%d\n\n", msg.Data.EndFlag) if msg.Data.EndFlag == 1 { break } } chn <- err } func SendAsr(urlStr, file string, reqParam WsReqParam) error { conn, _, err := websocket.DefaultDialer.Dial(urlStr, nil) if err != nil { fmt.Printf("websocket dial failed. url: %s\n", urlStr) return err } defer conn.Close() audioData, err := ioutil.ReadFile(file) if err != nil { fmt.Println("read file failed!!!") return err } // channel 等待返回使用 chn := make(chan error) // 开启接收websocket 消息 协程 go RecvMsg(conn, chn) for index := 0; index < len(audioData); index += 5120 { reqIdx := index / 5120 if index+5120 >= len(audioData) { reqIdx = -reqIdx audio := audioData[index:] reqParam.Params.AudioData = base64.StdEncoding.EncodeToString(audio) } else { audio := audioData[index : index+5120] reqParam.Params.AudioData = base64.StdEncoding.EncodeToString(audio) } reqParam.Params.ReqIdx = reqIdx fmt.Printf("send req_idx: %d\n", reqIdx) err = conn.WriteJSON(reqParam) if err != nil { fmt.Printf("websocket write json failed. url: %s\n", urlStr) chn <- err break } } fmt.Println("send audio data finish.") // 等待channel 返回 err = <-chn return err } func main() { var ( clientId, clientSecret, file, AudioFormat, domain, hotwordid, diylmid string SampleRate, maxBeginSilence, maxEndSilence int addPct, enableVad bool ) flag.StringVar(&clientId, "cid", "", "client id") flag.StringVar(&clientSecret, "cs", "", "client secret") flag.StringVar(&file, "f", "", "识别音频文件") flag.StringVar(&AudioFormat, "audio_format", "wav", "音频编码格式wav, pcm") flag.IntVar(&SampleRate, "sample_rate", 16000, "音频采样率8000, 16000") flag.StringVar(&domain, "domain", "", "模型名称") flag.BoolVar(&addPct, "add_pct", true, "加标点") flag.StringVar(&hotwordid, "hotwordid", "", "配置的热词组的id") flag.StringVar(&diylmid, "diylmid", "", "asr个性化模型的id") flag.BoolVar(&enableVad, "enable_vad", false, "静音检测") flag.Parse() if len(os.Args) < 2 { flag.Usage() return } if len(clientId) <= 0 || len(clientSecret) <= 0 || len(file) <= 0 || len(AudioFormat) <= 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 := WsReqParam{ AccessToken: accessToken, Version: "1.0", Params: ReqParams{ AudioFormat: AudioFormat, SampleRate: SampleRate, ReqIdx: 0, Domain: domain, AddPct: addPct, Hotwordid: hotwordid, Diylmid: diylmid, EnableVad: enableVad, MaxBeginSilence: maxBeginSilence, MaxEndSilence: maxEndSilence, }, } err = SendAsr("wss://openapi.data-baker.com/asr/wsapi", file, param) if err != nil { fmt.Printf("send websocket request failed. err: %s \n", err.Error()) return } fmt.Println("send websocket request success.") }
C示例代码
代码地址:Github
响应结果参数
参数名称 | 类型 | 描述 |
---|---|---|
code | int | 错误码4xxxx表示客户端参数错误,5xxxx表示服务端内部错误 |
message | string | 错误描述 |
trace_id | string | 任务id 用于定位错误跟踪日志 |
data | Object | 识别结果 |
data内部结构:
参数名称 | 类型 | 描述 |
---|---|---|
res_idx | int | 数据块序列号,请求内容会以流式的数据块方式返回给客户端。服务器端生成,从1递增 |
nbest | stringArray | 识别结果 |
end_flag | int | 是否是最后一个数据块,0:否,1:是 |
text | string | 语音识别结果,失败时为空 |
confidence | string | 整句置信度[0-100],值越大表示置信度越高。 |
speed | int | 语速,取值[0-2000] |
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": 90000, "data": { "confidence": "68.31", "end_flag": 1, "nbest": ["欢迎使用标贝科技开放平台。"], "res_idx": 20, "speed": 26, "speed_label": "MEDIUM", "text": "欢迎使用标贝科技开放平台。", "volume": 45, "volume_label": "SOFT", "words": [{ "confidence": "0.40", "eos": "0.51", "sos": "0.06", "word": "欢迎" }, { "confidence": "0.80", "eos": "1.05", "sos": "0.51", "word": "使用" }, { "confidence": "0.40", "eos": "1.52", "sos": "1.05", "word": "标贝" }, { "confidence": "1.00", "eos": "1.95", "sos": "1.52", "word": "科技" }, { "confidence": "0.50", "eos": "2.40", "sos": "1.95", "word": "开放" }, { "confidence": "1.00", "eos": "3.12", "sos": "2.40", "word": "平台" }] }, "message": "Success", "trace_id": "1652148314904999" }
错误码
错误码 | 描述 | 解决方案 |
---|---|---|
90000 | 文本数据 | |
90001 | 检测到音频 | 正常 |
90002 | 未检测到音频,超过最大开始静音时长 | 请检查音频有效长度,或者调整最大开始静音时长参数 |
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失败 | |
40001 | json解析失败 | 将请求序列化为json结构 |
40002 | json字段不全 | 检查对应的参数是否正确 |
40003 | 版本错误 | |
40004 | json字段值类型错误 | |
40005 | 参数错误 | |
40006 | idx超时 | 相邻idx间隔超过设置超时值(默认60s) |
40007 | idx顺序错误 | idx乱序 |
40008 | token校验失败 | |
40009 | token处于未激活状态 | 检查相应的client_id |
40010 | token已过期 | 重新获取token |
40011 | 使用量已超过购买量 | 检查相应的client_id |
40012 | qps错误 | 增大qps |
50001 | 处理超时 | |
50002 | 内部 rpc 调用失败 | |
50003 | 服务端繁忙 | |
50004 | 其他内部错误 | |
50005 | vad检测过程异常报错 | 服务内部错误,提交traceid,标贝后台进行排查。 |