阿里云智能语音交互实时语音识别Java SDK使用说明

简介: 实时语音识别功能提供了对长时间的语音数据流进行识别,适用于会议演讲、视频直播等长时间不间断识别的场景。。本文介绍如何使用阿里云智能语音服务提供的Java SDK,包括SDK的安装方法及SDK代码示例。

使用须知

  • 支持的输入格式:PCM(无压缩的PCM或WAV文件)、16 bit采样位数、单声道(mono)。
  • 音频采样率:8000Hz/16000Hz。
  • 支持设置返回结果:是否返回中间识别结果,在后处理中添加标点,将中文数字转为阿拉伯数字输出。
  • 设置多语言识别:在管控台编辑项目中进行模型选择,详情请参见管理项目

下载安装

1.导入Maven依赖文件

<dependency>    
      <groupId>com.alibaba.nls</groupId>  
      <artifactId>nls-sdk-transcriber</artifactId>   
      <version>2.2.1</version>
</dependency>

关键接口

  • NlsClient:语音处理客户端,利用该客户端可以进行一句话识别、实时语音识别和语音合成的语音处理任务。该客户端为线程安全,建议全局仅创建一个实例。
  • SpeechTranscriber:实时语音识别类,通过该接口设置请求参数,发送请求及声音数据。非线程安全。
  • SpeechTranscriberListener:实时语音识别结果监听类,监听识别结果。非线程安全。

代码示例

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import com.alibaba.nls.client.protocol.InputFormatEnum;
import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.SampleRateEnum;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 此示例演示了:
 * ASR实时识别API调用。
 * 动态获取token。
 * 通过本地模拟实时流发送。
 * 识别耗时计算。
 */
public class SpeechTranscriberDemo {
    private String appKey;
    private NlsClient client;
    private static final Logger logger = LoggerFactory.getLogger(SpeechTranscriberDemo.class);

    public SpeechTranscriberDemo(String appKey, String id, String secret, String url) {
        this.appKey = appKey;
        //应用全局创建一个NlsClient实例,默认服务地址为阿里云线上服务地址。
        //获取token,实际使用时注意在accessToken.getExpireTime()过期前再次获取。
        AccessToken accessToken = new AccessToken(id, secret);
        try {
            accessToken.apply();
            System.out.println("get token: " + ", expire time: " + accessToken.getExpireTime());
            if(url.isEmpty()) {
                client = new NlsClient(accessToken.getToken());
            }else {
                client = new NlsClient(url, accessToken.getToken());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static SpeechTranscriberListener getTranscriberListener() {
        SpeechTranscriberListener listener = new SpeechTranscriberListener() {
            //识别出中间结果。仅当setEnableIntermediateResult为true时,才会返回该消息。
            @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() +
                    //当前已处理的音频时长,单位为毫秒。
                    ", 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() +
                    //置信度
                    ", confidence: " + response.getConfidence() +
                    //开始时间
                    ", 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:支持8000或16000。
    public static int getSleepDelta(int dataSize, int sampleRate) {
        // 仅支持16位采样。
        int sampleBytes = 16;
        // 仅支持单通道。
        int soundChannel = 1;
        return (dataSize * 10 * 8000) / (160 * sampleRate);
    }

    public void process(String filepath) {
        SpeechTranscriber transcriber = null;
        try {
            //创建实例、建立连接。
            transcriber = new SpeechTranscriber(client, getTranscriberListener());
            transcriber.setAppKey(appKey);
            //输入音频编码方式。
            transcriber.setFormat(InputFormatEnum.PCM);
            //输入音频采样率。
            transcriber.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K);
            //是否返回中间识别结果。
            transcriber.setEnableIntermediateResult(false);
            //是否生成并返回标点符号。
            transcriber.setEnablePunctuation(true);
            //是否将返回结果规整化,比如将一百返回为100。
            transcriber.setEnableITN(false);

            //设置vad断句参数。默认值:800ms,有效值:200ms~2000ms。
            //transcriber.addCustomedParam("max_sentence_silence", 600);
            //设置是否语义断句。
            //transcriber.addCustomedParam("enable_semantic_sentence_detection",false);
            //设置是否开启顺滑。
            //transcriber.addCustomedParam("disfluency",true);
            //设置是否开启词模式。
            //transcriber.addCustomedParam("enable_words",true);
           //设置vad噪音阈值参数,参数取值为-1~+1,如-0.9、-0.8、0.2、0.9。
            //取值越趋于-1,判定为语音的概率越大,亦即有可能更多噪声被当成语音被误识别。
            //取值越趋于+1,判定为噪音的越多,亦即有可能更多语音段被当成噪音被拒绝识别。
            //该参数属高级参数,调整需慎重和重点测试。
            //transcriber.addCustomedParam("speech_noise_threshold",0.3);
            //设置训练后的定制语言模型id。
            //transcriber.addCustomedParam("customization_id","你的定制语言模型id");
            //设置训练后的定制热词id。
            //transcriber.addCustomedParam("vocabulary_id","你的定制热词id");
            //设置是否忽略单句超时。
            transcriber.addCustomedParam("enable_ignore_sentence_timeout",false);
            //vad断句开启后处理。
            //transcriber.addCustomedParam("enable_vad_unify_post",false);

            //此方法将以上参数设置序列化为JSON发送给服务端,并等待服务端确认。
            transcriber.start();

            File file = new File(filepath);
            FileInputStream fis = new FileInputStream(file);
            byte[] b = new byte[3200];
            int len;
            while ((len = fis.read(b)) > 0) {
                logger.info("send data pack length: " + len);
                transcriber.send(b, len);
                //本案例用读取本地文件的形式模拟实时获取语音流并发送的,因为读取速度较快,这里需要设置sleep。
                //如果实时获取语音则无需设置sleep, 如果是8k采样率语音第二个参数设置为8000。
                int deltaSleep = getSleepDelta(len, 16000);
                Thread.sleep(deltaSleep);
            }

            //通知服务端语音数据发送完毕,等待服务端处理完成。
            long now = System.currentTimeMillis();
            logger.info("ASR wait for complete");
            transcriber.stop();
            logger.info("ASR latency : " + (System.currentTimeMillis() - now) + " ms");
        } catch (Exception e) {
            System.err.println(e.getMessage());
        } finally {
            if (null != transcriber) {
                transcriber.close();
            }
        }
    }

    public void shutdown() {
        client.shutdown();
    }

    public static void main(String[] args) throws Exception {
        String appKey = "填写appkey";
        String id = "填写AccessKey Id";
        String secret = "填写AccessKey Secret";
        String url = "wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1"; // 默认值:wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1。

        //本案例使用本地文件模拟发送实时流数据。您在实际使用时,可以实时采集或接收语音流并发送到ASR服务端。
        String filepath = "文件.wav";
        SpeechTranscriberDemo demo = new SpeechTranscriberDemo(appKey, id, secret, url);
        demo.process(filepath);
        demo.shutdown();
    }
}

参考链接

实时语音识别接口说明

相关实践学习
达摩院智能语音交互 - 声纹识别技术
声纹识别是基于每个发音人的发音器官构造不同,识别当前发音人的身份。按照任务具体分为两种: 声纹辨认:从说话人集合中判别出测试语音所属的说话人,为多选一的问题 声纹确认:判断测试语音是否由目标说话人所说,是二选一的问题(是或者不是) 按照应用具体分为两种: 文本相关:要求使用者重复指定的话语,通常包含与训练信息相同的文本(精度较高,适合当前应用模式) 文本无关:对使用者发音内容和语言没有要求,受信道环境影响比较大,精度不高 本课程主要介绍声纹识别的原型技术、系统架构及应用案例等。 讲师介绍: 郑斯奇,达摩院算法专家,毕业于美国哈佛大学,研究方向包括声纹识别、性别、年龄、语种识别等。致力于推动端侧声纹与个性化技术的研究和大规模应用。
目录
相关文章
|
3月前
|
Java API 开发工具
百宝箱开放平台 ✖️ Java SDK
百宝箱提供Java SDK,支持开发者集成其开放能力。需先发布应用,准备Java 8+及Maven环境,通过添加依赖安装SDK,并初始化客户端调用对话型或生成型智能体,实现会话管理、消息查询与文件上传等功能。
1358 0
百宝箱开放平台 ✖️ Java SDK
|
7月前
|
存储 Java API
MinIO Java SDK 7.1.4 升级到 8.5.17 需要注意什么
现在我需要你帮我分析对比这个两个sdk在对外的接口设计上是否有不兼容的变更
617 5
|
Java Apache 开发工具
【Azure 事件中心】 org.slf4j.Logger 收集 Event Hub SDK(Java) 输出日志并以文件形式保存
【Azure 事件中心】 org.slf4j.Logger 收集 Event Hub SDK(Java) 输出日志并以文件形式保存
244 1
|
存储 Java API
【Azure 存储服务】Java Storage SDK 调用 uploadWithResponse 代码示例(询问ChatGTP得代码原型后人力验证)
【Azure 存储服务】Java Storage SDK 调用 uploadWithResponse 代码示例(询问ChatGTP得代码原型后人力验证)
175 0
|
弹性计算 安全 开发工具
灵码评测-阿里云提供的ECS python3 sdk做安全组管理
批量变更阿里云ECS安全组策略(批量变更)
|
程序员 开发工具 Android开发
Android|使用阿里云推流 SDK 实现双路推流不同画面
本文记录了一种使用没有原生支持多路推流的阿里云推流 Android SDK,实现同时推送两路不同画面的流的方法。
315 7
|
Java 开发工具
通过Java SDK调用阿里云模型服务
在阿里云平台上,可以通过创建应用并使用模型服务完成特定任务,如生成文章内容。本示例展示了一段简化的Java代码,演示了如何调用阿里云模型服务生成关于“春秋战国经济与文化”的简短文章。示例代码通过设置系统角色为历史学家,并提出文章生成需求,最终处理并输出生成的文章内容。在实际部署前,请确保正确配置环境变量中的密钥和ID,并根据需要调整SDK导入语句及类名。更多详情和示例,请参考相关链接。
|
JSON Java API
【Azure API 管理】通过Java APIM SDK创建一个新的API,如何为Reqeust的Representation设置一个内容示例(Sample)?
【Azure API 管理】通过Java APIM SDK创建一个新的API,如何为Reqeust的Representation设置一个内容示例(Sample)?
139 0
|
存储 Java 开发工具
【Azure 存储服务】Java Azure Storage SDK V12使用Endpoint连接Blob Service遇见 The Azure Storage endpoint url is malformed
【Azure 存储服务】Java Azure Storage SDK V12使用Endpoint连接Blob Service遇见 The Azure Storage endpoint url is malformed
215 0
|
开发工具 数据安全/隐私保护
【Azure Developer】使用MSAL4J 与 ADAL4J 的SDK时候,遇见了类型冲突问题 "java.util.Collections$SingletonList cannot be cast to java.lang.String"
【Azure Developer】使用MSAL4J 与 ADAL4J 的SDK时候,遇见了类型冲突问题 "java.util.Collections$SingletonList cannot be cast to java.lang.String"
312 0

热门文章

最新文章