说到人工智能,离不开语音,大家会认为一个设备可以跟人对话是有智能的体现,在国内语音智能研发,讯飞是公认的做的最好的,在了解语音智能时,客户提的是讯飞,因为他们目标是要做一个好的语音交互。客户意向是讯飞,但是我还是要了解一下其他的语音SDK,后来着重了一下腾讯语音SDK,然后放弃了,因为使用了腾讯SDK,然后跟正在做SDK开发的 了解了一下,发现要有比较智能的语音,不能太依靠腾讯语音SDK,后台开发量有点大,客户主意向也是讯飞语音,在了解讯飞智能时,智能讯飞有个AIUI技能。
随着人工智能的不断发展,机器语音技术也越来越重要,本文就介绍了机器语音交互的讯飞AIUI技能。
今年讯飞把aiui跟讯飞语音分开,去年aiui的使用量还是跟讯飞语音一起,现在aiui技能成立一个独立模块。
实体:静态实体和动态实体,所见即可说
静态实体:直接在aiui开发平台的技能工作室的创建词条。
动态实体:应用动态上传,如一个连锁饭店菜谱不同店可能有些不一样,直接应用上传到指定的动态资源,然后可以调用对应的资源。
aiui应用级:应用级的动态函数,如李白是唐代诗人,所有用户的答案多是李白是唐代诗人。
aiui用户级:有时不同用户,同个实体对应的内容不一样,如拨打何小姐的电话,不同的人手机号码里的何小姐是对应不同的人。
自定义:自己定义,如果需要要用可调用,资源维度自己定义,资源名称和资源维度是唯一值,代入共有参数声明,不要随意使用。
所见即可说:
动态实体密钥:这应该是一个账号对应一个密钥,上传动态资源是必不可少的参数,可在实体里查看
副助词:一些辅助词,类似,了,啦,恩,嗯,怎么等
设备人设:可以设置人设,如我叫小兰,在调用aiui时,问你名字,答:我是小兰
我的技能:私有技能,开放技能
私有技能:智能自己的账户下的应用可以调用
开放技能:其他账户只要有口技,选择了技能,即可调用
意图:是技能一个功能模块,如播放音乐模块,拨打电话模块。
我的技能:
创建实体
动态资源的创建
自定义的创建资源名跟维度名后续上传内容时需要
技能创建根据你的需要选择对应的技能类型
进入创建好的技能,创建意图
创建语料:语音交互的一些模式
添加链接描述
保存构建技能
技能后处理
意图有追问等技能,但是有是需要更完善的处理,在技能后处理代码处理即可
技能后处理,然后发布。
如果有创建aiui应用,在应用的应用配置里选择创建的技能,即可调用该技能。
下载sdk,里面有一个vtn.ivw文件。这是语音唤醒的重要配置文件![在这里插入图片描述](https://img-blog.csdnimg.cn/fcc8c3dc1417402b970c70e71c5ed658.png#pic_center
mAIUI=AIUIAgent.createAgent(mContext,getAIUIPath(),mAIUIListener);
String getAIUIPath()
{
String params = "";
AssetManager assetManager = mContext.getResources().getAssets();
try {
InputStream ins = assetManager.open("cfg/aiui_phone.cfg");
byte[] buffer = new byte[ins.available()];
ins.read(buffer);
ins.close();
params = new String(buffer);
JSONObject paramsJson = new JSONObject(params);
mIsWakeupEnable = !"off".equals(paramsJson.optJSONObject("speech").optString("wakeup_mode"));
if(mIsWakeupEnable) {
FucUtil.copyAssetFolder(mContext, "ivw", "/sdcard/AIUI/ivw");
}
params = paramsJson.toString();
} catch (IOException | JSONException e) {
main.OnLogErroy("getAIUIPath:"+e.toString(),null);
}
}
AIUIListener mAIUIListener=new AIUIListener()
{
@RequiresApi(api= Build.VERSION_CODES.N)
@Override
public void onEvent(AIUIEvent aiuiEvent) {
switch (aiuiEvent.eventType)
{
case AIUIConstant.EVENT_CONNECTED_TO_SERVER:
tips="已连接服务器"+aiuiEvent.eventType ;
break;
case AIUIConstant.EVENT_SERVER_DISCONNECTED:
tips="与服务器断连"+aiuiEvent.eventType ;
break;
//唤醒事件
case AIUIConstant.EVENT_WAKEUP:
tips="进入识别状态"+aiuiEvent.eventType ;
try
{
JSONObject jsInfo = new JSONObject(aiuiEvent.info);
String ivwResult = jsInfo.getString("ivw_result");
JSONObject ivwInfo = new JSONObject(ivwResult);
String keyword = ivwInfo.getString("keyword");
tips="本次唤醒为:" + keyword;
OnAiuiTTS("主人好!请问有什么吩咐!");
}catch (JSONException e)
{
}
break;
}
}
}
代码如下(示例):
AIUIAgent mAIUI;
void OnCreadAiui()
{
AIUISetting.setSystemInfo(AIUIConstant.KEY_SERIAL_NUM, deviceId);//deviceId:设备唯一标识
mAIUI=AIUIAgent.createAgent(mContext,getAIUIPath(),mAIUIListener);
if(mAIUI==null)
main.OnLogErroy("创建AIUIAgent失败!",null);
else
{
main.OnlogTips("AIUIAgent已创建",null);
}
}
public void OnAiuiTTS(String str)
{
String ttsStr = str;//
byte[] ttsData=null;
try
{
ttsData = ttsStr.getBytes("utf-8");
}
catch (UnsupportedEncodingException e)
{
main.OnLogErroy(e.toString(),null);
}
StringBuffer params = new StringBuffer(); //构建合成参数
params.append("vcn=x_qige"); //合成发音人 如 x_qige:讯飞小哥哥
params.append(",speed=50"); //合成速度
params.append(",pitch=50"); //合成音调
params.append(",volume=50"); //合成音量(0~100)
//开始合成
AIUIMessage startTts = new AIUIMessage(AIUIConstant.CMD_TTS,AIUIConstant.START, 0, params.toString(), ttsData);
mAIUI.sendMessage(startTts);
}
该处使用的url网络请求的数据。
技能生成,调用
@SuppressLint("NewApi")
//data 上传数据:*** 注意格式每条数据按json格式生成如{"appName": "微信", "alias": "wechat", "extra": "xxx"} ,多条数据,数据直接是用换行符隔开
// 如
// {"appName": "微信", "alias": "wechat", "extra": "xxx"}
//{"appName": "新浪微博", "alias": "微博", "extra": "yyy"}
public AIUIMessage SynSchemaMessage(String data,String tag)
{
AIUIMessage message=null;
String dataStrBase64= null;
try
{
JSONObject syncJson=new JSONObject();
JSONObject paramJson=new JSONObject();
dataStrBase64 = Base64.encodeToString(data.getBytes("utf-8"),Base64.DEFAULT | Base64.NO_WRAP);
//region uid/appid aiui应用/用户动态数据上传
/* paramJson.put("id_name","uid"); // appid paramJson.put("id_name", "appid");
paramJson.put("res_name","OS10473887526.place_twen");
syncJson.put("param",paramJson);
syncJson.put("data", dataStrBase64);
byte[] syncData=syncJson.toString().getBytes("utf-8");
JSONObject tagJson=new JSONObject();
tagJson.put("tag","sync_pos");
AIUIMessage mesgage=new AIUIMessage(AIUIConstant.CMD_SYNC,AIUIConstant.SYNC_DATA_SCHEMA,0,tagJson.toString(),syncData);
aiui.SendMessage(mesgage);*/
//endregion
//region自定义技能
json.put("appid","xxxx");//xxx应用的appid
paramJson.put("id_name","xxx");//自定义资源维度
paramJson.put("id_value","xx");//xx:词条
paramJson.put("res_name","xxxx.x1");//xxxx:动态密钥 x1:资源名称
syncJson.put("param",json);
syncJson.put("data", dataStrBase64);
byte[] syncData=syncJson.toString().getBytes("utf-8");
//tag:自定义字符,方便查询上传成功与否
JSONObject tagJson=new JSONObject();
if(tag==null)
{
if(json.getString("tag")!=null)
tagJson.put("tag",tag);
else
tagJson.put("tag",json.get("id_name")+"tag");
}
else
tagJson.put("tag",tag);
message=new AIUIMessage(AIUIConstant.CMD_SYNC,AIUIConstant.SYNC_DATA_SCHEMA,0,tagJson.toString(),syncData);
aiui.SendMessage(message);
//endregion
// region 自定义生效[语音交互生效]
JSONObject params = new JSONObject();
JSONObject audioParams = new JSONObject();
//x1:资源名称 xx:词条
audioParams.put("pers_param", "{\"x1\":\"xxx\",\"appid\":\"\",\"x1\":\"xx\",\"uid\":\"\"}");
params.put("audioparams", audioParams);
message=new AIUIMessage(AIUIConstant.CMD_SET_PARAMS, 0 , 0, params.toString(), null);
aiui.SendMessage(message);
//endregion
return message;
}
catch (Exception e)
{
aiui.OnTips("SynErroy:"+e.toString());
}
return message;
}
//上传成功与否
AIUIListener mAIUIListener=new AIUIListener()
{
@RequiresApi(api= Build.VERSION_CODES.N)
@Override
public void onEvent(AIUIEvent aiuiEvent) {
switch (aiuiEvent.eventType)
{
case AIUIConstant.EVENT_CMD_RETURN:
if(AIUIConstant.CMD_SYNC==aiuiEvent.arg1)
{
int syncType=aiuiEvent.data.getInt("sync_dtype");
switch (syncType)
{
case AIUIConstant.SYNC_DATA_SCHEMA:
if(AIUIConstant.SUCCESS==aiuiEvent.arg2)
{
String sid=aiuiEvent.data.getString("sid");
String tag=aiuiEvent.data.getString("tag");
/* // 获取上传调用耗时,单位:ms
long timeSpent = aiuiEvent.data.getLong("time_spent", -1);*/
tips="上传成功,sid=" + sid+" tag="+tag;
main.OnlogTips("sid:"+sid,null);
SecondAPI se=new SecondAPI<PubulicDataApl.IFLYTELKAPI>(PubulicDataApl.IFLYTELKAPI.synSchema);
try {
JSONObject attribu = new JSONObject();
attribu.put("sid", sid);
attribu.put("tag", tag);
dial = new Dial(se, "json", attribu);
main.ASCallUnity(dial);
}
catch (JSONException e)
{
main.OnLogErroy(e.toString(),null);
}
}
else
{
main.OnLogErroy("上传失败,错误码:"+aiuiEvent.arg2,null);
}
break;
default:
tips="sync:"+syncType;
main.OnLogErroy(tips,null);
break;
}
}
case AIUIConstant.CMD_QUERY_SYNC_STATUS:
int syncType = aiuiEvent.data.getInt("sync_dtype");
if (AIUIConstant.SYNC_DATA_QUERY == syncType) {
String result = aiuiEvent.data.getString("result");
if (0 == aiuiEvent.arg2) {
try
{
JSONObject res=new JSONObject(result);
main.OnlogTips("查询结果:" + res.getString("sid")+"上传成功", null);
}
catch (JSONException e)
{
main.OnLogErroy(e.toString(),null);
}
main.OnlogTips("查询结果:" + result, null);
} else {
main.OnLogErroy("1数据状态查询出错:" + aiuiEvent.arg2 + ", result:" + result, null);
main.OnLogErroy( result,null);
}
}
break;
}
}
}
//上传成功后,官方说5分钟可以生效,在10s后,如果上传成功,可以查询是否生效
public void Query(String sid)
{
aiui.OnTips("Query:"+sid);
try
{
JSONObject paramsJson = new JSONObject();
paramsJson.put("sid", sid);
AIUIMessage querySyncMsg = new AIUIMessage(AIUIConstant.CMD_QUERY_SYNC_STATUS,AIUIConstant.SYNC_DATA_SCHEMA, 0,paramsJson.toString(), null);
aiui.SendMessage(querySyncMsg);
}catch (Exception e)
{
aiui.OnTips("QueryErroy:"+e.toString());
}
}
文档
String setParams = "{\"userparams\":{\"xxxx\":\"xxx\"}}"
AIUIMessage setMsg = new AIUIMessage(CMD_SET_PARAMS, 0 , 0, setParams, "");
mAgent.sendMessage(setMsg);
public void UnityCallTemi(String str)
{
}
public void ASCallUnity(String dial)
{
UnityPlayer.UnitySendMessage(UnityObj,"AsCallUnityEven",dial);
}
jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
void UnityCallASEven(string str)
{
try
{
jo.Call(str);
}
catch (Exception e)
{
OnTips(e.ToString(), false);
}
}
public void UnityCallASEven(string dial)
{
}