全部产品
云市场

Java SDK 2.0

更新时间:2019-10-11 14:16:45

提示:

  • 在使用SDK之前,请先确保已阅读了 接口说明文档
  • 从2.1.0版本开始原有nls-sdk-long-asr 更名为 nls-sdk-transcriber.升级时需确认删除掉nls-sdk-long-asr,并按编译提示添加相应回调方法即可。

下载安装

可从maven 服务器下载最新版本SDK:

  1. <dependency>
  2. <groupId>com.alibaba.nls</groupId>
  3. <artifactId>nls-sdk-transcriber</artifactId>
  4. <version>2.1.0</version>
  5. </dependency>

使用方式参见下面代码示例。Demo 源码下载链接

demo 解压后,在pom 目录运行mvn package ,会在target目录生成可执行jar nls-example-transcriber-2.0.0-jar-with-dependencies.jar 将此jar拷贝到目标服务器,可用于快速验证及压测服务。

服务验证

java -cp nls-example-transcriber-2.0.0-jar-with-dependencies.jar com.alibaba.nls.client.SpeechTranscriberDemo并按提示提供相应参数,运行后在命令执行目录生成logs/nls.log

服务压测

java -jar nls-example-transcriber-2.0.0-jar-with-dependencies.jar并按提示提供相应参数,其中阿里云服务url参数为: wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1 ,语音文件请提供16k采样率 pcm 格式文件,并发数根据用户已购买并发谨慎选择。

温馨提示:自行压测超过2并发会产生费用。

关键接口

  • NlsClient:语音处理client,相当于所有语音相关处理类的factory,全局创建一个实例即可。线程安全。
  • SpeechTranscriber:实时语音识别类,设置请求参数,发送请求及声音数据。非线程安全。
  • SpeechTranscriberListener:实时语音识别结果监听类,监听识别结果。非线程安全。

更多介绍参见API文档链接: Java API接口说明

SDK 调用注意事项

  1. NlsClient对象创建一次可以重复使用,每次创建消耗性能。NlsClient使用了netty的框架,创建时比较消耗时间和资源,但创建之后可以重复利用。建议调用程序将NlsClient的创建和关闭与程序本身的生命周期结合。
  2. SpeechTranscriber对象不能重复使用,一个识别任务对应一个SpeechTranscriber对象。例如有N个音频文件,则要进行N次识别任务,创建N个SpeechTranscriber对象。
  3. 实现的SpeechTranscriberListener对象和SpeechTranscriber对象是一一对应的,不能将一个SpeechTranscriberListener对象设置到多个SpeechTranscriber对象中,否则不能区分是哪个识别任务。
  4. Java SDK依赖了Netty网络库,版本需设置为4.1.17.Final及以上。如果您的应用中依赖了Netty,请确保版本符合要求。

代码示例

说明:Demo中使用的音频文件为16000Hz采样率,请在管控台中将appKey对应项目的模型设置为通用模型,以获取正确的识别结果;如果使用其他音频,请设置为支持该音频场景的模型,模型设置请阅读管理项目一节。

nls-sample-16k.wav

说明2:Demo中使用了SDK内置的默认实时语音识别服务的外网访问URL,如果您使用阿里云上海ECS并想使用内网访问URL,则在创建NlsClient对象时,设置内网访问的URL:

  1. client = new NlsClient("ws://nls-gateway.cn-shanghai-internal.aliyuncs.com/ws/v1", accessToken);

示例:

  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.IOException;
  4. import com.alibaba.nls.client.protocol.InputFormatEnum;
  5. import com.alibaba.nls.client.protocol.NlsClient;
  6. import com.alibaba.nls.client.protocol.SampleRateEnum;
  7. import com.alibaba.nls.client.protocol.asr.SpeechTranscriber;
  8. import com.alibaba.nls.client.protocol.asr.SpeechTranscriberListener;
  9. import com.alibaba.nls.client.protocol.asr.SpeechTranscriberResponse;
  10. import org.slf4j.Logger;
  11. import org.slf4j.LoggerFactory;
  12. /**
  13. * 此示例演示了
  14. * ASR实时识别API调用
  15. * 动态获取token
  16. * 通过本地模拟实时流发送
  17. * 识别耗时计算
  18. * (仅作演示,需用户根据实际情况实现)
  19. */
  20. public class SpeechTranscriberDemo {
  21. private String appKey;
  22. private NlsClient client;
  23. private static final Logger logger = LoggerFactory.getLogger(SpeechTranscriberDemo.class);
  24. public SpeechTranscriberDemo(String appKey, String id, String secret, String url) {
  25. this.appKey = appKey;
  26. //TODO 重要提示 创建NlsClient实例,应用全局创建一个即可,生命周期可和整个应用保持一致,默认服务地址为阿里云线上服务地址
  27. //TODO 这里简单演示了获取token 的代码,该token会过期,实际使用时注意在accessToken.getExpireTime()过期前再次获取token
  28. AccessToken accessToken = new AccessToken(id, secret);
  29. try {
  30. accessToken.apply();
  31. System.out.println("get token: " + ", expire time: " + accessToken.getExpireTime());
  32. // TODO 创建NlsClient实例,应用全局创建一个即可,用户指定服务地址
  33. if(url.isEmpty()) {
  34. client = new NlsClient(id, secret);
  35. }else {
  36. client = new NlsClient(url, accessToken.getToken());
  37. }
  38. } catch (IOException e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. private static SpeechTranscriberListener getTranscriberListener() {
  43. SpeechTranscriberListener listener = new SpeechTranscriberListener() {
  44. //TODO 识别出中间结果.服务端识别出一个字或词时会返回此消息.仅当setEnableIntermediateResult(true)时,才会有此类消息返回
  45. @Override
  46. public void onTranscriptionResultChange(SpeechTranscriberResponse response) {
  47. System.out.println("task_id: " + response.getTaskId() +
  48. ", name: " + response.getName() +
  49. //状态码 20000000 表示正常识别
  50. ", status: " + response.getStatus() +
  51. //句子编号,从1开始递增
  52. ", index: " + response.getTransSentenceIndex() +
  53. //当前的识别结果
  54. ", result: " + response.getTransSentenceText() +
  55. //当前已处理的音频时长,单位是毫秒
  56. ", time: " + response.getTransSentenceTime());
  57. }
  58. @Override
  59. public void onTranscriberStart(SpeechTranscriberResponse response) {
  60. // TODO 重要提示: task_id很重要,是调用方和服务端通信的唯一ID标识,当遇到问题时,需要提供此task_id以便排查
  61. System.out.println("task_id: " + response.getTaskId() + ", name: " + response.getName() + ", status: " + response.getStatus());
  62. }
  63. @Override
  64. public void onSentenceBegin(SpeechTranscriberResponse response) {
  65. System.out.println("task_id: " + response.getTaskId() + ", name: " + response.getName() + ", status: " + response.getStatus());
  66. }
  67. //识别出一句话.服务端会智能断句,当识别到一句话结束时会返回此消息
  68. @Override
  69. public void onSentenceEnd(SpeechTranscriberResponse response) {
  70. System.out.println("task_id: " + response.getTaskId() +
  71. ", name: " + response.getName() +
  72. //状态码 20000000 表示正常识别
  73. ", status: " + response.getStatus() +
  74. //句子编号,从1开始递增
  75. ", index: " + response.getTransSentenceIndex() +
  76. //当前的识别结果
  77. ", result: " + response.getTransSentenceText() +
  78. //置信度
  79. ", confidence: " + response.getConfidence() +
  80. //开始时间
  81. ", begin_time: " + response.getSentenceBeginTime() +
  82. //当前已处理的音频时长,单位是毫秒
  83. ", time: " + response.getTransSentenceTime());
  84. }
  85. //识别完毕
  86. @Override
  87. public void onTranscriptionComplete(SpeechTranscriberResponse response) {
  88. System.out.println("task_id: " + response.getTaskId() + ", name: " + response.getName() + ", status: " + response.getStatus());
  89. }
  90. @Override
  91. public void onFail(SpeechTranscriberResponse response) {
  92. // TODO 重要提示: task_id很重要,是调用方和服务端通信的唯一ID标识,当遇到问题时,需要提供此task_id以便排查
  93. System.out.println("task_id: " + response.getTaskId() + ", status: " + response.getStatus() + ", status_text: " + response.getStatusText());
  94. }
  95. };
  96. return listener;
  97. }
  98. /// 根据二进制数据大小计算对应的同等语音长度
  99. /// sampleRate 仅支持8000或16000
  100. public static int getSleepDelta(int dataSize, int sampleRate) {
  101. // 仅支持16位采样
  102. int sampleBytes = 16;
  103. // 仅支持单通道
  104. int soundChannel = 1;
  105. return (dataSize * 10 * 8000) / (160 * sampleRate);
  106. }
  107. public void process(String filepath) {
  108. SpeechTranscriber transcriber = null;
  109. try {
  110. //创建实例,建立连接
  111. transcriber = new SpeechTranscriber(client, getTranscriberListener());
  112. transcriber.setAppKey(appKey);
  113. //输入音频编码方式
  114. transcriber.setFormat(InputFormatEnum.PCM);
  115. //输入音频采样率
  116. transcriber.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K);
  117. //是否返回中间识别结果
  118. transcriber.setEnableIntermediateResult(false);
  119. //是否生成并返回标点符号
  120. transcriber.setEnablePunctuation(true);
  121. //是否将返回结果规整化,比如将一百返回为100
  122. transcriber.setEnableITN(false);
  123. //此方法将以上参数设置序列化为json发送给服务端,并等待服务端确认
  124. transcriber.start();
  125. File file = new File(filepath);
  126. FileInputStream fis = new FileInputStream(file);
  127. byte[] b = new byte[3200];
  128. int len;
  129. while ((len = fis.read(b)) > 0) {
  130. logger.info("send data pack length: " + len);
  131. transcriber.send(b);
  132. // TODO 重要提示:这里是用读取本地文件的形式模拟实时获取语音流并发送的,因为read很快,所以这里需要sleep
  133. // TODO 如果是真正的实时获取语音,则无需sleep, 如果是8k采样率语音,第二个参数改为8000
  134. int deltaSleep = getSleepDelta(len, 16000);
  135. Thread.sleep(deltaSleep);
  136. }
  137. //通知服务端语音数据发送完毕,等待服务端处理完成
  138. long now = System.currentTimeMillis();
  139. logger.info("ASR wait for complete");
  140. transcriber.stop();
  141. logger.info("ASR latency : " + (System.currentTimeMillis() - now) + " ms");
  142. } catch (Exception e) {
  143. System.err.println(e.getMessage());
  144. } finally {
  145. if (null != transcriber) {
  146. transcriber.close();
  147. }
  148. }
  149. }
  150. public void shutdown() {
  151. client.shutdown();
  152. }
  153. public static void main(String[] args) throws Exception {
  154. String appKey = "填写你的appkey";
  155. String id = "填写你在阿里云网站上的AccessKeyId";
  156. String secret = "填写你在阿里云网站上的AccessKeySecret";
  157. String url = ""; // 默认即可,默认值:wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1
  158. if (args.length == 3) {
  159. appKey = args[0];
  160. id = args[1];
  161. secret = args[2];
  162. } else if (args.length == 4) {
  163. appKey = args[0];
  164. id = args[1];
  165. secret = args[2];
  166. url = args[3];
  167. } else {
  168. System.err.println("run error, need params(url is optional): " + "<app-key> <AccessKeyId> <AccessKeySecret> [url]");
  169. System.exit(-1);
  170. }
  171. // TODO 重要提示: 这里用一个本地文件来模拟发送实时流数据,实际使用时,用户可以从某处实时采集或接收语音流并发送到ASR服务端
  172. String filepath = "nls-sample-16k.wav";
  173. SpeechTranscriberDemo demo = new SpeechTranscriberDemo(appKey, id, secret, url);
  174. demo.process(filepath);
  175. demo.shutdown();
  176. }
  177. }