使用OLAMI SDK和讯飞语音合成制作一个语音回复的短信小助手

2024-01-25 20:48

本文主要是介绍使用OLAMI SDK和讯飞语音合成制作一个语音回复的短信小助手,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

现代人的生活越来越离不开手机,但我们总会遇到一些时候不方便用手去操作,比如开车,玩游戏的时候。智能语音时代这种情况有了新的解决方案。本文介绍了一个使用OLAMI Android SDK进行语音识别和理解,讯飞在线语音合成sdk进行语音合成实现在收到短信时直接进行语音回复的demo开发过程。在此基础上我们也可以很方便的增加其他的功能,比如查新闻,百科等,完成一个DIY的语音助手。

简介

OLAMI

OLAMI是由威盛电子(上海)有限公司人工智能软件研发团队推出的一个人工智能软件开发平台,提供包括自然语音交互技术在内的全方位人机交互解决方案,覆盖了众多垂直领域的语义通用场景。

讯飞语音合成

科大讯飞提供的语音合成解决方案,解决的主要问题是如何将文字信息转化为可听的声音信息,也即“让机器像人一样开口说话”。

开始

整个demo很简单,主要流程就是:收到短信->播报短信->用户语音回复->发送短信。其中的关键就是用户语音回复的内容如何转换成发送短信的命令。

开发工具:Android Studio 2.3.3
OLAMI SDK版本: 2.0.0

获取OLAMI SDK的密钥

要使用OLAMI服务,需要先注册,地址是https://cn.olami.ai/open/website/register/register_data。注册过程很简单,之后绑定手机就可以使用了。

现在可以回到应用管理,点击查看Key,记录下App Key和App Secret,留待后面编写代码的时候使用。顺便提一下,点击配置模块,里面有一些预定义好的内置功能,默认勾选的有nonsense(聊天)、date(日历)和cyclopaedia(百科)这几个被勾上,作用我们后面再说。

新建OLAMI应用

注册完之后进入应用管理,就可以创建自己的应用了。创建完应用之后进入NLI系统可以编写语法。我们的应用准备支持重念和回复功能。所以添加对应的两句语法:

重说

回复

写完之后不要忘记发布:

发布

至此,我们在OLAMI平台的准备工作就已经完成,马上就将进入Android Studio开始编写代码。

新建Android工程

在Android Studio中新建一个工程,Target Devices选Phone and Tablet。Android SDK从API 19开始提供了新的获取新收到短信的方法,所以Minimum SDK选择API 19。然后一路Next到Finish。

接收收到短信事件

在manifest中添加接收和发送短信的权限:

<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />

由于这个应用中收到短信广播后,要回到Activity中进行后续的工作,我们选择了在Activity动态创建一个Broadcast receiver,并通过setSmsHandler将二者关联起来:

// 注册短信广播接收器
receiver = new SmsReceiver();
receiver.setSmsHandler(this);
IntentFilter filter = new IntentFilter();
filter.addAction(SMS_RECEIVED_ACTION);
registerReceiver(receiver, filter);

在receiver的onReceive方法中获得刚收到的短信内容:

SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(intent);

然后就可以解析短信的数据了。需要注意的是,号码如果直接送到tts去读,有可能会读成数量的形式(例如10086会读成一万零八十六),所以demo中在每个数字之间加入了空格。

收到短信后,要播报短信内容,并且要存储短信以便重听的时候使用。所以这里在MainActivity中实现了一个接口方便在Receiver中使用:

SmsReceiver.java

public interface SmsHandler {void processNewMsg(String phoneNumber, String content);
}

MainActivity.java

@Override
public void processNewMsg(String phoneNumber, String content) {StringBuilder finalAddress = new StringBuilder();// 播报号码中加入空格,以免读成数量for (int i = 0; i < phoneNumber.length(); i ++) {finalAddress.append(phoneNumber.charAt(i));finalAddress.append(' ');}String tts = String.format("收到来自%s的短信,内容是%s,你想回复什么?", finalAddress, content);speak(tts);// 记录短信内容number = phoneNumber;lastMsg = content;// 打开录音try {recognizer.start();} catch (InterruptedException e) {e.printStackTrace();}
}

播报短信

前面我们看到在processNewMsg中调用了speak方法来念出短信。这个例子中选择使用讯飞的在线语音合成api实现。讯飞语音合成的sdk同样需要注册,创建应用,完成后即可下载sdk。讯飞的知名度比较高,这里就不详细介绍过程了。

讯飞api的使用也很简单,按照sdk中的文档添加权限,把包放到响应的位置就可以开始编写代码了。首先在onCreate中初始化:

// 初始化讯飞服务。APPID注册讯飞平台,创建应用即可获得
SpeechUtility uti = SpeechUtility.createUtility(getApplicationContext(), SpeechConstant.APPID + "=595da10d");if (uti == null) {System.out.println("create Utility failed. ");
}tts = SpeechSynthesizer.createSynthesizer(getApplicationContext(), new InitListener() {@Overridepublic void onInit(int i) {System.out.println("tts初始化完成");tts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);tts.setParameter(SpeechConstant.ENGINE_MODE, SpeechConstant.MODE_AUTO);tts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");tts.setParameter(SpeechConstant.SPEED, "40");}
});

然后就可以使用了:

public void speak(String content) {tts.startSpeaking(content, new SynthesizerListener() {@Overridepublic void onSpeakBegin() {}@Overridepublic void onBufferProgress(int i, int i1, int i2, String s) {}@Overridepublic void onSpeakPaused() {}@Overridepublic void onSpeakResumed() {}@Overridepublic void onSpeakProgress(int i, int i1, int i2) {}@Overridepublic void onCompleted(SpeechError speechError) {}@Overridepublic void onEvent(int i, int i1, int i2, Bundle bundle) {}});
}

从代码里的linstener中我们可以看到讯飞提供了丰富的回调函数便于处理整个语音合成的过程。

至此我们就实现了收到短信播报的功能。

语音转语义

OLAMI SDK中提供了方便的接口(参考文档:OLAMI Android Client SDK & 示例代码),配置对应权限后,从打开录音到得到语义的整个过程都只需调用一个简单的start方法,之后在对应的回调函数中可以拿到结果。

与讯飞接口类似,首先在onCreate中初始化:

...// MainActivity的成员变量
RecorderSpeechRecognizer recognizer;
TextRecognizer textRecognizer;...// onCreate方法中// 初始化olami服务
// 创建 APIConfiguration 对象
APIConfiguration config = new APIConfiguration(KEY, SECRET, APIConfiguration.LOCALIZE_OPTION_SIMPLIFIED_CHINESE);
recognizer = RecorderSpeechRecognizer.create(this, config);
textRecognizer = new TextRecognizer(config);
// 下面为可选的设置
recognizer.setLengthOfVADEnd(2000);
textRecognizer.setEndUserIdentifier("Someone");
textRecognizer.setTimeout(1000);

RecorderSpeechRecognizer是语音识别引擎,TextRecognizer是文本识别引擎。TextRecognizer在这里用于模拟器测试,在不方便录音的情况下也能够做到短信收发。RecorderSpeechRecognizer.create方法的第一个参数是IRecorderSpeechRecognizerListener,这里直接在MainActivity中实现。这个Listener中也提供了很丰富的回调接口,涵盖了整个录音、识别、音量调节过程,很方便使用。

然后在Activity中放一个按钮(我这里叫Button2),点击事件中启动录音:

public void onButton2Click(View view) {RecorderSpeechRecognizer.RecordState recordState = recognizer.getRecordState();// Check to see if we should start recording or stop manually.if (recordState == RecorderSpeechRecognizer.RecordState.STOPPED) {try {// * Request to start voice recording and recognition.recognizer.start();} catch (InterruptedException e) {e.printStackTrace();}} else if (recordState == RecorderSpeechRecognizer.RecordState.RECORDING) {// * Request to stop voice recording when manually stop,//   and then wait for the final recognition result.recognizer.stop();}
}

之后就是在onRecognizeResultChange中处理结果:

@Override
public void onRecognizeResultChange(APIResponse response) {if (response.ok() && response.hasData()) {// 提取语音转文字识别结果//SpeechResult sttResult = response.getData().getSpeechResult();// 提取 NLI 语义或 IDS 数据if (response.getData().hasNLIResults()) {NLIResult[] nliResults = response.getData().getNLIResults();for (NLIResult result : nliResults) {if (result.getSemantics() != null && result.getSemantics().length > 0) {for (Semantic semantic : result.getSemantics()) {if (semantic.getAppModule().equals("sms")) {switch (semantic.getGlobalModifiers()[0]) {case "reply": {for (Slot slot : semantic.getSlots()) {if (slot.getName().equals("content")) {replyMsg(slot.getValue());return;}}}break;case "repeat": {repeatMsg();}default:break;}}}} else {speak(result.getDescObject().getReplyAnswer());}}}}
}

这里提到一个小插曲,在刚开始做这个demo的时候下载的OLAMI SDK还是1.0版jar包的方式,前两天发现SDK升级到了2.0版。2.0版的使用比旧版方便很多,只需在build.gradle中加上配置,就可以直接从gradle中央仓库获得。可见OLAMI官方代码的维护还是很勤快的。

回复短信

接下来只要实现replyMsg和repeatMsg就大功告成了:

public void replyMsg(String content) {if (number != null) {SmsManager.getDefault().sendTextMessage(number, null, content, null, null);speak("好的");} else {speak("我还不知道要发给谁。");}
}private void repeatMsg() {if (lastMsg != null) {speak(lastMsg);} else {speak("我不知道你想听的是哪条短信。");}
}

小结

总的来说OLAMI和讯飞两部分的SDK使用起来都很轻松方便,只要把任务交出去就能拿到结果。整个demo结构非常简单,实现了主要功能,但正式使用的话还需要很多改进,比如加上权限的判断,以免启动时报错退出;丰富OLAMI平台上的语法,以适应不同用户的不同说法等。

结束语

本文主要介绍了如何用OLAMI SDK和讯飞语音合成制作一个Android平台短信小助手的过程。通过对这些开放平台的使用,普通的开发者能够很快捷的实现语音、语义相关的功能。前面提到的OLAMI平台勾选的预置功能在最后也带来了很有意思的效果:本来预想一个简单的语音回复短信工具居然自带了聊天机器人的功能。如果我们对功能进行扩展,就能很快的为自己量身打造一个语音助手,这在几年前是很难想象的事情。

附录

* 本示例源代码 *

github:https://github.com/stdioh-cn/MessageDemo2

csdn下载频道:http://download.csdn.net/detail/speeds3/9899273

* 优秀自然语言理解博客文章推荐:*

根据OLAMI平台开发的日历Demo

用olami开放语义平台做汇率换算应用

自然语言处理-实际开发:用语义开放平台olami写一个翻译的应用

自定义java.awt.Canvas—趣味聊天

微信小程序+OLAMI自然语言API接口制作智能查询工具–快递、聊天、日历等

热门自然语言理解和语音API开发平台对比


* 自然语言理解开发爱好者博客汇总:*

http://blog.csdn.net/huangmeimao

http://blog.csdn.net/u011211290

http://blog.csdn.net/u011827504

http://blog.csdn.net/xinfinityx

http://blog.csdn.net/happycxz

这篇关于使用OLAMI SDK和讯飞语音合成制作一个语音回复的短信小助手的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/644559

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的