一句话识别Restful API
功能介绍
识别不超过60s的语音,适用于语音交互、控制口令、对话聊天等场景。
音频要求
- 时长限制:60秒以内
- 支持音频格式:wav,pcm
- 音频采样率:8000Hz,16000Hz
- 位深:16bits
- 声道:单声道
使用方法
1. 创建账号和应用,详见平台新手指引,通过标贝开放平台/应用/服务获取client_id,client_secret
2. 发送请求获取access_token,详见获取访问令牌
3. 发送识别请求:按照请求说明发送请求,具体参数详见请求参数。
6. 接收返回结果:发送请求成功后会立即收到返回响应,采用JSON格式封装,识别结果在“text"字段内,具体参数定义详见响应识别结果。
服务地址
访问类型 | 说明 | URL | Host |
---|---|---|---|
外网访问 | 支持中文普通话、中英自由说、英文、粤语、维语 | https://openapi.data-baker.com/asr/api? | openapi.data-baker.com |
交互流程

请求参数
2. 请求headers
参数名称 | 名称 | 是否必填项 | 说明 |
---|---|---|---|
access_token | string | yes | 通过client_id,client_secret调用授权服务获得见获取访问令牌 |
audio_format | string | yes | 音频编码格式 wav pcm |
sample_rate | integer | yes | 音频采样率 8000 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’: 关闭 |
HTTP请求体为二进制音频数据
测试音频
请求示例
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/api?"
Python示例代码
代码地址:Github
Python3示例:
#!/usr/bin/env python # coding: utf-8 import requests import json import argparse # 获取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(e) return else: access_token = json.loads(response.text).get('access_token') return access_token # 获取识别后文本 def get_text(file, headers): url = "https://openapi.data-baker.com/asr/api?" response = requests.post(url, data=file, headers=headers) code = json.loads(response.text).get("code") text = json.loads(response.text).get("text") if code != 20000: print(response.text) return text # 获取命令行输入参数 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') parser.add_argument('--add_pct', type=str, default='true') args = parser.parse_args() return args if __name__ == '__main__': args = get_args() # 获取access_token client_secret = args.client_secret client_id = args.client_id access_token = get_access_token(client_secret, client_id) # 读取音频文件 with open(args.file_path, 'rb') as f: file = f.read() # 填写Header信息 audio_format = args.audio_format sample_rate = args.sample_rate add_pct = args.add_pct headers = {'access_token': access_token, 'audio_format': audio_format, 'sample_rate': sample_rate, 'add_pct': add_pct} text = get_text(file, headers) print(text)
命令行执行: 默认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
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 = 'https://openapi.data-baker.com/asr/api?'; //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_TIMEOUT, 60); // 识别时长不超过原始音频 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); $text = $audio_info['text']; //获取识别出的文本内容 var_dump($text);die;
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_word_api_restful】 * <p> * 注意:仅作为demo示例,失败重试、token过期重新获取、日志打印等优化工作需要开发者自行完成 * * @author data-baker */ public class AsrRestApiDemo { /** * 授权:需要在开放平台获取【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 asrUrl = "https://openapi.data-baker.com/asr/api"; /** * 音频文件 */ public static String audioPath = "/home/asr/16bit_16k.pcm"; /** * 文件大小限制:开发者需注意服务端会校验音频时长不超过60S。demo作为示例,简化为只校验文件大小 * * @param args */ public static Integer MAX_FILE_SIZE = 10 * 1024 * 1024; public static void main(String[] args) { String accessToken = getAccessToken(); if (StringUtils.isNotEmpty(accessToken)) { File audioFile = new File(audioPath); //一句话在线识别支持的音频长度在60S内,开发者需注意音频流的大小 if (audioFile.exists() && audioFile.length() < MAX_FILE_SIZE) { //支持pcm和wav格式:如果是wav格式,audioFormat设置为"wav";如果是pcm格式,audioFormat设置为"pcm" doSpeechRecognition(accessToken, audioFile, "pcm", 16000); } } } public static void doSpeechRecognition(String accessToken, File audioFile, String audioFormat, Integer sampleRate) { try { OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/octet-stream"); FileInputStream in = new FileInputStream(audioFile); byte[] fileByte = new byte[(int) audioFile.length()]; int realLen = in.read(fileByte); //确保音频文件内容全部被读取 if (realLen == (int) audioFile.length()) { RequestBody body = RequestBody.create(mediaType, fileByte); //构造request Request request = new Request.Builder() .url(asrUrl) .addHeader("access_token", accessToken) .addHeader("audio_format", audioFormat) .addHeader("sample_rate", String.valueOf(sampleRate)) .addHeader("domain", "common") .method("POST", body) .build(); Response response = client.newCall(request).execute(); if (response.isSuccessful()) { JSONObject jsonObject = JSON.parseObject(response.body().string()); System.out.println("识别成功,识别结果:" + (jsonObject == null ? "" : jsonObject.getString("text"))); } 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; } }
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 ReqParams struct { AccessToken string AudioFormat string SampleRate int domain string addPct string hotwordId string diylmId string } type Response struct { Code int `json:"code"` Text string `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 SendAsr(reqUrl, file string, reqParam ReqParams) (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.addPct) > 0 { req.Header.Add("add_pct", reqParam.addPct) } if len(reqParam.hotwordId) > 0 { req.Header.Add("hotwordid", reqParam.hotwordId) } if len(reqParam.diylmId) > 0 { req.Header.Add("diylmid", reqParam.diylmId) } 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 string(result), err } if 20000 == response.Code { return response.Text, nil } return string(result), nil } func main() { var ( clientId, clientSecret, file string ) param := ReqParams{} flag.StringVar(&clientId, "cid", "", "client id") flag.StringVar(&clientSecret, "cs", "", "client secret") flag.IntVar(¶m.SampleRate, "sample_rate", 16000, "sample_rate: 8000, 16000") flag.StringVar(¶m.domain, "domain", "common", "domain") flag.StringVar(¶m.AudioFormat, "audio_format", "wav", "音频编码格式 wav, pcm") flag.StringVar(¶m.addPct, "add_pct", "true", "add_pct true: 加标点,默认值. false:不添加标点") flag.StringVar(¶m.hotwordId, "hotwordid", "", "配置的热词组的id") flag.StringVar(¶m.diylmId, "diylmid", "", "asr个性化模型的id") flag.StringVar(&file, "f", "", "需要识别的音频文件") flag.Parse() if len(os.Args) < 2 { flag.Usage() return } if len(clientId) <= 0 || len(clientSecret) <= 0 || len(file) <= 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.AccessToken = accessToken result, err := SendAsr("https://openapi.data-baker.com/asr/api?", file, param) if err != nil { fmt.Printf("send http request failed. result: %s \n", result) return } fmt.Printf("send http request success. result: %s\n", result) }
C示例代码
代码地址:Github
响应结果参数
字段名 | 类型 | 描述 |
---|---|---|
trace_id | string | 任务id,如遇到问题,可反馈此id给开发,用于跟踪问题 |
code | int | 请求结果码,请参考错误码一节 |
sid | string | 会话id |
text | string | 语音识别结果,失败时为空 |
info | 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": 20000, "confidence": "68.31", "info": "Success", "sid": "d0b28d23-49f3-46d8-80f1-b4e1cbfec496", "speed": 26, "speed_label": "MEDIUM", "text": "欢迎使用标贝科技开放平台。", "trace_id": "1652148140911063", "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": "平台" }] }
错误码
code | 描述 | 处理建议 |
---|---|---|
20000 | 请求成功 | |
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 | 无效的token | 检查对应的header参数是否正确 |
40002 | 无效的头部参数(或未被授权) | |
40005 | 不支持的audio_format | |
40006 | 不支持的sample_rate | |
40007 | 缺少body | 上传有效的body |
40009 | 账号处于未激活状态 | 检查账号状态 |
40010 | 账号已过期 | |
40011 | 购买调用量已耗尽 | |
40012 | 超过qps限制 | 升级qps |
40015 | 请求体长度过大 | 检查发送音频长度和大小 |
50002 | 内部rpc调用失败 | |
50009 | 其他内部错误 |
- 功能介绍
- 音频要求
- 使用方法
- 服务地址
- 交互流程
- 请求参数
- 测试音频
- 请求示例
- Python示例代码
- PHP示例代码
- JAVA示例代码
- GO示例代码
- C示例代码
- 响应结果参数
- 响应结果示例
- 错误码