开放能力
开发平台
行业应用
生态合作
开发与教学
资讯 社区 控制台
技术能力
语音技术
文字识别
人脸与人体
图像技术
语言与知识
视频技术
AR与VR
数据智能
场景方案
部署方案
行业应用
智能教育
智能医疗
智能零售
智能工业
企业服务
智能政务
信息服务
智能园区

调用流程

DEMO在SDK的基础上,封装了输入和输出格式,您可以直接使用SDK,或者使用DEMO封装好SDK接口的类。 使用SDK方式的话,比较底层,需要自行实现一部分逻辑。可以参考DEMO中对SDK的调用封装。基于SDK集成和基于DEMO集成方式2选1即可。

在线识别调用流程

调用流程

SDK 的调用过程可以参见DEMO中的ActivityMiniRecog类

DEMO的调用过程可以参考DEMO中的ActivityAbstractRecog类

1 初始化

1.1 初始化EventManager对象

SDK中,通过工厂创建语音识别的事件管理器。注意识别事件管理器只能维持一个,请勿同时使用多个实例。即创建一个新的识别事件管理器后,之前的那个置为null,并不再使用。

EventManager asr = EventManagerFactory.create(this, "asr"); 
// this是Activity或其它Context类

详见ActivityMiniRecog类中”基于sdk集成1.1 初始化EventManager对象"

1.2 自定义输出事件类

SDK中,需要实现EventListener的输出事件回调接口。该类需要处理SDK在识别过程中的回调事件。可以参考DEMO中对SDK的调用封装。

EventListener yourListener = new EventListener() {
	@Override
	public void onEvent(String name, String params, byte [] data, int offset, int length) {
		if(name.equals(SpeechConstant.CALLBACK_EVENT_ASR_READY)){
			// 引擎就绪,可以说话,一般在收到此事件后通过UI通知用户可以说话了
		}
		if(name.equals(SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL)){
			// 一句话的临时结果,最终结果及语义结果
		}
			// ... 支持的输出事件和事件支持的事件参数见“输入和输出参数”一节
	}
};

详见ActivityMiniRecog类中”基于sdk集成1.2 自定义输出事件类"

1.3 注册自己的输出事件类

asr.registerListener(yourListener);

详见ActivityMiniRecog类中”基于sdk集成1.3 注册自己的输出事件类”

DEMO中,以上两步合并为

IRecogListener listener = new MessageStatusRecogListener(handler);

// 可以传入IRecogListener的实现类,也可以如SDK,传入EventListener实现类
//如果传入IRecogListener类,在RecogEventAdapter为您做了大多数的json解析。

MyRecognizer myRecognizer = new MyRecognizer(this, listener); 
//this是Activity或其它Context类

详见ActivityAbstractRecog类中”基于DEMO集成第1.1, 1.2, 1.3 步骤 初始化EventManager类并注册自定义输出事件

2 开始识别

开始事件的参数可以参见"输入和输出参数"。

2.1 设置识别输入参数

SDK中,您需要根据文档或者demo确定您的输入参数。DEMO中有UI界面简化选择和测试过程。demo中,在点击“开始录音”按钮后,您可以在界面或者日志中看见ASR_START事件的json格式的参数。

// asr.params(反馈请带上此行日志):{"accept-audio-data":false,"disable-punctuation":false,"accept-audio-volume":true,"pid":1736}

//其中{"accept-audio-data":false,"disable-punctuation":false,"accept-audio-volume":true,"pid":1736}为ASR_START事件的参数

String json ="{\"accept-audio-data\":false,\"disable-punctuation\":false,\"accept-audio-volume\":true,\"pid\":1736}"

详见ActivityMiniRecog类中”基于SDK集成2.1 设置识别参数‘’

2.2 发送start开始事件

asr.send(SpeechConstant.ASR_START, json, null, 0, 0);

详见ActivityMiniRecog类中”基于SDK集成2.2 发送开始事件

DEMO中, 您需要传递Map<String,Object>的参数,会将Map自动序列化为json

Map<String, Object> params;
... // 设置识别参数
// params ="accept-audio-data":false,"disable-punctuation":false,"accept-audio-volume":true,"pid":1736
myRecognizer.start(params);

详见ActivityAbstractRecog类中"基于DEMO集成2.1, 2.2 设置识别参数并发送开始事件"

3 收到回调事件

3.1开始回调事件

回调事件在您实现的EventListener中获取。OnEvent方法中, name是输出事件名,params该事件的参数,(data,offset, length)三者一起组成额外数据。如回调的音频数据,从data[offset]开始至data[offset + length] 结束,长度为length。

public void onEvent(String name, String params, byte [] data, int offset, int length);

详见ActivityMiniRecog类中”基于SDK集成3.1 开始回调事件"

DEMO中, 回调事件在您实现的IRecogListener中获取。

详见RecogEventAdapter类中”基于DEMO集成3.1 开始回调事件"

4控制识别

4.1 控制停止识别

asr.send(SpeechConstant.ASR_STOP, null, null, 0, 0); 
//发送停止录音事件,提前结束录音等待识别结果

详见ActivityMiniRecog类中”基于SDK集成4.1 发送停止事件"

4.2 控制取消识别

asr.send(SpeechConstant.ASR_CANCEL, null, null, 0, 0);
 //取消本次识别,取消后将立即停止不会返回识别结果

详见ActivityMiniRecog类中”基于SDK集成4.2 发送取消事件"

DEMO 中:

myRecognizer.stop(); 
// 发送停止录音事件,提前结束录音等待识别结果

详见ActivityAbstractRecog类中”基于DEMO集成4.1 发送停止事件"

myRecognizer.cancel(); 
// 取消本次识别,取消后将立即停止不会返回识别结果

详见ActivityAbstractRecog类中”基于DEMO集成4.2 发送取消事件"

5 事件管理器退出

5.1 在线不需要卸载离线命令词

先启动取消,避免有还在运行的识别。 之后需要将之前的listener卸载,不卸载的话,可能有内存溢出

asr.send(SpeechConstant.ASR_CANCEL, null, null, 0, 0); // 取消识别

5.2 释放资源

asr.unregisterListener(this);

详见ActivityMiniRecog类中基于SDK集成5.2 退出事件管理器"

DEMO中,

myRecognizer.release(); 
// 含有离线引擎卸载

详见ActivityAbstractRecog类中基于DEMO的5.2 退出事件管理器"


离线命令词调用流程

离线命令词的bsg文件设置:

在语音控制台的左侧功能栏中,进入“离线词&语义设置”模块,根据页面上的引导自行定义词条和语法,并生成bsg文件。其中右侧“说法”部分,为固定语法,下载后不可更改。左侧“词条”部分,代码中可以动态定义覆盖。 image.png

离线命令词功能可以测试DEMO中的第二个按钮“离线命令词识别”

调用流程:

离线命令词功能需要首先实现之前的在线识别功能的代码。离线引擎加载需要在EventManager初始化之后,识别事件之前。 在SDK中,

HashMap map = new HashMap();
map.put(SpeechConstant.DECODER, 2); 
// 0:在线 2.离在线融合(在线优先)
map.put(SpeechConstant.ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH, "/sdcard/yourpath/baidu_speech_grammar.bsg");
 //设置离线命令词文件路径

// 下面这段可选,用于生成SLOT_DATA参数, 用于动态覆盖ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH文件的词条部分

JSONObject json = new JSONObject();
json.put("name", new JSONArray().put("王自强").put("叶问")).put("appname", new
JSONArray().put("手百").put("度秘"));
map.put(SpeechConstant.SLOT_DATA, json.toString());
// SLOT_DATA 参数添加完毕

1.1 到1.3同在线

1.4 加载离线资源

asr.send(SpeechConstant.ASR_KWS_LOAD_ENGINE,new
JSONObject(map).toString());

//加载离线引擎,使用离线命令词时使用,请在整个离线识别任务结束之后卸载离线引擎

详见ActivityMiniRecog类中”基于SDK离线命令词1.4 加载离线资源(离线时使用)"

//离线引擎加载完毕事件后,开始你的识别流程,此处开始你的识别流程,注意离线必须断网生效或者SDK无法连接百度服务器时生效,只能识别bsg文件里定义的短语。

2.1-4.2 步骤同在线

5.1 卸载离线资源

//不再需要识别功能后,卸载离线引擎。再次需要识别功能的话,可以重复以上步骤。即依旧需要EventManager初始化之后,识别事件之前加载离线引擎。

asr.send(SpeechConstant.ASR_KWS_UNLOAD_ENGINE, null, null, 0, 0);

详见ActivityMiniRecog类中”基于SDK集成5.1 卸载离线资源步骤(离线时使用)"

在demo中,

HashMap&lt;String, Object&gt; map = new HashMap&lt;String, Object&gt;();
map.put(SpeechConstant.DECODER, 2); 
// 0:在线 2.离在线融合(在线优先)
map.put(SpeechConstant.ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH, "/sdcard/yourpath/baidu_speech_grammar.bsg"); 
//设置离线命令词文件路径

// 下面这段可选,用于生成SLOT_DATA参数, 用于动态覆盖ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH文件的词条部分

JSONObject json = new JSONObject();
json.put("name", new
JSONArray().put("王自强").put("叶问")).put("appname", new
JSONArray().put("手百").put("度秘"));
map.put(SpeechConstant.SLOT_DATA, json.toString());
// SLOT_DATA 参数添加完毕
myRecognizer.loadOfflineEngine(map);
//加载离线引擎,使用离线命令词时使用,请在整个离线识别任务结束之后卸载离线引擎 

详见ActivityAbstractRecog类中”基于DEMO集成1.4 加载离线资源步骤(离线时使用)"

//离线引擎加载完毕事件后,开始你的识别流程,注意离线必须断网生效或者SDK无法连接百度服务器时生效,只能识别bsg文件里定义的短语。

//不再需要识别功能后,卸载离线引擎。再次需要识别功能的话,可以重复以上步骤, 新建MyRecognizer类即可。

myRecognizer.release();

详见ActivityAbstractRecog类中”基于DEMO5.1 卸载离线资源(离线时使用)"


唤醒词调用流程

SDK 的调用过程可以参见DEMO中的ActivityMiniWakeUp类

DEMO的调用过程可以参考DEMO中的ActivityWakeUp类

1 初始化

1.1 初始化EventManager对象

SDK中,通过工厂创建语音唤醒词的事件管理器。注意唤醒词事件管理器同识别事件管理器一样只能维持一个,请勿同时使用多个实例。即创建一个新的唤醒词事件管理器后,之前的那个设置为null。并不再使用。

EventManager wp= EventManagerFactory.create(this,"wp");
 //this是Activity或其它Context类

详见ActivityMiniWakeUp类中”基于SDK唤醒词集成1.1 初始化EventManager"

1.2 自定义输出事件类

DEMO中,初始化过程合并到下一步。注意SDK和DEMO调用方式2选1即可。 注册用户自己实现的输出事件类

EventListener yourListener = new EventListener() {
@Override
public void onEvent(String name, String params, byte [] data, int
offset, int length) {
	Log.d(TAG, String.format("event: name=%s, params=%s", name, params));
	//唤醒事件
	if(name.equals("wp.data")){
		try {
			JSONObject json = new JSONObject(params);
			int errorCode = json.getInt("errorCode");
			if(errorCode == 0){
			    //唤醒成功
			} else {
			    //唤醒失败
			}
		 } catch (JSONException e) {
		     e.printStackTrace();
		   }
	 } else if("wp.exit".equals(name)){
		//唤醒已停止
	 }
	 }
}

详见ActivityMiniWakeUp类中”基于SDK唤醒词集成1.2 自定义输出事件类"

1.3 注册自己的输出事件类

wp.registerListener(yourListener);

详见ActivityMiniWakeUp类中”基于SDK唤醒词集成1.3 注册输出事件"

DEMO中,以上两步合并为

IWakeupListener listener = new SimpleWakeupListener();
myWakeup = new MyWakeup(this,listener);
// this是Activity或其它Context类

详见ActivityWakeUp类中”基于DEMO唤醒词集成第1.1, 1.2, 1.3步骤"

2 开始唤醒

2.1 设置唤醒输入参数

SDK中,您需要根据文档或者demo确定您的输入参数。DEMO中有UI界面简化选择和测试过程。demo中,在点击“开始”按钮后,您可以在界面或者日志中看见WAKEUP_START事件的json格式的参数。

wakeup.params(反馈请带上此行日志):{"kws-file":"assets:\/\/\/WakeUp.bin"} // 其中{"kws-file":"assets:\/\/\/WakeUp.bin"}为WAKEUP_START事件的参数

HashMap map = new HashMap();
map.put(SpeechConstant.WP_WORDS_FILE, "assets://WakeUp.bin");

详见ActivityMiniWakeUp类中”基于SDK唤醒词集成第2.1 设置唤醒的输入参数" 唤醒词文件请去http://ai.baidu.com/tech/speech/wake\#tech-demo设置并下载

2.2 发送start开始事件

wp.send(SpeechConstantWAKEUP_START, json, null, 0, 0);

详见ActivityMiniWakeUp类中”基于SDK唤醒词集成第2.2 发送开始事件开始唤醒"

DEMO中, 您需要传递Map 的参数,会将Map自动序列化为json

HashMap<String,Object> params = new
HashMap<String,Object>();
params.put(SpeechConstant.WP_WORDS_FILE, "assets://WakeUp.bin");
myWakeup.start(params);

详见ActivityWakeUp类中”基于DEMO唤醒词集成第2.1, 2.2 发送开始事件开始唤醒"

3 收到回调事件

3.1 开始回调事件

SDK中,回调事件在您实现的EventListener中获取。OnEvent中, name是输出事件名,params该事件的参数,(data,offset, length)三者一起组成额外数据。如回调的音频数据,从data[offset]开始至data[offset + length] 结束,长度为length。

public void onEvent(String name, String params, byte [] data, int offset, int length);

详见ActivityMiniWakeUp类中”基于SDK唤醒3.1 开始回调事件"

DEMO中, 回调事件在您实现的IWakeupListener中获取。

详见WakeupEventAdapter类中”基于DEMO唤醒3.1 开始回调事件"

4 控制唤醒

SDK中,

4.1 控制停止唤醒

wp.send(SpeechConstant.WAKEUP_STOP, null, null, 0, 0);

详见ActivityMiniWakeUp类中”基于SDK唤醒词集成第4.1 发送停止事件"

DEMO中,

myWakeup.stop();

详见ActivityWakeUp类中”基于DEMO唤醒词集成第4.1 发送停止事件"

5 事件管理器退出

SDK中无需调用任何逻辑,但需要创建一个新的唤醒词事件管理器的话,之前的事件管理器请设置为null,并不再使用。

DEMO中,

myWakeup.release();

详见ActivityWakeUp类中”基于DEMO唤醒词集成第5 退出事件管理器">


集成指南

  1. DEMO 中已经集成了 SDK。您可以参考DEMO,集成SDK。
  2. 集成前,请先测通DEMO,了解调用原理。
  3. 如果您自己代码过于复杂,可以使用一个helloworld项目了解集成过程。
  4. DEMO目录下的doc_integration_DOCUMENT的目录中有图文集成教程。

本文以Android Studio 作为示例

集成时请确认已经复制或者修改了以下文件,一共4步:

  1. AndroidManifest.xml
  2. app/libs/bdasr_V3_xxxxx_xxxxx.jar
  3. app/src/main/jniLibs 下armeabi等5个目录
  4. 官网申请应用时的包名与build.gradle里一致,demo的包名是"com.baidu.speech.recognizerdemo"。这步没做会导致离线命令词或者唤醒报“no licence” 错误
  5. 运行时 getApplicationInfo().nativeLibraryDir 目录下查看是否有完整so文件。 特别是系统app需要手动push so文件到这个目录下。

AndroidManifest.xml 文件

  • 设置权限
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • 设置APP_ID, APP_KEY, SECRET_KEY
    <meta-data android:name="com.baidu.speech.APP_ID"
        android:value="9788136" />
    <meta-data
        android:name="com.baidu.speech.API_KEY"
        android:value="0GjQNO5H4pGPf9HyA3AmZEbz" />
    <meta-data
        android:name="com.baidu.speech.SECRET_KEY"
        android:value="db981ef3ec647ba8a09b599ad7447a24" />

也可以作为识别和唤醒的参数填入这3个鉴权信息。 AndroidManifest.xml填写方式仅供测试使用,上线后请使用APP_ID, APP_KEY, SECRET填写鉴权信息,建议代码里直接传入APP_ID, APP_KEY, SECRET,请参考在线识别具体功能参数- 鉴权信息部分,填写这3个鉴权信息。

android 6.0 以上版本权限申请

以下代码可以在demo中查找

/**
 * android 6.0 以上需要动态申请权限
 */
private void initPermission() {
    String permissions[] = {Manifest.permission.RECORD_AUDIO,
            Manifest.permission.ACCESS_NETWORK_STATE,
            Manifest.permission.INTERNET,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

    ArrayList<String> toApplyList = new ArrayList<String>();

    for (String perm :permissions){
        if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, perm)) {
            toApplyList.add(perm);
            //进入到这里代表没有权限.

        }
    }
    String tmpList[] = new String[toApplyList.size()];
    if (!toApplyList.isEmpty()){
        ActivityCompat.requestPermissions(this, toApplyList.toArray(tmpList), 123);
    }

}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    // 此处为android 6.0以上动态授权的回调,用户自行实现。

bdasr_V3_xxxxxxxx_xxxx.jar 库

将core/libs/bdasr_V3_xxxxx_xxxxx.jar 复制到您的项目的同名目录中。

复制NDK 架构目录

  1. 将 core/src/main/jniLibs 下armeabi等包含so文件的5个目录,复制合并到您的项目的同名或者存放so的目录中。如果build.gradle中定义过jniLibs.srcDirs ,则复制合并到这个目录。
  2. 如与第三方库集成,至少要保留armeabi目录。如第三方库有7个架构目录,比语音识别SDK多出2个目录 mips和mips64,请将mips和mips64目录删除,剩下5个同名目录合并。
  3. 如第三方库仅有armeabi这一个目录,请将语音识别SDK的额外4个目录如armeabi-v7a删除,合并armeabi目录下的so。 即目录取交集,so文件不可随意更改所属目录。
  4. 打包成apk文件,按照zip格式解压出libs目录可以验证。
  5. 运行时 getApplicationInfo().nativeLibraryDir 目录下查看是否有完整so文件。 特别是系统app需要手动push so文件到这个目录下。

build.gradle 文件及包名确认

  1. 根目录下build.gradle确认下gradle的版本。
  2. app/build.gradle 确认下 applicationId 包名是否与官网申请应用时相一致(离线功能需要)。 demo的包名是"com.baidu.speech.recognizerdemo"。
  3. 确认 compileSdkVersion buildToolsVersion 及 targetSdkVersion

proguard文件

-keep class com.baidu.speech.**{*;}

BEST PRACTICE

  • 请先测通DEMO,了解DEMO的功能,代码的运行原理后再集成。DEMO有bug,请立即反馈。
  • 对应任何第三方库,从一开始集成,边开发边测试,不要等所有功能都开发完再集成。否则一旦有问题,难以隔离排查。
  • 有问题先与DEMO做对比。DEMO有bug,请查看错误码文档,如无法解决请立即反馈;DEMO无bug,自身代码有问题,请设置同样的输入参数后,对比两边代码及日志,自行排查问题。
上一篇
简介
下一篇
输入参数