创建语音识别 SDK 引擎实例前调用,完成网络环境等相关依赖配置。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { return [SpeechEngine prepareEnvironment]; }
语音识别 SDK 通过如下方式获取相关实例。
//创建实例 self.engine = [[SpeechEngine alloc] init]; //添加引擎代理,需要实现回调方法 [self.engine createEngineWithDelegate:self];
【必选参数】引擎类型 [self.engine setStringParam:SE_ASR_ENGINE forKey:SE_PARAMS_KEY_ENGINE_NAME_STRING];
为便于开发者集成调试,有如下建议:
日志级别,开发时设置为 DEBUG
, 线上设置WARN
调试路径,语音识别 SDK 会在该路径下生成文件名前缀为 speech_sdk_
的日志文件,开发时设置,线上关闭。
//【可选配置】日志级别 [self.engine setStringParam:SE_LOG_LEVEL_DEBUG forKey:SE_PARAMS_KEY_LOG_LEVEL_STRING]; //【可选配置】调试路径,该路径必须在设备中存在,否则请提前创建 [self.engine setStringParam:@"{DEBUG PATH}" forKey:SE_PARAMS_KEY_DEBUG_PATH_STRING];
请先到火山控制台申请 Appid
和 Token
,申请方法参考控制台使用FAQ1,配置 Token
时需要添加固定前缀 Bearer;
。
//【必须配置】鉴权相关:AppID [self.engine setStringParam:@"{APPID}" forKey:SE_PARAMS_KEY_APP_ID_STRING]; //【必须配置】鉴权相关:Token [self.engine setStringParam:@"Bearer;{TOKEN}" forKey:SE_PARAMS_KEY_APP_TOKEN_STRING];
发起语音识别请求前,需要配置 ADDRESS
、URI
以及 CLUSTER
参数。
ADDRESS: websocket接口地址中的 scheme://域名,当前为wss://openspeech.bytedance.com
URI: websocket接口地址中的 ADDRESS 后的部分,当前为/api/v2/asr
CLUSTER: 控制台获取,可参考控制台使用FAQ-Q1
//【必须配置】识别服务ADDRESS [self.engine setStringParam:@"wss://openspeech.bytedance.com" forKey:SE_PARAMS_KEY_ASR_ADDRESS_STRING]; //【必须配置】识别服务URI [self.engine setStringParam:@"/api/v2/asr" forKey:SE_PARAMS_KEY_ASR_URI_STRING]; //【必须配置】识别服务CLUSTER [self.engine setStringParam:@"{CLUSTER}" forKey:SE_PARAMS_KEY_ASR_CLUSTER_STRING];
SDK 还支持调整建连、接收超时和重连。
//【可选配置】建连超时时间,建议使用默认值 [self.engine setIntParam:12000 forKey:SE_PARAMS_KEY_ASR_CONN_TIMEOUT_INT]; //【可选配置】数据接收超时时间,建议使用默认值 [self.engine setIntParam:8000 forKey:SE_PARAMS_KEY_ASR_RECV_TIMEOUT_INT]; //【可选配置】请求断连后是否尝试重连,默认0不重连 [self.engine setIntParam:0 forKey:SE_PARAMS_KEY_ASR_MAX_RETRY_TIMES_INT];
语音识别 SDK 支持以内置录音机、外部 PCM 流或音频文件作为输入,配置值分别为:
SE_RECORDER_TYPE_RECORDER,内置录音机;
SE_RECORDER_TYPE_STREAM,外部 PCM 流流;
SE_RECORDER_TYPE_FILE,PCM 格式音频文件。
//【必须配置】使用内置录音机,默认为单声道,16K 采样率,16 位深 [self.engine setStringParam:SE_RECORDER_TYPE_RECORDER forKey:SE_PARAMS_KEY_RECORDER_TYPE_STRING];
当使用内置录音机时,SDK 支持返回归一化的录音音量,如果 APP 需要显示音频波形可以使用这里返回的音量值。
//【可选配置】是否需要返回录音音量 [self.engine setBoolParam:TRUE forKey:SE_PARAMS_KEY_ENABLE_GET_VOLUME_BOOL];
设置最大录音时长,当达到设置的时间后,会发送音频结束包并等待asr结果
//【可选配置】最大录音时长,默认60000ms,如果使用场景超过60s请修改该值,-1为不限制录音时长 [self.engine setIntParam:60000 forKey:SE_PARAMS_KEY_VAD_MAX_SPEECH_DURATION_INT];
通过选择是否打开标点、顺滑等功能,可以更加细致地控制识别结果的形式,满足您不同层次的识别需求。
//【可选配置】是否开启顺滑功能,默认false,不开启 [self.engine setBoolParam:TRUE forKey:SE_PARAMS_KEY_ASR_ENABLE_DDC_BOOL]; //【可选配置】是否返回标点符号,默认false,不返回 [self.engine setBoolParam:TRUE forKey:SE_PARAMS_KEY_ASR_SHOW_NLU_PUNC_BOOL]; //【可选配置】是否隐藏句尾标点,默认false,不隐藏 [self.engine setBoolParam:TRUE forKey:SE_PARAMS_KEY_ASR_DISABLE_END_PUNC_BOOL]; //【可选配置】是否开启自动判停,默认false,不开启 [self.engine setBoolParam:TRUE forKey:SE_PARAMS_KEY_ASR_AUTO_STOP_BOOL]; //【可选配置】设置纠错词表,识别结果中会把匹配到纠错词表key值对应的文字置换为纠错词表value值对应的文字 [self.curEngine setStringParam:@"{\"星球崛起\":\"猩球崛起\"}", forKey:SE_PARAMS_KEY_ASR_CORRECT_WORDS_STRING];
如果识别时长较长建议设置识别结果形式为增量返回,只返回当前分句,否则内存会有增长。
//【可选配置】设置结果返回形式,建议设置为增量返回 [self.engine setStringParam:SE_ASR_RESULT_TYPE_SINGLE forKey:SE_PARAMS_KEY_ASR_RESULT_TYPE_STRING];
一句话场景下可以选用全量返回模式:
//【可选配置】设置结果返回形式,建议设置为全量返回 [self.engine setStringParam:SE_ASR_RESULT_TYPE_SINGLE forKey:SE_PARAMS_KEY_ASR_RESULT_TYPE_FULL];
参数配置完成后,调用 初始化引擎接口
,完成引擎实例的配置,然后注册 回调监听器
。
SEEngineErrorCode ret = [self.engine initEngine]; if (ret != SENoError) { NSLog(@"Init Engine failed: %d", ret); }
语音识别 SDK 通过发送指令接口 sendDirective
触发各种操作,需要注意以下两点:
不建议在 SDK 的回调线程中调用该接口;
sendDirective 接口所支持的指令中, START_ENGINE
, STOP_ENGINE
是异步指令,在相应的回调到达后才真正完成了操作。
SEDirectiveStartEngine
// 注意这里先调用同步停止,避免SDK内部异步线程带来的问题 [self.engine sendDirective:SEDirectiveSyncStopEngine, data:@""]; [self.engine sendDirective:SEDirectiveStartEngine, data:@""];
SEDirectiveFinishTalking
// 音频输入完成,引擎内部会关闭录音机,等待最终识别结果 [self.engine sendDirective:SEDirectiveFinishTalking, data:@""];
SEDirectiveStopEngine
// 取消本次请求,在业务超时时,可以调用该指令,正常结束不需要调用,引擎内部会自动结束 [self.engine sendDirective:SEDirectiveStopEngine, data:@""];
SEDirectiveUpdateAsrHotWords
// 设置热词词表,支持在任意时刻设置 [self.engine sendDirective:SEDirectiveUpdateAsrHotWords data: @"{\"hotwords\":[{\"word\":\"过秦论\",\"scale\":2.0}]}"];
SEEngineStart
收到该回调后表示识别已经开始。
SEEngineStop
收到该回调后,引擎进入空闲状态。
SEEngineError
引擎发生错误。数据部分为 JSON 结构,内部包含三个字段:
req_id:请求 ID;
err_msg:错误描述信息;
err_code:错误码,可参考语音识别 SDK 错误码说明;
SEAsrPartialResult
表示当前 session 已处理的部分音频的识别结果。对于流式 ASR 而言,处理最终识别结果和中间识别结果的方法相同。数据字段为 json 格式,json 数据的详细信息参考这里。
SETTING_ASR_RESULT_TYPE不同场景结果处理示例
dispatch_async(dispatch_get_main_queue(), ^{ // 从回调的 json 数据中解析 ASR 结果 NSError *error; NSDictionary *jsonResult = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error]; if (![jsonResult objectForKey:@"result"]) { return; } NSString *result = [[[jsonResult objectForKey:@"result"] firstObject] objectForKey:@"text"]; if (result.length == 0) { return; } // 结果上屏 // [self setResultText:[result stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]]; });
@property (nonatomic, strong) NSString *lastSentence; // 上一句结果 @property (nonatomic, strong) NSString *totalText; // 全量结果 self.lastSentence = @""; self.totalText = @""; dispatch_async(dispatch_get_main_queue(), ^{ // 从回调的 json 数据中解析 ASR 结果 NSError *error; NSDictionary *jsonResult = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error]; if (![jsonResult objectForKey:@"result"]) { return; } NSString *result = [[[jsonResult objectForKey:@"result"] firstObject] objectForKey:@"text"]; if (result.length == 0 && self.lastSentence.length > 0) { self.totalText = [self.totalText stringByAppendingString:self.lastSentence]; } self.lastSentence = result; // 结果上屏 // [self setResultText:[self.totalText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]]; });
SEFinalResult
表示当前 session 的整段音频的识别结果。处理方法参考前述“中间识别结果”的处理方法。
SEVolumeLevel
使用内置录音机时,才会返回的一个回调。其值为[0-1]之间的归一化值,正常音量在0.2附近。
当不再需要语音识别后,建议对引擎实例进行销毁,释放内存资源。
[self.engine destroyEngine]; self.engine = nil;