全部产品
云市场

Java SDK

更新时间:2020-06-24 10:46:40

本文介绍了如何使用阿里云智能语音服务提供的Java SDK,包括SDK的安装方法及SDK代码示例。

注意事项

  • 在使用SDK前,请先阅读接口说明,详情请参见接口说明
  • 从2.1.0版本开始原有nls-sdk-short-asr 更名为nls-sdk-recognizer,升级时需确认已删除nls-sdk-short-asr,并按编译提示添加相应回调方法。

下载安装

从maven服务器下载最新版本SDK,下载demo源码ZIP包

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

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

服务验证

运行如下代码并按提示提供参数,运行后在命令执行目录生成logs/nls.log。

  1. java -cp nls-example-recognizer-2.0.0-jar-with-dependencies.jar com.alibaba.nls.client.SpeechRecognizerDemo

服务压测

运行如下代码并按提示提供参数,其中阿里云服务url参数为: wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1 ,语音文件为16k采样率PCM格式文件,并发数根据您已购买并发选择。

  1. java -jar nls-example-recognizer-2.0.0-jar-with-dependencies.jar

说明:自行压测超过2并发会产生费用。

关键接口

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

更多介绍,请参见Java API接口说明

SDK 调用注意事项

  • NlsClient使用了netty框架,NlsClient对象的创建会消耗一定时间和资源,一经创建可以重复使用。建议调用程序将NlsClient的创建和关闭与程序本身的生命周期结合。
  • SpeechRecognizer对象不可重复使用,一个识别任务对应一个SpeechRecognizer对象。例如,N个音频文件要进行N次识别任务,创建N个SpeechRecognizer对象。
  • SpeechRecognizerListener对象和SpeechRecognizer对象是一一对应的,不能将一个SpeechRecognizerListener对象设置到多个SpeechRecognizer对象中,否则不能将各识别任务区分开。
  • Java SDK依赖Netty网络库,如果您的应用依赖Netty,其版本需更新至4.1.17.Final及以上。

代码示例

说明:

  • Demo中使用的音频文件为16000Hz采样率,请在管控台中将appKey对应项目的模型设置为通用模型,以获取准确的识别效果。如果使用其他音频,请设置为支持该音频场景的模型,关于模型设置,请参见管理项目nls-sample-16k.wav
  • 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.SpeechRecognizer;
  8. import com.alibaba.nls.client.protocol.asr.SpeechRecognizerListener;
  9. import com.alibaba.nls.client.protocol.asr.SpeechRecognizerResponse;
  10. import org.slf4j.Logger;
  11. import org.slf4j.LoggerFactory;
  12. /**
  13. * 此示例演示了
  14. * ASR一句话识别API调用
  15. * 动态获取token
  16. * 通过本地文件模拟实时流发送
  17. * 识别耗时计算
  18. */
  19. public class SpeechRecognizerDemo {
  20. private static final Logger logger = LoggerFactory.getLogger(SpeechRecognizerDemo.class);
  21. private String appKey;
  22. NlsClient client;
  23. public SpeechRecognizerDemo(String appKey, String id, String secret, String url) {
  24. this.appKey = appKey;
  25. //应用全局创建一个NlsClient实例,默认服务地址为阿里云线上服务地址
  26. //获取token,实际使用时注意在accessToken.getExpireTime()过期前再次获取
  27. AccessToken accessToken = new AccessToken(id, secret);
  28. try {
  29. accessToken.apply();
  30. System.out.println("get token: " + accessToken.getToken() + ", expire time: " + accessToken.getExpireTime());
  31. if(url.isEmpty()) {
  32. client = new NlsClient(accessToken.getToken());
  33. }else {
  34. client = new NlsClient(url, accessToken.getToken());
  35. }
  36. } catch (IOException e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. private static SpeechRecognizerListener getRecognizerListener(int myOrder, String userParam) {
  41. SpeechRecognizerListener listener = new SpeechRecognizerListener() {
  42. //识别出中间结果。仅当setEnableIntermediateResult为true时,才会返回该消息
  43. @Override
  44. public void onRecognitionResultChanged(SpeechRecognizerResponse response) {
  45. //事件名称RecognitionResultChanged、状态码(20000000:识别成功)、getRecognizedText是语音识别文本
  46. System.out.println("name: " + response.getName() + ", status: " + response.getStatus() + ", result: " + response.getRecognizedText());
  47. }
  48. //识别完毕
  49. @Override
  50. public void onRecognitionCompleted(SpeechRecognizerResponse response) {
  51. //事件名称RecognitionCompleted、状态码(20000000:识别成功)、getRecognizedText是识别结果文本
  52. System.out.println("name: " + response.getName() + ", status: " + response.getStatus() + ", result: " + response.getRecognizedText());
  53. }
  54. @Override
  55. public void onStarted(SpeechRecognizerResponse response) {
  56. System.out.println("myOrder: " + myOrder + "; myParam: " + userParam + "; task_id: " + response.getTaskId());
  57. }
  58. @Override
  59. public void onFail(SpeechRecognizerResponse response) {
  60. //task_id是调用方和服务端通信的唯一标识,当遇到问题时,需要提供此task_id
  61. System.out.println("task_id: " + response.getTaskId() + ", status: " + response.getStatus() + ", status_text: " + response.getStatusText());
  62. }
  63. };
  64. return listener;
  65. }
  66. //根据二进制数据大小计算对应的同等语音长度
  67. //sampleRate仅支持8000或16000
  68. public static int getSleepDelta(int dataSize, int sampleRate) {
  69. // 仅支持16位采样
  70. int sampleBytes = 16;
  71. // 仅支持单通道
  72. int soundChannel = 1;
  73. return (dataSize * 10 * 8000) / (160 * sampleRate);
  74. }
  75. public void process(String filepath, int sampleRate) {
  76. SpeechRecognizer recognizer = null;
  77. try {
  78. //传递用户自定义参数
  79. String myParam = "user-param";
  80. int myOrder = 1234;
  81. SpeechRecognizerListener listener = getRecognizerListener(myOrder, myParam);
  82. recognizer = new SpeechRecognizer(client, listener);
  83. recognizer.setAppKey(appKey);
  84. //设置音频编码格式。如果是OPUS文件,请设置为InputFormatEnum.OPUS
  85. recognizer.setFormat(InputFormatEnum.PCM);
  86. //设置音频采样率
  87. if(sampleRate == 16000) {
  88. recognizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K);
  89. } else if(sampleRate == 8000) {
  90. recognizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_8K);
  91. }
  92. //设置是否返回中间识别结果
  93. recognizer.setEnableIntermediateResult(true);
  94. //此方法将以上参数设置序列化为json发送给服务端,并等待服务端确认
  95. long now = System.currentTimeMillis();
  96. recognizer.start();
  97. logger.info("ASR start latency : " + (System.currentTimeMillis() - now) + " ms");
  98. File file = new File(filepath);
  99. FileInputStream fis = new FileInputStream(file);
  100. byte[] b = new byte[3200];
  101. int len;
  102. while ((len = fis.read(b)) > 0) {
  103. logger.info("send data pack length: " + len);
  104. recognizer.send(b, len);
  105. //本案例用读取本地文件的形式模拟实时获取语音流,因为读取速度较快,这里需要设置sleep
  106. // 如果实时获取语音则无需设置sleep,如果是8k采样率语音第二个参数设置为8000
  107. int deltaSleep = getSleepDelta(len, sampleRate);
  108. Thread.sleep(deltaSleep);
  109. }
  110. //通知服务端语音数据发送完毕,等待服务端处理完成
  111. now = System.currentTimeMillis();
  112. //计算实际延迟,stop返回之后一般即是识别结果返回时间
  113. logger.info("ASR wait for complete");
  114. recognizer.stop();
  115. logger.info("ASR stop latency : " + (System.currentTimeMillis() - now) + " ms");
  116. fis.close();
  117. } catch (Exception e) {
  118. System.err.println(e.getMessage());
  119. } finally {
  120. //关闭连接
  121. if (null != recognizer) {
  122. recognizer.close();
  123. }
  124. }
  125. }
  126. public void shutdown() {
  127. client.shutdown();
  128. }
  129. public static void main(String[] args) throws Exception {
  130. String appKey = null; //填写appkey
  131. String id = null; //填写AccessKeyId
  132. String secret = null; //填写AccessKeySecret
  133. String url = ""; // 默认值:wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1
  134. if (args.length == 3) {
  135. appKey = args[0];
  136. id = args[1];
  137. secret = args[2];
  138. } else if (args.length == 4) {
  139. appKey = args[0];
  140. id = args[1];
  141. secret = args[2];
  142. url = args[3];
  143. } else {
  144. System.err.println("run error, need params(url is optional): " + "<app-key> <AccessKeyId> <AccessKeySecret> [url]");
  145. System.exit(-1);
  146. }
  147. SpeechRecognizerDemo demo = new SpeechRecognizerDemo(appKey, id, secret, url);
  148. //本案例使用本地文件模拟发送实时流数据
  149. demo.process("./nls-sample-16k.wav", 16000);
  150. //demo.process("./nls-sample.opus", 16000);
  151. demo.shutdown();
  152. }
  153. }