全部产品

RESTful API

更新时间:2017-07-28 15:08:02   分享:   

1. 简介

短语音识别REST API支持以POST方式整段上传长度不多于一分钟的语音文件。识别结果将以JSON格式在请求响应中一次性返回,开发者需保证在识别结果返回前连接不被中断。

2. 选取语音模型和编码格式

开发者需要根据自身应用场景选取合适的语音模型。不同的语音模型对应不同的编码与数据格式,并在特定的场景下获得更高的识别准确度。

语音模型 语言 采样率 适用场景
customer-service-8k 中文 8KHz 客服对话
customer-service 中文 16KHz 客服对话
chat 中文 16KHz 社交聊天
entertainment 中文 16KHz 家庭娱乐
shopping 中文 16KHz 电商购物
english 英文 16KHz 英文转写

3. 上传语音文件

  • 短语识别请求实例
  1. POST https://nlsapi.aliyun.com/recognize?model=chat
  2. Authorization: Dataplus *****
  3. Content-type: audio/pcm; samplerate=16000
  4. Accept: application/json
  5. Date: Sat, 11 Mar 2017 08:33:32 GMT
  6. Content-Length: *
  7. [audio data]

一个完整的语音识别请求需包含以下要素:

3.1 URL

协议 URL 方法
HTTPS https://nlsapi.aliyun.com/recognize POST

3.2 输入参数

名称 类型 需求 描述
version String 必填 目前的版本号是”2.0”
model String 必填 语音模型,详见 2

3.3 HTTP Header Field

名称 类型 需求 描述
Authorization String 必填 鉴权, 详见 3.3.1
Content-type String 必填 必须以audio/开头,标明编码类型与抽样率,详见 3.3.2
Accept String 必填 识别结果返回格式,仅支持application/json
Date String 必填 鉴权,HTTP 1.1协议中规定的GMT时间,例如:Wed, 05 Sep. 2012 23:00:00 GMT
Content-Length Integer 必填 语音文件长度

3.3.1 Authorization Header

调用阿里巴巴智能语音交互平台的任何功能前都需经过严格的鉴权验证,参见“官方服务API校验规范”。在处理用户请求前,服务端会校验Authorization Header以确保用户请求在传输过程中没有被恶意篡改或替换。

  1. Authorization: Dataplus access_id:signature

Authorization以固定字符串Dataplus开头,开发者需要将从阿里云申请到的access_id和经过计算的signature以:分隔并以Base64编码后加入Header。

3.3.1.1 signature的计算

区别于标准的校验规范,计算signature需要首先对语音文件进行两次MD5和Base64编码。之后将编码结果与Reqeust MethodAcceptContent-TypeDate Header合并产生特征值。最终用阿里云取得的access_key对特征值进行HMAC-SHA1加密生成signature。

  1. // 1.对body做两次MD5+BASE64加密
  2. String bodyMd5 = MD5Base64(MD5Base64(body));
  3. // 2.特征值
  4. String feature = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date;
  5. // 2.对特征值HMAC-SHA1加密
  6. String signature = HMACSha1(feature, access_secret);
3.3.1.2 计算 MD5+BASE64
  1. public static String MD5Base64(String s) throws UnsupportedEncodingException {
  2. if (s == null)
  3. return null;
  4. String encodeStr = "";
  5. //string 编码必须为utf-8
  6. byte[] utfBytes = s.getBytes("UTF-8");
  7. MessageDigest mdTemp;
  8. try {
  9. mdTemp = MessageDigest.getInstance("MD5");
  10. mdTemp.update(utfBytes);
  11. byte[] md5Bytes = mdTemp.digest();
  12. BASE64Encoder b64Encoder = new BASE64Encoder();
  13. encodeStr = b64Encoder.encode(md5Bytes);
  14. } catch (Exception e) {
  15. throw new Error("Failed to generate MD5 : " + e.getMessage());
  16. }
  17. return encodeStr;
  18. }
3.3.1.3 计算 HMAC-SHA1
  1. public static String HMACSha1(String data, String key) {
  2. String result;
  3. try {
  4. SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
  5. Mac mac = Mac.getInstance("HmacSHA1");
  6. mac.init(signingKey);
  7. byte[] rawHmac = mac.doFinal(data.getBytes());
  8. result = (new BASE64Encoder()).encode(rawHmac);
  9. } catch (Exception e) {
  10. throw new Error("Failed to generate HMAC : " + e.getMessage());
  11. }
  12. return result;
  13. }

3.3.2 Content-Type Header

语音格式 编码 采样率
pcm pcm 16K/8K
wav pcm 16K/8K
opu 阿里优化opus 16K
opus 标准opus 16K
speex speex 16K

音频文件格式需要在HTTP Header的Content-Type中,如果没有以samplerate标明,采样率默认为16K。

  1. Content-Type: audio/wav; samplerate=8000

4. 识别结果返回

HTTP状态码200表示识别成功,请求结果以application/json格式在Response Body中返回;其他的HTTP错误码表示识别失败,具体的错误消息以application/json格式在Response Body中返回。

4.1 识别成功与识别失败

名称 类型 描述
request_id String 识别请求id
result String ASR识别结果
  • 识别成功实例
  1. {
  2. "request_id":"5552717cb25e4f64a180feecbe478889",
  3. "result":"测试五秒钟长度的语音"
  4. }

4.2 识别失败

名称 类型 描述
request_id String 识别请求id
error_code String 具体的错误代码
error_message String 具体的错误消息
  • 识别失败实例
  1. {
  2. "request_id":"5552717cb25e4f64a180feecbe478889",
  3. "error_code"80103,
  4. "error_message":"Failed to invoke auth service!"
  5. }

4.3 错误码定义

HTTP状态 status_code HTTP语义
请求格式有误 400 错误请求
鉴权失败 403 鉴权验证失败
无法接受 406 检查Accept类型,必须为application/json
请求超时 408 处理请求超时
超出最大并发量 429 太多请求
处理出错 500 服务器内部错误
服务不可用 503 服务不可用

5. 代码示例

5.1 请求DEMO

  1. package com.alibaba.idst.nls;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.io.UnsupportedEncodingException;
  5. import java.nio.file.FileSystem;
  6. import java.nio.file.FileSystems;
  7. import java.nio.file.Files;
  8. import java.nio.file.Path;
  9. import com.alibaba.fastjson.JSON;
  10. import com.alibaba.idst.nls.response.HttpResponse;
  11. import com.alibaba.idst.nls.utils.HttpUtil;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. public class HttpAsrDemo {
  15. private static Logger logger = LoggerFactory.getLogger(HttpAsrDemo.class);
  16. private static String url = "http://nlsapi.aliyun.com/recognize?";
  17. public static void main(String[] args) throws IOException {
  18. //请使用https://ak-console.aliyun.com/ 页面获取的Access 信息
  19. //请提前开通智能语音服务(https://data.aliyun.com/product/nls)
  20. String ak_id = args[0];
  21. String ak_secret = args[1];
  22. //使用对应的ASR模型 详情见文档部分2
  23. String model = "chat";
  24. url = url+"model="+model;
  25. //读取本地的语音文件
  26. Path path = FileSystems.getDefault().getPath("src/main/resources/demo.wav");
  27. byte[] data = Files.readAllBytes(path);
  28. HttpResponse response = HttpUtil.sendAsrPost(data,"pcm",16000,url,ak_id,ak_secret);
  29. logger.info(JSON.toJSONString(response));
  30. }
  31. }

5.2 请求服务的HttpUtil类

  1. package com.alibaba.idst.nls.utils;
  2. /**
  3. * Created by songsong.sss on 16/5/23.
  4. */
  5. import java.io.*;
  6. import java.net.HttpURLConnection;
  7. import java.net.URL;
  8. import java.security.MessageDigest;
  9. import java.text.SimpleDateFormat;
  10. import java.util.*;
  11. import javax.crypto.spec.SecretKeySpec;
  12. import com.alibaba.idst.nls.response.HttpResponse;
  13. import javax.crypto.Mac;
  14. import org.slf4j.Logger;
  15. import org.slf4j.LoggerFactory;
  16. import sun.misc.BASE64Encoder;
  17. @SuppressWarnings("restriction")
  18. public class HttpUtil {
  19. static Logger logger = LoggerFactory.getLogger(HttpUtil.class);
  20. /*
  21. * 计算MD5+BASE64
  22. */
  23. public static String MD5Base64(byte[] s) throws UnsupportedEncodingException {
  24. if (s == null){
  25. return null;
  26. }
  27. String encodeStr = "";
  28. //string 编码必须为utf-8
  29. MessageDigest mdTemp;
  30. try {
  31. mdTemp = MessageDigest.getInstance("MD5");
  32. mdTemp.update(s);
  33. byte[] md5Bytes = mdTemp.digest();
  34. BASE64Encoder b64Encoder = new BASE64Encoder();
  35. encodeStr = b64Encoder.encode(md5Bytes);
  36. /* java 1.8以上版本支持
  37. Encoder encoder = Base64.getEncoder();
  38. encodeStr = encoder.encodeToString(md5Bytes);
  39. */
  40. } catch (Exception e) {
  41. throw new Error("Failed to generate MD5 : " + e.getMessage());
  42. }
  43. return encodeStr;
  44. }
  45. /*
  46. * 计算 HMAC-SHA1
  47. */
  48. public static String HMACSha1(String data, String key) {
  49. String result;
  50. try {
  51. SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
  52. Mac mac = Mac.getInstance("HmacSHA1");
  53. mac.init(signingKey);
  54. byte[] rawHmac = mac.doFinal(data.getBytes());
  55. result = (new BASE64Encoder()).encode(rawHmac);
  56. /*java 1.8以上版本支持
  57. Encoder encoder = Base64.getEncoder();
  58. result = encoder.encodeToString(rawHmac);
  59. */
  60. } catch (Exception e) {
  61. throw new Error("Failed to generate HMAC : " + e.getMessage());
  62. }
  63. return result;
  64. }
  65. /*
  66. * 等同于javaScript中的 new Date().toUTCString();
  67. */
  68. public static String toGMTString(Date date) {
  69. SimpleDateFormat df = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.UK);
  70. df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));
  71. return df.format(date);
  72. }
  73. /*
  74. * 发送POST请求
  75. */
  76. public static HttpResponse sendAsrPost(byte[] audioData, String audioFormat, int sampleRate, String url,String ak_id, String ak_secret) {
  77. PrintWriter out = null;
  78. BufferedReader in = null;
  79. String result = "";
  80. HttpResponse response = new HttpResponse();
  81. try {
  82. URL realUrl = new URL(url);
  83. /*
  84. * http header 参数
  85. */
  86. String method = "POST";
  87. String accept = "application/json";
  88. String content_type = "audio/"+audioFormat+";samplerate="+sampleRate;
  89. int length = audioData.length;
  90. String date = toGMTString(new Date());
  91. // 1.对body做MD5+BASE64加密
  92. String bodyMd5 = MD5Base64(audioData);
  93. String md52 = MD5Base64(bodyMd5.getBytes());
  94. String stringToSign = method + "\n" + accept + "\n" + md52 + "\n" + content_type + "\n" + date ;
  95. // 2.计算 HMAC-SHA1
  96. String signature = HMACSha1(stringToSign, ak_secret);
  97. // 3.得到 authorization header
  98. String authHeader = "Dataplus " + ak_id + ":" + signature;
  99. // 打开和URL之间的连接
  100. HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
  101. // 设置通用的请求属性
  102. conn.setRequestProperty("accept", accept);
  103. conn.setRequestProperty("content-type", content_type);
  104. conn.setRequestProperty("date", date);
  105. conn.setRequestProperty("Authorization", authHeader);
  106. conn.setRequestProperty("Content-Length", String.valueOf(length));
  107. // 发送POST请求必须设置如下两行
  108. conn.setDoOutput(true);
  109. conn.setDoInput(true);
  110. // 获取URLConnection对象对应的输出流
  111. OutputStream stream = conn.getOutputStream();
  112. // 发送请求参数
  113. stream.write(audioData);
  114. // flush输出流的缓冲
  115. stream.flush();
  116. stream.close();
  117. response.setStatus(conn.getResponseCode());
  118. // 定义BufferedReader输入流来读取URL的响应
  119. if (response.getStatus() ==200){
  120. in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
  121. }else {
  122. in = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
  123. }
  124. String line;
  125. while ((line = in.readLine()) != null) {
  126. result += line;
  127. }
  128. if (response.getStatus() == 200){
  129. response.setResult(result);
  130. response.setMassage("OK");
  131. }else {
  132. response.setMassage(result);
  133. }
  134. System.out.println("post response status code: ["+response.getStatus()+"], response massage : ["+response.getMassage()+"] ,result :["+response.getResult()+"]");
  135. } catch (Exception e) {
  136. System.out.println("发送 POST 请求出现异常!" + e);
  137. e.printStackTrace();
  138. }
  139. // 使用finally块来关闭输出流、输入流
  140. finally {
  141. try {
  142. if (out != null) {
  143. out.close();
  144. }
  145. if (in != null) {
  146. in.close();
  147. }
  148. } catch (IOException ex) {
  149. ex.printStackTrace();
  150. }
  151. }
  152. return response;
  153. }
  154. /*
  155. * 发送POST请求
  156. */
  157. public static HttpResponse sendTtsPost(String textData,String audioType, String audioName,String url,String ak_id, String ak_secret) {
  158. PrintWriter out = null;
  159. BufferedReader in = null;
  160. String result = "";
  161. HttpResponse response = new HttpResponse();
  162. try {
  163. URL realUrl = new URL(url);
  164. /*
  165. * http header 参数
  166. */
  167. String method = "POST";
  168. String content_type = "text/plain";
  169. String accept = "audio/"+audioType+",application/json";
  170. int length = textData.length();
  171. String date = toGMTString(new Date());
  172. // 1.对body做MD5+BASE64加密
  173. String bodyMd5 = MD5Base64(textData.getBytes());
  174. // String md52 = MD5Base64(bodyMd5.getBytes());
  175. String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date ;
  176. // 2.计算 HMAC-SHA1
  177. String signature = HMACSha1(stringToSign, ak_secret);
  178. // 3.得到 authorization header
  179. String authHeader = "Dataplus " + ak_id + ":" + signature;
  180. // 打开和URL之间的连接
  181. HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
  182. // 设置通用的请求属性
  183. conn.setRequestProperty("accept", accept);
  184. conn.setRequestProperty("content-type", content_type);
  185. conn.setRequestProperty("date", date);
  186. conn.setRequestProperty("Authorization", authHeader);
  187. conn.setRequestProperty("Content-Length", String.valueOf(length));
  188. // 发送POST请求必须设置如下两行
  189. conn.setDoOutput(true);
  190. conn.setDoInput(true);
  191. // 获取URLConnection对象对应的输出流
  192. OutputStream stream = conn.getOutputStream();
  193. // 发送请求参数
  194. stream.write(textData.getBytes());
  195. // flush输出流的缓冲
  196. stream.flush();
  197. stream.close();
  198. response.setStatus(conn.getResponseCode());
  199. // 定义BufferedReader输入流来读取URL的响应
  200. InputStream is = null;
  201. String line = null;
  202. if (response.getStatus() ==200){
  203. is=conn.getInputStream();
  204. }else {
  205. in = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
  206. while ((line = in.readLine()) != null) {
  207. result += line;
  208. }
  209. }
  210. FileOutputStream fileOutputStream = null;
  211. File ttsFile = new File(audioName+"."+audioType);
  212. fileOutputStream = new FileOutputStream(ttsFile);
  213. byte[] b=new byte[1024];
  214. int len=0;
  215. while(is!=null&&(len=is.read(b))!=-1){ //先读到内存
  216. fileOutputStream.write(b, 0, len);
  217. }
  218. if (response.getStatus() == 200){
  219. response.setResult(result);
  220. response.setMassage("OK");
  221. System.out.println("post response status code: ["+response.getStatus()+"], generate tts audio file :" + audioName+"."+audioType);
  222. }else {
  223. response.setMassage(result);
  224. System.out.println("post response status code: ["+response.getStatus()+"], response massage : ["+response.getMassage()+"]");
  225. }
  226. } catch (Exception e) {
  227. System.out.println("发送 POST 请求出现异常!" + e);
  228. e.printStackTrace();
  229. }
  230. // 使用finally块来关闭输出流、输入流
  231. finally {
  232. try {
  233. if (out != null) {
  234. out.close();
  235. }
  236. if (in != null) {
  237. in.close();
  238. }
  239. } catch (IOException ex) {
  240. ex.printStackTrace();
  241. }
  242. }
  243. return response;
  244. }
  245. }

5.3 请求结果类

  1. package com.alibaba.idst.nls.response;
  2. public class HttpResponse {
  3. private int status;
  4. private String result;
  5. private String massage;
  6. public int getStatus() {
  7. return status;
  8. }
  9. public void setStatus(int status) {
  10. this.status = status;
  11. }
  12. public String getResult() {
  13. return result;
  14. }
  15. public void setResult(String result) {
  16. this.result = result;
  17. }
  18. public String getMassage() {
  19. return massage;
  20. }
  21. public void setMassage(String massage) {
  22. this.massage = massage;
  23. }
  24. }
本文导读目录
本文导读目录
以上内容是否对您有帮助?