声网4.x+小游戏ASR 接入(iOS)

SudMGP提供的互动小游戏,你画我猜、你说我猜、数字炸弹, 支持玩家用语音命中,提高可玩性,增强社交属性。接入步骤十分便捷,本文介绍接入SudMGP SDK的ASR功能的步骤。

一、背景

小游戏可以带有语音命中能力,App只要从声网RTC获得特定格式PCM数据,以指定方式传入SudMGP SDK, 即可。 在此以hello-sud-plus-ios 为例,hello-sud-plus-ios源码地址: https://github.com/SudTechnology/hello-sud-plus-ios hello-sud-plus-ios以SudMGPWrapper封装集成 SudMGP SDK, 我们建议客户用SudMGPWrapper集成SDK。 二、集成步骤 SDK Github地址:https://github.com/SudTechnology/sud-mgp-ios 请使用最新版本, 可用CocoaPods方式集成,以V1.3.4.1290版本举例: 1.集成SudMGP SDK: 标准版: pod 'SudMGPWrapper', '~> 1.3.4.1' Lite版: pod 'SudMGPWrapper_Lite', '~> 1.3.4.1' 2.集成语音识别库: pod 'MicrosoftCognitiveServicesSpeech-iOS', '1.23.0'

三、小游戏启动语音识别(ASR)

小游戏进入语音识别场景时,会自动启动ASR能力,此时,会向App发送MG_COMMON_GAME_ASR状态, isOpen是true, 见SudFSMMGListener协议的:

  • (void)onGameMGCommonGameASR:(nonnull id )handle model:(MGCommonGameASRModel *)model;

四、App 启动RTC音频流监听

App收到 MG_COMMON_GAME_ASR状态, isOpen == YES后, 调用声网接口AgoraRtcEngineKit的方法:

  • (BOOL)setAudioFrameDelegate:(id _Nullable)delegate; 并实现AgoraAudioFrameDelegate协议, 启动声网本端PCM数据采集

1.调用 [AgoraRtcEngineKit setAudioFrameDelegate:]

/// 开始原始音频采集
- (void)startPCMCapture {
    [[AsyncCallWrapper sharedInstance] addOperationWithBlock:^{
        AgoraRtcEngineKit *engine = [self getEngine];
        if (engine != nil) {
            /* 开启获取PCM数据功能 */
            [engine setAudioFrameDelegate:self];
        }
    }];
}

2.AgoraAudioFrameDelegate协议

#pragma mark - AgoraAudioFrameDelegate
- (BOOL)onRecordAudioFrame:(AgoraAudioFrame * _Nonnull)frame channelId:(NSString * _Nonnull)channelId {
    [HSThreadUtils runOnUiThread:^{
        if (self.mISudAudioEventListener != nil && [self.mISudAudioEventListener respondsToSelector:@selector(onCapturedPCMData:)]) {
            NSUInteger length = frame.samplesPerChannel * frame.channels * frame.bytesPerSample;
            NSData *pcmData = [[NSData alloc] initWithBytes:frame.buffer length:length];
            [self.mISudAudioEventListener onCapturedPCMData:pcmData];
        }
    }];
    return YES;
}

- (AgoraAudioParams* _Nonnull)getEarMonitoringAudioParams {
return nil;
}

- (AgoraAudioParams* _Nonnull)getMixedAudioParams {
return nil;
}

- (AgoraAudioFramePosition)getObservedAudioFramePosition {
return AgoraAudioFramePositionRecord;
}

- (AgoraAudioParams* _Nonnull)getPlaybackAudioParams {
return nil;
}

- (AgoraAudioParams* _Nonnull)getRecordAudioParams {
    AgoraAudioParam * param = [[AgoraAudioParam alloc] init];
    param.channel = 1;
    param.sampleRate = 16000;
    param.mode = AgoraAudioRawFrameOperationModeReadOnly;
    param.samplesPerCall = 160;
    return param;
}

- (BOOL)onPlaybackAudioFrame:(AgoraAudioFrame* _Nonnull)frame {
    return NO;
}

- (BOOL)onMixedAudioFrame:(AgoraAudioFrame* _Nonnull)frame channelId:(NSString * _Nonnull)channelId {
    return NO;
}

- (BOOL)onPlaybackAudioFrameBeforeMixing:(AgoraAudioFrame* _Nonnull)frame uid:(NSUInteger)uid {
    return NO;
}

- (BOOL)onEarMonitoringAudioFrame:(AgoraAudioFrame* _Nonnull)frame {
    return NO;
}

getRecordAudioParams 回调方法设置PCM数据格式, 调用pushAudio传入的音频切片是从RTC获取的PCM数据 PCM数据格式必须是:采样率:16000, 采样位数:16, 声道数: MONO PCM数据长度可以根据效果调整,长度大: 精确度好但延时长 长度小:延时短但牺牲精确度 声网的音频切片默认是10ms,可以根据效果调整下面传给pushAudio的音频切片长度

onRecordAudioFrame 回调方法返回RTC采集的本端PCM数据,处理方法请见下节

3.将RTC采集的PCM数据传给SDK onRecordAudioFrame 回调方法返回本端PCM数据切片,最终调用如下方法将PCM数据传给SDK:

/**
 * 音频流数据
 */
- (void)onCapturedPCMData:(NSData *)data {
    [self.sudFSTAPPDecorator pushAudio:data];
}

pushAudio接口可以在工作线程中调用 声网的音频切片默认是10ms,可以根据效果调整传给pushAudio的音频切片长度

五、App关闭RTC音频流监听

小游戏在命中或超时导致退出语音识别场景后,会向App发送状态提示关闭PCM数据捕获 App收到 MG_COMMON_GAME_ASR状态, isOpen == NO后, 调用声网接口[AgoraRtcEngineKit setAudioDataFrame:nil], 关闭声网本端PCM数据采集

/// 结束原始音频采集
- (void)stopPCMCapture {
    [[AsyncCallWrapper sharedInstance] addOperationWithBlock:^{
        AgoraRtcEngineKit *engine = [self getEngine];
        if (engine != nil) {
            /* 关闭获取PCM数据功能 */
            [engine setAudioDataFrame:nil];
        }
    }];
}

六、只用ASR玩游戏时

只用ASR玩游戏时,App只需要处理MG_COMMON_GAME_ASR状态,负责开启/关闭本端PCM数据采集。不需要像文字命中一样向游戏发mg_common_key_word_to_hit

七、用文字输入玩小游戏的文字命中场景

有语音识别场景的小游戏,通常也能并行使用文字输入来进行命中。游戏会通过mg_common_key_word_to_hit状态通知App命中场景开始, App会通过SudFSMMGListener协议接收:

  • (void)onGameMGCommonKeyWordToHit:(nonnull id )handle model:(MGCommonKeyWrodToHitModel *)model; 文字命中场景,小游戏分两类 1.让App持有关键字的小游戏,如你画我猜,你说我猜,model.word不为空,App需要在本地判断是否命中,判断命中后,再通过接口方法[SudFSTAPPDecorator notifyAppComonDrawTextHit] 通知游戏 2.不让App持有关键字的小游戏,如数字炸弹,model.word为空,App需要每次将文字送给游戏,由游戏判断是否命中 ```objc
  • (void)handleGameKeywordHitting:(NSString *)content { // 数字炸弹 if (self.sudFSMMGDecorator.isHitBomb) {
      if ([self isPureInt:content]) {
          /// 关键词命中
          [self.sudFSTAPPDecorator notifyAppComonDrawTextHit:false keyWord:@"" text:content];
      }
      return;
    
    }

// 你画我猜 if (self.sudFSMMGDecorator.keyWordHiting == YES && [content isEqualToString:self.sudFSMMGDecorator.drawKeyWord]) { /// 关键词命中 [self.sudFSTAPPDecorator notifyAppComonDrawTextHit:true keyWord:self.sudFSMMGDecorator.drawKeyWord text:self.sudFSMMGDecorator.drawKeyWord]; } } ```

results matching ""

    No results matching ""