有奖捉虫:办公协同&微信生态&物联网文档专题 HOT
为方便开发者快速实现实时语音流转文本(以下用 实时 ASR 指代)功能,这里向您介绍实时语音转文本的使用场景以及接入流程。

使用场景

GME 语音转文本服务,可以将 GME SDK 采集的音频流实时识别成文字。该功能可应用于线上桌游场景,如 “你说我猜”“你画我猜” 等猜词游戏场景,玩家开始猜词后,调用 GME SDK实时 ASR 接口,即可将玩家的实时语音流送入 GME 进行实时识别。业务客户端或业务服务端使用 GME 返回的语音转文本识别结果,可进行相关游戏玩法的逻辑实现。
说明
实时语音流转文本目前仅支持中文识别。

前提条件

已开通实时语音服务:可参见 服务开通指引
已开通语音转文本服务:可参见 服务开通指引
已接入 GME SDK:包括核心接口和实时语音接口的接入,详情可参见 Native SDK 快速接入Unity SDK 快速接入Unreal SDK 快速接入
说明
实时语音流转文本功能将产生实时语音服务费用、语音转文本服务费用。详情请参见 计费文档

使用限制

实时语音流转文本默认单账号限制并发连接数为50路,如您有提高并发限制的需求,请提工单 进行咨询。

实现流程

整体流程

实时语音流转文本整体流程如下:



接入流程





接入步骤

步骤1: 启动实时语音流转文本

在成功进房之后,开启麦克风采集及上行的情况下,调用 StartRealTimeASR 接口可以启动实时语音流转文本功能。
iOS
Android
//启动实时语音流转文本
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
转文本内容
回调示例代码:
iOS
Android
-(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 接口可以停止实时语音转文本。
示例代码:
iOS
Android
//停止实时语音ASR
ret = (int)[[ITMGContext GetInstance] StopRealTimeASR];
//停止实时语音ASR
int nRet = ITMGContext.GetInstance(getActivity()).StopRealTimeASR();

最佳实践

在一局“你说我猜”游戏中,将所有玩家加入房间。以每一轮新词竞猜作为一个实时语音转文本的会话周期,即:在每一次更换新词时调用“启动实时语音转文本”接口;在当前词语竞猜时间截止时,或有玩家猜中时调用“停止实时语音转文本”接口。