为方便开发者快速实现实时语音流转文本(以下用 实时 ASR 指代)功能,这里向您介绍实时语音转文本的使用场景以及接入流程。
使用场景
GME 语音转文本服务,可以将 GME SDK 采集的音频流实时识别成文字。该功能可应用于线上桌游场景,如 “你说我猜” 、“你画我猜” 等猜词游戏场景,玩家开始猜词后,调用 GME SDK 的 实时 ASR 接口,即可将玩家的实时语音流送入 GME 进行实时识别。业务客户端或业务服务端使用 GME 返回的语音转文本识别结果,可进行相关游戏玩法的逻辑实现。
说明:
实时语音流转文本目前仅支持中文识别。
前提条件
已开通实时语音服务:可参见 服务开通指引。
已开通语音转文本服务:可参见 服务开通指引。
已接入 GME SDK:包括核心接口和实时语音接口的接入,详情可参见 Native SDK 快速接入、Unity SDK 快速接入、Unreal SDK 快速接入。
说明:
使用限制
实现流程
整体流程
实时语音流转文本整体流程如下:
接入流程
接入步骤
1. 启动实时语音流转文本
2. 实时语音流转文本回调
3. 业务进行后续逻辑判断
4. 停止实时语音流转文本
步骤1: 启动实时语音流转文本
在成功进房之后,开启麦克风采集及上行的情况下,调用 StartRealTimeASR 接口可以启动实时语音流转文本功能。
//启动实时语音流转文本ret = (int)[[ITMGContext GetInstance] StartRealTimeASR];
//启动实时语音流转文本nRet = ITMGContext.GetInstance(getActivity()).StartRealTimeASR();
步骤2: 实时语音流转文本回调
启动实时语音流转文本功能之后,会在回调 ITMG_MAIN_EVENT_TYPE_REALTIME_ASR 中返回对应的信息。
字段 | 含义 |
sub_type | ITMG_REALTIME_ASR_START:调用 StartRealTimeASR 接口返回值为0 ITMG_REALTIME_ASR_CONTENT:转文本内容,可根据不同的slice_type获取不同状态的转文本结果 ITMG_REALTIME_ASR_END:调用StopRealTimeASR 函数接口返回值为0,或者在成功启动实时语音转文本,如果中间发生错误,例如服务器返回异常,长时间断网也会返回此回调 |
index | 前一段话的结果在整个音频流中的序号,从0开始逐句递增 |
result | 执行结果,如果为 0 则表示成功 |
slice_type | 转文本状态,业务层可根据需求关注不同状态的返回文本: 0:一段话开始转文本 1:一段话转文本中,voice_text_str 为非稳态结果(结果还可能变化) 2:一段话转文本结束,voice_text_str 为稳态结果(结果不再变化) 识别过程中可能返回的 slice_type 序列可能有: 0-1-2:一段话开始识别(slice_type=0)、识别中(可能有多次slice_type=1返回)、识别结束(slice_type=2) 0-2:一段话开始识别(slice_type=0)、识别结束(slice_type=2) 2:直接返回一段话完整的转文本结果(slice_type=2) |
voice_text_str | 转文本内容 |
回调示例代码:
-(void)OnEvent:(ITMG_MAIN_EVENT_TYPE)eventType data:(NSDictionary *)data{NSString* log =[NSString stringWithFormat:@"OnEvent:%d,data:%@", (int)eventType, data];[self showLog:log];NSLog(@"====%@====",log);switch (eventType) {case ITMG_MAIN_EVENT_TYPE_REALTIME_ASR :{if (ITMG_REALTIME_ASR_START == ((NSNumber *)data[@"sub_type"]).intValue) {UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"实时语音流转文本" message:[NSString stringWithFormat:@"开始 结果:%@ 错误信息:%@",data[@"result"],data[@"error_info"]] delegate:NULL cancelButtonTitle:@"OK" otherButtonTitles:nil];[alert show];if (((NSNumber *)data[@"result"]).intValue == 0) {isRealTimeASRRunnig = true;asrResult = @"";}}else if (ITMG_REALTIME_ASR_CONTENT == ((NSNumber *)data[@"sub_type"]).intValue){asrResult = [NSString stringWithFormat:@"index:%@ \\n slice_type:%@ \\n voice_text_str:%@",data[@"index"],data[@"slice_type"],data[@"voice_text_str"]];NSString *totalString = [NSString stringWithFormat:@" \\n \\n ASR: \\n %@ \\n sendType:%d \\n sendList:%@ \\n recvType:%d \\nrecvlist:%@ \\n %@",asrResult,sendType,sendArray,recvType,recvArray,tips];[RunningTipsView Show:totalString parentView:_tipsScrollView];} else if (ITMG_REALTIME_ASR_END == ((NSNumber *)data[@"sub_type"]).intValue){UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"实时语音流转文本" message:[NSString stringWithFormat:@"结束 结果:%@ 错误信息:%@",data[@"result"],data[@"error_info"]] delegate:NULL cancelButtonTitle:@"OK" otherButtonTitles:nil];[alert show];isRealTimeASRRunnig = false;asrResult = @"";} else {UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"实时语音流转文本" message:[NSString stringWithFormat:@"未知操作 结果:%@ 错误信息:%@",data[@"result"],data[@"error_info"]] delegate:NULL cancelButtonTitle:@"OK" otherButtonTitles:nil];[alert show];}```}}```}
...//判断回调if(ITMGContext.ITMG_MAIN_EVENT_TYPE.ITMG_MAIN_EVENT_TYPE_REALTIME_ASR== type) {int code = data.getIntExtra("result", 0);int sub_type = data.getIntExtra("sub_event", 0);if (sub_type == ITMGContext.ITMG_REALTIME_ASR_CONTENT){String totaString = " \\n \\n ASR: \\n ";totaString += data.getIntExtra("index", -1);totaString += " \\n slice_type:";totaString += data.getIntExtra("slice_type", -1);totaString += " \\n voice_text_str";totaString += data.getStringExtra("voice_text_str");totaString += "\\nAudioRoute :" + "\\n";}String errorInfo = data.getStringExtra("error_info");String typeInfo ;if (sub_type == ITMGContext.ITMG_REALTIME_ASR_START) {typeInfo = "开始 结果:";if (code ==0) {isRealTimeASRRunning = true;}} else if(sub_type == ITMGContext.ITMG_REALTIME_ASR_END) {typeInfo = "结束 结果:";isRealTimeASRRunning = false;} else {typeInfo = "操作unknown 结果:";}Toast.makeText(getActivity(), String.format("%s %d:错误信息:%s ",typeInfo,code,errorInfo), Toast.LENGTH_SHORT).show();}
步骤3: 业务进行后续逻辑判断
业务客户端在收到 GME 返回的实时语音识别结果后,即可在客户端或服务端根据玩法逻辑进行后续判断。
步骤4: 停止实时语音转文本
通过 StopRealTimeASR 接口可以停止实时语音转文本。
示例代码:
//停止实时语音ASRret = (int)[[ITMGContext GetInstance] StopRealTimeASR];
//停止实时语音ASRint nRet = ITMGContext.GetInstance(getActivity()).StopRealTimeASR();
实践教程
在一局“你说我猜”游戏中,将所有玩家加入房间。以每一轮新词竞猜作为一个实时语音转文本的会话周期,即:在每一次更换新词时调用“启动实时语音转文本”接口;在当前词语竞猜时间截止时,或有玩家猜中时调用“停止实时语音转文本”接口。