全部产品
阿里云办公

Java SDK 1.0

更新时间:2018-12-10 10:59:00

本文档为智能语音交互1.0,新用户请使用智能语音交互2.0

功能介绍

语音Java SDK提供一句话识别服务,提供将实时短语音转成文字的功能,可直接用于语音搜索类应用。

选择app_key

选择app_key

SDK下载地址

一句话识别Java SDK

压缩包内为java demo maven工程,sdk jar包在src/main/java/resources/目录下,sdk 的引入方式如下:

  1. <dependency>
  2. <groupId>com.alibaba.idst</groupId>
  3. <artifactId>nls-service-sdk</artifactId>
  4. <version>${project.version}</version>
  5. <scope>system</scope>
  6. <systemPath>${project.basedir}/src/main/resources/nls-service-sdk.jar</systemPath>
  7. </dependency>

用户使用IDE直接导入工程即可运行:

  • IDEA自带maven,直接导入工程即可运行;
  • Eclipse首先确定已经安装配置好maven插件,然后通过 File->import->Existing Maven Projects 的方式导入工程。

请注意:SDK内部不自带语音采集的功能,只提供将语音流与文字互转和语意识别的功能。

示例说明

SDK调用顺序

  1. 创建一个NlsClient的实例并调用init()方法来初始化客户端。

  2. 提取语音数据并创建语音识别请求,至少填写appKey及需要识别的语音数据的格式。创建一个NlsListener的实现类。

  3. 调用NlsClient的createNlsFuture(第2步中的listener实例作为入参之一,用来处理返回结果)方法获取future,通过future的sendVoice方法来发送语音数据并在listener中处理返回结果。

  4. 通过future的sendFinishSignal来结束语音文件的发送,ASR服务收到这个结束信号后,会返回处理结果。

  5. 如有多个识别需要,重复步骤2-4。

  6. 调用NlsClient的close()方法来关闭客户端并释放资源。

SDK调用注意事项

  1. NlsClient创建一次可以重复使用,每次创建消耗性能。

  2. NlsClient使用了netty的框架,创建时比较消耗时间和资源,但创建之后可以重复利用。建议调用程序将NlsClient的创建和关闭与程序本身的生命周期结合。

  3. 每一次调用语音识别请求时注入的NlsListener只对本次语音识别的生命周期负责。

  4. 每次调用createNlsFuture(NlsRequest req, com.alibaba.idst.nls.event.NlsListener listener)方法做语音识别和对话时,注入的listener只对本次识别起作用。其他的语音识别进程不会触发该listener。

  5. NlsRequest里面的语音格式请与语音文件的格式保持一致。目前SDK支持pcm和opu格式,opu格式请参考opus编解码文档进行压缩。

  6. SDK只会根据该格式来切分和发送语音文件,如果两个不一致,后续的一切都是错误的。

  7. NlsListener的实现类里面,处理返回结果的代码尽量耗时剪短,最好不要涉及I/O操作。

  8. NlsListener的实现类中的处理方法是在NlsClient的语音识别线程中调用的,太长的操作时间导致线程不能及时释放会影响其他识别进程的顺利进行,同时也会影响整个程序的loading。I/O操作应该禁止在该实现类中出现,最好使用触发的方式将操作转移到其他线程中去进行。

  9. 并发或多线程支持,如果需要在您的应用支持多个并发请求,请不要重复创建NlsClient对象。正确的做法是构建不同的NlsRequest对象,同时创建不同的NlsListener,并传入NlsRequest对象。这样就可以并发不同请求并且拿到正确的相应的结果。

重要接口说明

com.alibaba.idst.nls.NlsClient


语音sdk对外暴露的类,调用程序通过调用该类的init()、close()、createNlsFuture()等方法来打开、关闭或发送语音数据。

初始化NlsClient

public void init((boolean sslMode, int port)

  • 说明 初始化NlsClient,创建好websocket client factory
  • 参数

    • sslMode 是否采用ssl模式,一般设置为true
    • port 端口号,一般为443
  • 返回值 null

设置服务器地址

public void setHost(String host)

  • 说明 设置服务器地址
  • 参数

  • 返回值 null

实例化NlsFuture请求

public NlsFuture createNlsFuture(NlsRequest req, com.alibaba.idst.nls.event.NlsListener listener)

  • 说明 实例化NlsFuture请求,传入请求和监听器
  • 参数

    • req 请求对象
    • listener 回调数据的监听器
  • 返回值 future

关闭NlsClient

public void close()

  • 说明 关闭websocket client factory,释放资源
  • 参数

    null

  • 返回值 null

com.alibaba.idst.nls.event.NlsListener


语音识别是一个非常漫长的过程,为了不影响服务端的正常工作,语音sdk被设计成异步模式,调用程序将语音客户端建立好并将语音数据交给sdk后就可以离开。在收到语音数据之后的处理需要通过实现该接口来完成。每一个识别过程创建的时候都需要注入侦听者以响应语音识别的结果。

识别结果回调

void onMessageReceived(NlsEvent e);

  • 说明 识别结果回调
  • 参数

    • NlsEvent Nls服务结果的对象 识别结果在e.getResponse()中
  • 返回值 null

识别失败回调

void onOperationFailed(NlsEvent e);

  • 说明 识别失败回调
  • 参数

    • NlsEvent Nls服务结果的对象 错误信息在e.getErrorMessage()中
  • 返回值 null

socket 连接关闭的回调

void onChannelClosed(NlsEvent e);

  • 说明 socket 连接关闭的回调
  • 参数

    • NlsEvent Nls服务结果的对象
  • 返回值 null

com.alibaba.idst.nls.protocol.NlsRequest


语音识别的请求封装对象。调用程序需要至少在请求对象里设定好调用者的appKey和语音数据的格式以便后台服务能正确识别并识别语音。

初始化Nls 请求:NlsRequest mNlsRequest = new NlsRequest(proto)

public void setAppKey(String app_key)

  • 说明 设置应用的appkey,appkey需要先申请再使用。
  • 参数
    • app_key
  • 返回值 null

public void setAsrFormat(String sc)

  • 说明 设置语音识别的语音格式,一般为pcm。若使用opu格式的语音,请参考opus编解码文档说明进行编码设置。

    该项在使用语音识别服务时必须设置,起到初始化作用。

  • 参数
    • sc 一般为pcm。
  • 返回值 null

public void setAsrResposeMode(NlsRequestASR.mode mode)

  • 说明 设置asr识别结果的返回方式。

    默认为流式。

  • 参数
    • mode.STREAMING:逐词返回,流式效果;mode.NORMAL:逐句返回
  • 返回值 null

public void setAsrSampleRate(String sampleRate)

  • 说明 设置输入asr音频的采样率。

    默认为16 即16k采样率。

  • 参数
    • 可设置为8 或 16 分别代表8k,16k 采样率
  • 返回值 null

public void authorize(String id, String secret)

  • 说明 数加认证模块,所有的请求都必须通过authorize方法认证通过,才可以使用。 id和secret需要申请获取。
  • 参数
    • id 数加平台申请的Access Key ID。
    • secret 对应密钥Access Key Secret。
  • 返回值 null

public void setAsrVocabularyId(String vocabularyId)

  • 说明 设置词表id
  • 参数
    • id 热词使用
  • 返回值 null

com.alibaba.idst.nls.internal.protocol.NlsRequestProto


NlsRequest对象初始化时需要注入的参数。

public void setApp_id(String app_id)

  • 设置application_id.

public void setApp_user_id(String app_user_id)

  • 设置app_user_id.

com.alibaba.idst.nls.NlsFuture


NlsFuture是具体操作语音的对象类,语音数据的发送/接收都通过这个类进行操作。public NlsFuture sendVoice(byte[] data, int offset, int length)

  • 说明 语音识别时,发送语音文件的方法
  • 参数
    • data byte[]类型的语音流
    • offset
    • length
  • 返回值 NlsFuture

public NlsFuture sendFinishSignal()

  • 说明 语音识别结束时,发送结束符
  • 参数

  • 返回值 NlsFuture

public boolean await(int timeout)

  • 说明 请求超时时间
  • 参数
    • timeout 请求发送出去后,等待服务端结果返回的超时时间,单位ms
  • 返回值 true false

com.alibaba.idst.nls.protocol.NlsResponse


语音识别的返回结果封装对象。返回结果告知语音识别是否成功,语音识别结果或部分结果(视调用程序需要的返回方式而定),语音识别是否已经结束。

public String getAsr_ret()

  • 说明 获取语音识别的结果
  • 参数
    • null
  • 返回值 String

服务端返回结果说明

服务端返回错误码和返回结果详细字段解析请参考文档:服务端错误码和结果说明

完整示例

  1. package com.demo;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import com.alibaba.idst.nls.NlsClient;
  5. import com.alibaba.idst.nls.NlsFuture;
  6. import com.alibaba.idst.nls.event.NlsEvent;
  7. import com.alibaba.idst.nls.event.NlsListener;
  8. import com.alibaba.idst.nls.protocol.NlsRequest;
  9. import com.alibaba.idst.nls.protocol.NlsResponse;
  10. public class AsrDemo implements NlsListener {
  11. private static NlsClient client = new NlsClient();
  12. public AsrDemo() {
  13. System.out.println("init Nls client...");
  14. // 初始化NlsClient
  15. client.init();
  16. }
  17. public void shutDown() {
  18. System.out.println("close NLS client");
  19. // 关闭客户端并释放资源
  20. client.close();
  21. System.out.println("demo done");
  22. }
  23. public void startAsr() {
  24. //开始发送语音
  25. System.out.println("open audio file...");
  26. FileInputStream fis = null;
  27. try {
  28. String filePath = "src/main/java/resources/sample.pcm";
  29. File file = new File(filePath);
  30. fis = new FileInputStream(file);
  31. } catch (Exception e) {
  32. e.printStackTrace();
  33. }
  34. if (fis != null) {
  35. System.out.println("create NLS future");
  36. try {
  37. NlsRequest req = new NlsRequest();
  38. req.setAppKey("nls-service"); // appkey请从 "快速开始" 帮助页面的appkey列表中获取
  39. req.setAsrFormat("pcm"); // 此处可选值为pcm、opus, 支持wav格式文件,但必须是pcm编码,此处填pcm,注意不要填 wav
  40. /*热词相关配置*/
  41. //req.setAsrVocabularyId("Vocabulary_id"); // 热词词表id
  42. /*热词相关配置*/
  43. req.authorize("", ""); // 请替换为用户申请到的Access Key ID和Access Key Secret
  44. NlsFuture future = client.createNlsFuture(req, this); // 实例化请求,传入请求和监听器
  45. System.out.println("call NLS service");
  46. byte[] b = new byte[6400];
  47. int len = 0;
  48. /*
  49. 语音数据发送控制:
  50. 语音数据是实时的,不用sleep控制速率,直接发送即可;
  51. 语音数据来自文件,发送时需要控制速率,使单位时间内发送的数据大小接近单位时间原始语音数据存储的大小
  52. 对于8k pcm 编码数据,建议每发送3200字节sleep 200ms;
  53. 对于16k pcm 编码数据,建议每发送6400字节sleep 200ms;
  54. 对于其它编码格式的数据,用户根据压缩比,自行估算,比如压缩比为10:1的16k opus,需要每发送6400/10=640 sleep 200ms。
  55. */
  56. while ((len = fis.read(b)) > 0) {
  57. future.sendVoice(b, 0, len); // 发送语音数据
  58. Thread.sleep(200);
  59. }
  60. future.sendFinishSignal(); // 语音识别结束时,发送结束符
  61. System.out.println("main thread enter waiting for less than 10s.");
  62. future.await(10000); // 设置服务端结果返回的超时时间
  63. } catch (Exception e) {
  64. e.printStackTrace();
  65. }
  66. System.out.println("calling NLS service end");
  67. }
  68. }
  69. public void onMessageReceived(NlsEvent e) {
  70. // 识别结果的回调
  71. NlsResponse response = e.getResponse();
  72. String result = "";
  73. int statusCode = response.getStatus_code();
  74. if (response.getAsr_ret() != null) {
  75. result += "\nget asr result: statusCode=[" + statusCode + "], " + response.getAsr_ret(); // 识别结果
  76. }
  77. if (result != null) {
  78. System.out.println(result);
  79. } else {
  80. System.out.println(response.jsonResults.toString());
  81. }
  82. }
  83. @Override
  84. public void onOperationFailed(NlsEvent e) {
  85. // 识别失败的回调
  86. String result = "";
  87. result += "on operation failed: statusCode=[" + e.getResponse().getStatus_code() + "], " + e.getErrorMessage();
  88. System.out.println(result);
  89. }
  90. @Override
  91. public void onChannelClosed(NlsEvent e) {
  92. // socket 连接关闭的回调
  93. System.out.println("on websocket closed.");
  94. }
  95. public static void main(String[] args) {
  96. AsrDemo asrDemo = new AsrDemo();
  97. asrDemo.startAsr();
  98. asrDemo.shutDown();
  99. }
  100. }

注:请着重阅读代码注释中的“语音数据发送控制”部分。