本文介绍如何使用听悟开发套件提供的实时语音推流Java SDK,包括SDK的安装方法及SDK代码示例。
前提条件
在使用语音推流Java SDK之前,请先阅读开发参考。
下载安装
从Maven服务器下载听悟实时语音推流SDK。
<dependency>
<groupId>com.alibaba.nls</groupId>
<artifactId>nls-sdk-transcriber</artifactId>
<version>2.2.5</version>
</dependency>
示例代码
下载nls-sample-16k.wav。示例中使用的音频文件为16000Hz采样率。
说明
示例为读取本地文件模拟线下单路语音识别会议。
如场景为线上多路语音识别会议,可参考实时会议语音推流步骤2中protobuf的MultiAudioFrame数据结构构造每帧语音流。
package com.aliyun.sample;
import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriber;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriberListener;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriberResponse;
import java.io.File;
import java.io.FileInputStream;
public class SpeechTranscriberSample {
/**
* 创建实例
* @return
*/
public static NlsClient createClient() {
return new NlsClient("default");
}
/**
* 监听识别事件及识别结果
* @return
*/
public static SpeechTranscriberListener getTranscriberListener() {
SpeechTranscriberListener listener = new SpeechTranscriberListener() {
// 识别出中间结果。仅当RealtimeResultLevel=2时,才会返回该消息。
@Override
public void onTranscriptionResultChange(SpeechTranscriberResponse response) {
System.out.println("task_id: " + response.getTaskId() +
", name: " + response.getName() +
// 状态码“20000000”表示正常识别。
", status: " + response.getStatus() +
// 句子编号,从1开始递增。
", index: " + response.getTransSentenceIndex() +
// 当前的识别结果。
", result: " + response.getTransSentenceText() +
// 当前的词模式识别结果。
", words: " + response.getWords() +
// 当前已处理的音频时长,单位为毫秒。
", time: " + response.getTransSentenceTime());
}
@Override
public void onTranscriberStart(SpeechTranscriberResponse response) {
// task_id是调用方和服务端通信的唯一标识,遇到问题时,需要提供此task_id。
System.out.println("task_id: " + response.getTaskId() + ", name: " + response.getName() + ", status: " + response.getStatus());
}
@Override
public void onSentenceBegin(SpeechTranscriberResponse response) {
System.out.println("task_id: " + response.getTaskId() + ", name: " + response.getName() + ", status: " + response.getStatus());
}
//识别出一句话。服务端会智能断句,当识别到一句话结束时会返回此消息。
@Override
public void onSentenceEnd(SpeechTranscriberResponse response) {
System.out.println("task_id: " + response.getTaskId() +
", name: " + response.getName() +
// 状态码“20000000”表示正常识别。
", status: " + response.getStatus() +
// 句子编号,从1开始递增。
", index: " + response.getTransSentenceIndex() +
// 当前的识别结果。
", result: " + response.getTransSentenceText() +
// 当前的词模式识别结果。
", words: " + response.getWords() +
// 开始时间
", begin_time: " + response.getSentenceBeginTime() +
// 当前已处理的音频时长,单位为毫秒。
", time: " + response.getTransSentenceTime());
}
//识别完毕
@Override
public void onTranscriptionComplete(SpeechTranscriberResponse response) {
System.out.println("task_id: " + response.getTaskId() + ", name: " + response.getName() + ", status: " + response.getStatus());
}
@Override
public void onFail(SpeechTranscriberResponse response) {
//task_id是调用方和服务端通信的唯一标识,遇到问题时,需要提供此task_id。
System.out.println("task_id: " + response.getTaskId() + ", status: " + response.getStatus() + ", status_text: " + response.getStatusText());
}
};
return listener;
}
/**
* 根据二进制数据大小计算对应的同等语音长度。
* sampleRate:16000。
* @param dataSize
* @return
*/
public static int getSleepDelta(int dataSize) {
return dataSize / (2 * 16000 / 1000);
}
/**
* 与服务端建立WebSocket长连接
* @param nlsClient
* @param meetingJoinUrl
* @return
*/
public static SpeechTranscriber startTranscriber(NlsClient nlsClient, String meetingJoinUrl) {
SpeechTranscriber transcriber = null;
try {
transcriber = new SpeechTranscriber(nlsClient, "default", getTranscriberListener(), meetingJoinUrl);
// 暂停再继续识别,且在创建会议时设置了AudioOutputEnabled为false或未设置时,需要设置继续识别的会议时间偏移(单位毫秒)
// transcriber.addCustomedParam("tw_time_offset", xxx);
// 在启动识别前可进行翻译配置修改
// addTranslateConfigOnStart(speechTranscriber, true, "en");
// 发送开始识别指令给服务端,并等待服务端确认。
transcriber.start();
} catch (Exception e) {
// 如有需要,请打印 error
}
return transcriber;
}
public static void process(SpeechTranscriber transcriber, byte[] data, int length) {
transcriber.send(data, length);
}
public static void stopTranscriber(SpeechTranscriber transcriber) {
if (transcriber != null) {
try {
transcriber.stop();
} catch (Exception error) {
// 如有需要,请打印 error
} finally {
transcriber.close();
}
}
}
public static void main(String[] args) throws Exception {
// 本案例使用本地文件模拟发送实时流数据。您在实际使用时,可以实时采集或接收语音流并发送到服务端。
String filepath = "nls-sample-16k.wav";
String meetingJoinUrl = "调用创建会议接口返回的会议语音推流地址";
NlsClient nlsClient = createClient();
SpeechTranscriber transcriber = SpeechTranscriberSample.startTranscriber(nlsClient, meetingJoinUrl);
File file = new File(filepath);
FileInputStream fis = new FileInputStream(file);
byte[] data = new byte[3200];
int length;
while ((length = fis.read(data)) > 0) {
System.out.println("send data pack length: " + length);
SpeechTranscriberSample.process(transcriber, data, length);
// 本案例用读取本地文件的形式模拟实时获取语音流并发送的,因为读取速度较快,这里需要设置sleep。
// 如果实时获取语音则无需设置sleep
int deltaSleep = getSleepDelta(length);
Thread.sleep(deltaSleep);
// 在识别过程中可按需进行翻译配置修改,注意不要循环调用,该处仅为示例在语音推流过程中可进行调用
// sendTranslateConfigUpdateDirective(speechTranscriber, true, "en");
}
//通知服务端语音数据发送完毕,等待服务端处理完成。
long now = System.currentTimeMillis();
System.out.println("ASR wait for complete");
SpeechTranscriberSample.stopTranscriber(transcriber);
System.out.println("ASR latency : " + (System.currentTimeMillis() - now) + " ms");
}
// translateResultEnabled、translateLanguages参数说明与CreateMeetingTrans接口同名参数一致
public void addTranslateConfigOnStart(SpeechTranscriber speechTranscriber, boolean translateResultEnabled, String translateLanguages) {
if (translateResultEnabled) {
speechTranscriber.addCustomedParam("translate_result_enabled", true);
speechTranscriber.addCustomedParam("translate_languages", translateLanguages);
} else {
speechTranscriber.addCustomedParam("translate_result_enabled", false);
}
}
// translateResultEnabled、translateLanguages参数说明与CreateMeetingTrans接口同名参数一致
public void sendTranslateConfigUpdateDirective(SpeechTranscriber speechTranscriber, boolean translateResultEnabled, String translateLanguages) {
Map<String, Object> directive = new HashMap<>();
Map<String, Object> header = new HashMap<>();
header.put("name", "UpdateConfig");
directive.put("header", header);
Map<String, Object> payload = new HashMap<>();
payload.put("instruction_id", UUID.randomUUID().toString()); // 设置该参数后,发送指令后会收到UpdateConfigACK消息,消息定义见文档目录“开发参考”部分
if (translateResultEnabled) {
payload.put("translate_result_enabled", true);
payload.put("translate_languages", translateLanguages);
} else {
payload.put("translate_result_enabled", false);
}
directive.put("payload", payload);
String directiveJsonString = JSON.toJSONString(directive); // 自行调用JSON库把Map转成JSON字符串
speechTranscriber.getConnection().sendText(directiveJsonString);
}
}
反馈
- 本页导读 (0)
文档反馈