讯飞语音唤醒SDK接入流程

本流程以Android Studio 2.2+Unity5.6來說明

1.安裝Android Studio 2.2(64Bit)


讯飞语音唤醒SDK接入流程_第1张图片


2.安裝Unity 5.6


讯飞语音唤醒SDK接入流程_第2张图片

3.在訊飛平台上創建一個項目,我這裡使用的是喚醒詞體驗包,有三個裝機量,35天,以及三個喚醒詞的限制,然後下載喚醒詞體驗包SDK(如图)


讯飞语音唤醒SDK接入流程_第3张图片
讯飞语音唤醒SDK接入流程_第4张图片


讯飞语音唤醒SDK接入流程_第5张图片

4.在Android studio中創建一個工程,流程如下面圖片

a.創建一個新工程,Application name我這裡設置成IFlyWakeupSDK,Company Domain:按照xxx.com的格式設置,然後Next

讯飞语音唤醒SDK接入流程_第6张图片

b.Next後如圖:默认已经勾选Phone and Tablet 后面的不需要选择 ,Minimum SDK我这里选择:API16:Android 4.1(Jelly Bean),然後Next

讯飞语音唤醒SDK接入流程_第7张图片

c.點Next後如圖:这里选择Empty Activity然後Next

讯飞语音唤醒SDK接入流程_第8张图片

d.點Next後如圖:然后点Finish

讯飞语音唤醒SDK接入流程_第9张图片

點完Finish後,我們可以看到完整的工程結構如圖:到这里项目基本创建完毕,下面讲如何设置工程

讯飞语音唤醒SDK接入流程_第10张图片

5.工程设置

a.在工程名山右鍵,New => Module,选择一个Empty Activity,最后命名为:IFlySDKLibrary 如图:


讯飞语音唤醒SDK接入流程_第11张图片
讯飞语音唤醒SDK接入流程_第12张图片
讯飞语音唤醒SDK接入流程_第13张图片

最后的工程结构如图:


讯飞语音唤醒SDK接入流程_第14张图片

b.選擇File => Project Structure ,然後選擇app,然后点检 - 按钮 刪除app Module,接着回到工程目錄下 右鍵選擇app => Delete

如圖:


讯飞语音唤醒SDK接入流程_第15张图片
讯飞语音唤醒SDK接入流程_第16张图片

c.回到工程目錄下,选择创建的library下的AndroidManifest.xml,删除多余的内容,然后添加上相应的权限,最后的内容如图:


讯飞语音唤醒SDK接入流程_第17张图片

d.打開下載的訊飛語音喚醒SDK目錄,在libs下有Msc.jar和Sunflower
.jar兩個文件,選擇他们然後複製,粘贴到工程中的libs目录下,然後把Unity5.6的jar也複製到這個目錄下,在Unity 5.6中在發布設置中我選擇的是Mono2x 所以我们找到Mono2x对应的目录(Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar)复制classes.jar,粘贴到工程中的libs目录下,最后工程截图如下:


讯飞语音唤醒SDK接入流程_第18张图片
讯飞语音唤醒SDK接入流程_第19张图片
讯飞语音唤醒SDK接入流程_第20张图片

e:回到工程 File => Project Structure ,选择mudules下的iflysdklibrary ,在選項卡的最後面有一個叫Dependencies,先删除如图中红色框中内容

然後把之前複製進來的3個jar包添加進來,如图:


讯飞语音唤醒SDK接入流程_第21张图片
讯飞语音唤醒SDK接入流程_第22张图片

然后选择Properties选项,设置Compile sdk version以及Build tools sdk Version版本,我这里都选择26(注意:因为unity中的编译sdk版本为26,所以选择26,不然在unity中编译不通过),然后选择Flavors选项,设置Min sdk Version为16 Target Sdk version为26,如图:


讯飞语音唤醒SDK接入流程_第23张图片
讯飞语音唤醒SDK接入流程_第24张图片

然后打开build.gradle,删除如图红框中的那行:


讯飞语音唤醒SDK接入流程_第25张图片

f:开始编写代码,不贅述直接上代碼:

package com.kingsoft.iflysdklibrary;

import android.content.Context;

import android.os.Bundle;

import android.os.Environment;

import android.util.Log;

import android.app.Fragment;

import com.iflytek.cloud.ErrorCode;

import com.iflytek.cloud.InitListener;

import com.iflytek.cloud.SpeechUtility;

import com.unity3d.player.UnityPlayer;

import org.json.JSONException;

import org.json.JSONObject;

import com.iflytek.cloud.SpeechConstant;

import com.iflytek.cloud.SpeechError;

import com.iflytek.cloud.SpeechEvent;

import com.iflytek.cloud.VoiceWakeuper;

import com.iflytek.cloud.WakeuperListener;

import com.iflytek.cloud.WakeuperResult;

import com.iflytek.cloud.util.ResourceUtil;

import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE;

public class MainActivity extends Fragment

{

private final String TAG = "Unity";

private final String CALLBACK_GAMEOBJECT= "IFlyManager";

// 语音唤醒对象

private VoiceWakeuper mIvw;

private final static int MAX = 60;

private final static int MIN = -20;

private int curThresh = 10;

private String ivwNetMode = "0";

private Context context;

// 唤醒结果内容

private String resultString;

private String keep_alive = "1";

private String gameObjectName;

private static MainActivity Instance = null;

public static MainActivity GetInstance(String gameObject)

{

if (Instance == null)

{

Instance = new MainActivity();

Instance.gameObjectName = gameObject;

UnityPlayer.currentActivity.getFragmentManager().beginTransaction().add(Instance, "MyPlugin").commit();

}

return Instance;

}

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setRetainInstance(true);

context = getActivity().getApplicationContext();

SpeechUtility.createUtility(context,SpeechConstant.APPID+"=xxxxxxx");

Log.d(TAG,"onCreate exec!!!");

}

public void StartWakeUpSpeechListener()

{

mIvw = VoiceWakeuper.createWakeuper(context,initListener);

if(mIvw == null)

{

Log.d(TAG,"VoiceWakeuper.createWakeuper faild!!!");

return;

}

resultString = "";

// 清空参数

mIvw.setParameter(SpeechConstant.PARAMS, null);

// 唤醒门限值,根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入

mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:"+ curThresh);

// 设置唤醒模式

mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup");

// 设置持续进行唤醒

mIvw.setParameter(SpeechConstant.KEEP_ALIVE, keep_alive);

// 设置闭环优化网络模式

mIvw.setParameter(SpeechConstant.IVW_NET_MODE, ivwNetMode);

// 设置唤醒资源路径

mIvw.setParameter(SpeechConstant.IVW_RES_PATH, getResource());

// 设置唤醒录音保存路径,保存最近一分钟的音频

mIvw.setParameter( SpeechConstant.IVW_AUDIO_PATH, Environment.getExternalStorageDirectory().getPath()+"/msc/ivw.wav");

mIvw.setParameter( SpeechConstant.AUDIO_FORMAT, "wav" );

// 如有需要,设置 NOTIFY_RECORD_DATA 以实时通过 onEvent 返回录音音频流字节

//mIvw.setParameter( SpeechConstant.NOTIFY_RECORD_DATA, "1" );

// 启动唤醒

int status = mIvw.startListening(mWakeuperListener);

if(status != ErrorCode.SUCCESS)

{

Log.d(TAG,"status:"+status);

}else

{

Log.d(TAG,"start wakeup Listening");

}

}

public void StopWakeUpSpeechListener()

{

if(mIvw != null)

{

mIvw.stopListening();

}

Log.d(TAG,"StopWakeUpSpeechListener");

}

private InitListener initListener = new InitListener()

{

@Override

public void onInit(int code)

{

Log.d(TAG,"onInit code:"+code);

}

};

private WakeuperListener mWakeuperListener = new WakeuperListener() {

@Override

public void onResult(WakeuperResult result)

{

Log.d(TAG, "onResult");

if(!"1".equalsIgnoreCase(keep_alive))

{

}

try

{

String text = result.getResultString();

JSONObject object;

object = new JSONObject(text);

StringBuffer buffer = new StringBuffer();

buffer.append("【RAW】 "+text);

buffer.append("\n");

buffer.append("【操作类型】"+ object.optString("sst"));

buffer.append("\n");

buffer.append("【唤醒词id】"+ object.optString("id"));

buffer.append("\n");

buffer.append("【得分】" + object.optString("score"));

buffer.append("\n");

buffer.append("【前端点】" + object.optString("bos"));

buffer.append("\n");

buffer.append("【尾端点】" + object.optString("eos"));

resultString = buffer.toString();

Log.d(TAG,"resultString:"+resultString);

//SendMsgToUnity("onVolumeChanged", ""+object.optString("score"));

SendMsgToUnity("onResult",""+object.optString("id"));

}

catch (JSONException e)

{

resultString = "结果解析出错";

Log.d(TAG,resultString);

e.printStackTrace();

}

}

@Override

public void onError(SpeechError error)

{

String errorCode = error.getErrorCode()+"";

Log.d( TAG, "errorCode:"+errorCode);

SendMsgToUnity("onError",errorCode);

}

@Override

public void onBeginOfSpeech()

{

Log.d( TAG, "onBeginOfSpeech");

SendMsgToUnity("onBeginOfSpeech","onBeginOfSpeech");

}

@Override

public void onEvent(int eventType, int isLast, int arg2, Bundle obj)

{

switch( eventType ){

// EVENT_RECORD_DATA 事件仅在 NOTIFY_RECORD_DATA 参数值为 真 时返回

case SpeechEvent.EVENT_RECORD_DATA:

final byte[] audio = obj.getByteArray( SpeechEvent.KEY_EVENT_RECORD_DATA );

Log.d( TAG, "ivw audio length: "+audio.length );

break;

}

}

@Override

public void onVolumeChanged(int volume)

{

Log.d( TAG, "onVolumeChanged:"+volume);

SendMsgToUnity("onVolumeChanged", volume+"");

}

};

private String getResource()

{

String resPath = ResourceUtil.generateResourcePath(context, RESOURCE_TYPE.assets, "ivw/595b8757.jet");

Log.d( TAG, "resPath:"+resPath);

return resPath;

}

private void SendMsgToUnity(String methodName,String msg)

{

UnityPlayer.UnitySendMessage(CALLBACK_GAMEOBJECT, methodName, msg);

}

public void Exit()

{

android.os.Process.killProcess(android.os.Process.myPid());

System.exit(0);

}

}

g.接着Build => Build APK 会在iflysdklibrary目录下build=>outputs=>aar目录中生成一个.aar文件,如图:


讯飞语音唤醒SDK接入流程_第26张图片

然后进入到aar目录下 把生成的.aar文件修改扩展名问zip,用解压软件打开,删除libs目录下的classes.jar(不删除在unity中会编译不通过),然后打开下载的讯飞唤醒体验包,把其中的依赖的so文件复制进zip目录下的libs中,最后的结构如图:

讯飞语音唤醒SDK接入流程_第27张图片
讯飞语音唤醒SDK接入流程_第28张图片

然后把zip包重新命名为.aar,到这里为止android studio中的工作就完成了,接着把讯飞唤醒sdk下的语音包复制到unity的Plugins/Android/Assets目录下,下面开始在Unity中的工作

h.unity中的设置如图,unity中的代码直接上图,不多赘述:


讯飞语音唤醒SDK接入流程_第29张图片
讯飞语音唤醒SDK接入流程_第30张图片
讯飞语音唤醒SDK接入流程_第31张图片
讯飞语音唤醒SDK接入流程_第32张图片

如果有不清楚的或者想交流的朋友,请联系QQ:2718390374

你可能感兴趣的:(讯飞语音唤醒SDK接入流程)