文档

Java SDK

更新时间:
一键部署

本文介绍如何使用听悟开发套件提供的实时语音推流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)