实时说话人分离

最近更新时间:2026-06-29 15:22:00

我的收藏

1. 接入准备

1.1 SDK 获取

实时语音识别(话者分离版)的 iOS SDK 以及 Demo 的下载地址:接入 SDK 下载,选择 iOS-Sentence下载。

1.2 接入须知

开发者在调用前请先查看实时语音识别的 接口说明,了解接口的使用要求使用步骤
该接口需要手机能够连接网络(GPRS、3G 或 Wi-Fi 网络等),且系统为 iOS 9.0 及以上版本。
运行 Demo 必须设置 AppID、SecretID、SecretKey,可在 API 密钥管理 中获取。

1.3 SDK 导入

1. 下载并解压 iOS SDK 压缩包,压缩包中包含 Demo 和 SDK, 其中QCloudRealTime.xcframework为实时语音识别framework包;VoiceCommon.framework为语音SDK公共组件framework包
2. XcodeFile > Add Files to "Your Project",在弹出 Panel 选中所下载SDK包QCloudRealTime.xcframework和VoiceCommon.framework > Add(选中"Copy items if needed")。

1.4 工程配置

在工程的 info.plist 中申请系统麦克风权限,添加如下内容:
<key>NSMicrophoneUsageDescription</key>
<string>需要使用您的麦克风采集音频</string>
在工程中添加依赖库,在 Build Phases Link Binary With Libraries 中添加以下库:
QCloudRealTime.xcframework
libc++.tbd
AVFoundation.framework
AudioToolbox.framework
VoiceCommon.framework

2. 快速接入

2.1 开发流程及接入示例

话者分离版 SDK 通过 WebSocket 实时识别音频,并将服务端返回的原始 JSON 透传给开发者,由开发者自行解析话者分离结果。

2.1.1 使用内置录音器采集语音识别示例

1. 引入SDK 的头文件
#import <QCloudRealTime/QCloudRealTimeRecognizer.h>
#import <QCloudRealTime/QCloudConfig.h>
#import <QCloudRealTime/QCloudRealTimeResult.h>
#import <QCloudRealTime/QCloudAudioDataSource.h>
2. 创建 QCloudConfig 实例
//1.创建 QCloudConfig 实例
QCloudConfig *config = [[QCloudConfig alloc] initWithAppId:kQDAppId
secretId:kQDSecretId
secretKey:kQDSecretKey
projectId:0];

// 以下为可选配置参数
config.requestTimeout = 10; // 请求超时时间(秒)
// config.sliceTime = 40; // 语音分片时长默认40ms(无特殊需求不建议更改)
config.enableDetectVolume = YES; // 是否检测音量
config.endRecognizeWhenDetectSilence = YES; // 是否检测到静音停止识别
config.shouldSaveAsFile = YES; // 仅限使用SDK内置录音器有效,是否保存录音文件到本地 默认关闭
config.saveFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"recordaudio.wav"]; // 开启shouldSaveAsFile后音频保存的路径,仅限使用SDK内置录音器有效,默认路径为[NSTemporaryDirectory() stringByAppendingPathComponent:@"recordaudio.wav"]

// 以下为API参数配置,参数描述见API文档:https://cloud.tencent.com/document/product/1093/48982
config.engineType = @"16k_zh_en_speaker"; // 话者分离版必须使用此引擎
config.filterDirty = 0; // 是否过滤脏词,具体的取值见API文档的filter_dirty参数
config.filterModal = 0; // 过滤语气词,具体的取值见API文档的filter_modal参数
config.filterPunc = 0; // 过滤句末的句号,具体的取值见API文档的filter_punc参数
config.convertNumMode = 1; // 是否进行阿拉伯数字智能转换。具体的取值见API文档的convert_num_mode参数
// config.hotwordId = @""; // 热词id。具体的取值见API文档的hotword_id参数
// config.customizationId = @""; // 自学习模型id,详情见API文档
// config.vadSilenceTime = -1; // 语音断句检测阈值,详情见API文档
config.needvad = 1; // 默认1 0:关闭 vad,1:开启 vad。如果语音分片长度超过60秒,用户需开启 vad。
config.wordInfo = 0; // 是否显示词级别时间戳。详情见API文档
config.reinforceHotword = 0; // 热词增强功能 0:关闭,1:开启 默认0
config.noiseThreshold = 0; // 噪音参数阈值,默认为0,取值范围:[-1,1]
3. 创建 QCloudRealTimeRecognizer 实例
QCloudRealTimeRecognizer *recognizer = [[QCloudRealTimeRecognizer alloc] initWithConfig:config];
4. 设置 delegate,实现 QCloudRealTimeRecognizerDelegate 方法
recognizer.delegate = self;
5. 开始识别
//使用内置录音器前需要先设置AVAudioSession状态为可录音的模式
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:&error];
if (error) {
//错误处理
}
[[AVAudioSession sharedInstance] setActive:YES error:nil];
//启动识别
[recognizer start];
6. 结束识别
[recognizer stop];

2.1.2 调用者提供语音数据示例

1. 引入 SDK 的头文件
#import <QCloudRealTime/QCloudRealTimeRecognizer.h>
#import <QCloudRealTime/QCloudConfig.h>
#import <QCloudRealTime/QCloudRealTimeResult.h>
#import <QCloudRealTime/QCloudAudioDataSource.h>
2. 创建 QCloudConfig 实例
//1.创建 QCloudConfig 实例
QCloudConfig *config = [[QCloudConfig alloc] initWithAppId:kQDAppId
secretId:kQDSecretId
secretKey:kQDSecretKey
projectId:0];

// 以下为可选配置参数
config.requestTimeout = 10; // 请求超时时间(秒)
// config.sliceTime = 40; // 语音分片时长默认40ms(无特殊需求不建议更改)
config.enableDetectVolume = YES; // 是否检测音量
config.endRecognizeWhenDetectSilence = YES; // 是否检测静音,默认YES
config.silenceDetectDuration = 3.0; // 最大静音时间阈值,单位:秒
config.endRecognizeWhenDetectSilenceAutoStop = YES; // 是否检测到静音停止识别,默认YES

// 以下为API参数配置,参数描述见API文档:https://cloud.tencent.com/document/product/1093/131127
config.engineType = @"16k_zh_en_speaker"; // 话者分离版兜底使用此引擎,详情见API文档
config.filterDirty = 0; // 是否过滤脏词,具体的取值见API文档的filter_dirty参数
config.filterModal = 0; // 过滤语气词,具体的取值见API文档的filter_modal参数
config.filterPunc = 0; // 过滤句末的句号,具体的取值见API文档的filter_punc参数
config.convertNumMode = 1; // 是否进行阿拉伯数字智能转换。具体的取值见API文档的convert_num_mode参数
// config.hotwordId = @""; // 热词id。具体的取值见API文档的hotword_id参数
// config.customizationId = @""; // 自学习模型id,详情见API文档
// config.vadSilenceTime = -1; // 语音断句检测阈值,详情见API文档
config.needvad = 1; // 默认1 0:关闭 vad,1:开启 vad。如果语音分片长度超过60秒,用户需开启 vad。
config.wordInfo = 0; // 是否显示词级别时间戳,详情见API文档
config.noiseThreshold = 0; // 噪音参数阈值,默认为0,取值范围:[-1,1],详情见API文档
// [config setApiParam:@"custom_param" value:@"value"]; // 设置自定义请求参数,用于在请求中添加SDK尚未支持的参数
3. 自定义 QCloudDemoAudioDataSource,QCloudDemoAudioDataSource 实现 QCloudAudioDataSource 协议
// QCloudDemoAudioDataSource 具体源代码详见 SDK demo 目录
QCloudDemoAudioDataSource *dataSource = [[QCloudDemoAudioDataSource alloc] init];
4. 创建 QCloudRealTimeRecognizer 实例
QCloudRealTimeRecognizer *recognizer = [[QCloudRealTimeRecognizer alloc] initWithConfig:config dataSource:dataSource];
5. 设置 delegate,实现 QCloudRealTimeRecognizerDelegate 方法
recognizer.delegate = self;
6. 开始识别
[recognizer start];
7. 结束识别
[recognizer stop];

2.2 主要接口类说明

2.2.1 QCloudRealTimeRecognizer 初始化说明

QCloudRealTimeRecognizer 是实时语音识别类,提供两种初始化方法。
/**
* 初始化方法,调用者使用内置录音器采集音频
* @param config 配置参数,详见QCloudConfig定义
*/
- (instancetype)initWithConfig:(QCloudConfig *)config;

/**
* 初始化方法,调用者传递语音数据调用此初始化方法
* @param config 配置参数,详见QCloudConfig定义
* @param dataSource 语音数据数据源,必须实现QCloudAudioDataSource协议
*/
- (instancetype)initWithConfig:(QCloudConfig *)config dataSource:(id<QCloudAudioDataSource>)dataSource;

2.2.2 QCloudConfig 初始化方法说明

/**
* 初始化方法-直接鉴权
* @param appid 腾讯云 appId
* @param secretId 腾讯云 secretId
* @param secretKey 腾讯云 secretKey
* @param projectId 腾讯云 projectId
*/
- (instancetype)initWithAppId:(NSString *)appid
secretId:(NSString *)secretId
secretKey:(NSString *)secretKey
projectId:(NSString *)projectId;

/**
* 初始化方法-通过STS临时证书鉴权,详见https://cloud.tencent.com/document/product/598/33416
* @param appid 腾讯云appId
* @param secretId 腾讯云临时secretId
* @param secretKey 腾讯云临时secretKey
* @param token 对应的token
*/
- (instancetype)initWithAppId:(NSString *)appid
secretId:(NSString *)secretId
secretKey:(NSString *)secretKey
token:(NSString *)token;

2.2.3 获取SDK版本号接口说明

/**
* 获取SDK版本号
*/
+ (NSString*) getVersion;

2.2.4 话者分离 JSON 响应格式

话者分离版 SDK 的核心差异:服务端返回的 JSON 数据通过 realTimeRecognizerOnRawResult:jsonData: 回调原始透传,开发者自行解析。
{
"code": 0,
"message": "",
"sentences": {
"voice_text_str": "完整识别文本",
"sentence_list": [
{
"sentence_id": 0,
"sentence_type": 1,
"speaker_id": 0,
"sentence": "今天天气真好"
},
{
"sentence_id": 1,
"sentence_type": 0,
"speaker_id": -1,
"sentence": "是的啊"
}
]
},
"speaker_context_id": "a1b2c3d4e5f6..."
}

字段说明:
字段
类型
说明
sentence_id
int
句子 ID,从 0 开始递增
sentence_type
int
0=中间态(非稳态),1=稳态(最终确定结果)
speaker_id
int
说话人 ID:**-1**=未确定,0~9=对应说话人
sentence
string
当前句子的识别文本
voice_text_str
string
完整语音流的识别文本汇总
speaker_context_id
string
声纹 ID,24h 有效。下次识别传入可保持说话人 ID 连续性
说明:
兼容旧版 result.speaker_sentences 格式,建议优先使用新版 sentences.sentence_list

2.2.5 QCloudRealTimeRecognizerDelegate 方法说明

@protocol QCloudRealTimeRecognizerDelegate <NSObject>

@required
/**
* 原始 JSON 数据回调
* 话者分离版 SDK 通过此回调透传服务端返回的原始 JSON,开发者自行解析话者分离结果
* @param recognizer 实时语音识别实例
* @param jsonData 服务端返回的 JSON 字符串
*/
- (void)realTimeRecognizerOnRawResult:(QCloudRealTimeRecognizer *)recognizer jsonData:(NSString *)jsonData;


@optional
/**
* 一次识别成功回调
@param recognizer 实时语音识别实例
@param result 一次识别出的总文本, 实际是由SDK本地处理,将本次识别的realTimeRecognizerOnSegmentSuccessRecognize 识别结果拼接后一次性返回
*/
- (void)realTimeRecognizerDidFinish:(QCloudRealTimeRecognizer *)recognizer result:(NSString *)result;
/**
* 一次识别失败回调
* @param recognizer 实时语音识别实例
* @param result 识别结果信息,错误信息详情看QCloudRealTimeResponse内错误码
*/
- (void)realTimeRecognizerDidError:(QCloudRealTimeRecognizer *)recognizer result:(QCloudRealTimeResult *)result;


/**
* 开始录音回调
* @param recognizer 实时语音识别实例
* @param error 开启录音失败,错误信息
*/
- (void)realTimeRecognizerDidStartRecord:(QCloudRealTimeRecognizer *)recognizer error:(NSError *)error;
/**
* 结束录音回调
* @param recognizer 实时语音识别实例
*/
- (void)realTimeRecognizerDidStopRecord:(QCloudRealTimeRecognizer *)recognizer;
/**
* 录音音量实时回调用
* @param recognizer 实时语音识别实例
* @param volume 声音音量,取值范围(-40-0)
*/
- (void)realTimeRecognizerDidUpdateVolume:(QCloudRealTimeRecognizer *)recognizer volume:(float)volume;
/**
* 录音音量实时回调用
* @param recognizer 实时语音识别实例
* @param volume 声音音量,计算方式如下$A_{i}$为采集音频振幅值
* $$A_{mean} = \\frac{1}{n} \\sum_{i=1}^{n} A_{i}^{2}$$
* $$volume=\\max (10*\\log_{10}(A_{mean}), 0)$$
*/
- (void)realTimeRecognizerDidUpdateVolumeDB:(QCloudRealTimeRecognizer *)recognizer volume:(float)volume;



/**
* 语音流的开始识别
* @param recognizer 实时语音识别实例
* @param voiceId 语音流对应的voiceId,唯一标识
* @param seq flow的序列号
*/
- (void)realTimeRecognizerOnFlowRecognizeStart:(QCloudRealTimeRecognizer *)recognizer voiceId:(NSString *)voiceId seq:(NSInteger)seq;
/**
* 语音流的结束识别
* @param recognizer 实时语音识别实例
* @param voiceId 语音流对应的voiceId,唯一标识
* @param seq flow的序列号
*/
- (void)realTimeRecognizerOnFlowRecognizeEnd:(QCloudRealTimeRecognizer *)recognizer voiceId:(NSString *)voiceId seq:(NSInteger)seq;

/**
* 触发静音事件时回调
*/
-(void)realTimeRecognizerOnSliceDetectTimeOut;

/**
* 录音停止后回调一次,再次开始录音会清空上一次保存的文件
* @param recognizer 实时语音识别实例
* @param audioFilePath 音频文件路径
*/
- (void)realTimeRecognizerDidSaveAudioDataAsFile:(QCloudRealTimeRecognizer *)recognizer
audioFilePath:(NSString *)audioFilePath;

@end

2.2.6 QCloudAudioDataSource 协议说明

调用者不使用 SDK 内置录音器进行语音数据采集,自己提供语音数据需要实现此协议所有方法,可见 Demo 工程中的 QDAudioDataSource 实现。
/**
* 语音数据数据源,如果调用者需要自己提供语音数据需要, 调用者实现此协议中所有方法
* 提供符合以下要求的语音数据:
* 采样率:16k
* 音频格式:pcm
* 编码:16bit位深的单声道
*/
@protocol QCloudAudioDataSource <NSObject>

@required

/**
* 标识data source是否开始工作,执行完start后需要设置成YES, 执行完stop后需要设置成NO
*/
@property (nonatomic, assign) BOOL running;

@property (nonatomic, copy, readonly) NSString *audioFilePath;

/**
* 标识QCloudAudioRecorder是否正在录音
*/
@property (nonatomic, assign, readonly) BOOL recording;

/**
* SDK会调用start方法,实现此协议的类需要初始化数据源。didStart 是否开始 YES 往下执行,NO不会往下执行
*/
- (void)start:(void(^)(BOOL didStart, NSError *error))completion;
/**
* SDK会调用stop方法,实现此协议的类需要停止提供数据
*/
- (void)stop;
/**
* SDK会调用实现此协议的对象的此方法读取语音数据, 如果语音数据不足expectLength,read线程进入休眠。
* @param expectLength 期望读取的字节数,如果返回的NSData不足expectLength个字节,SDK会抛出异常。
*/
- (nullable NSData *)readData:(NSInteger)expectLength;

@end

2.2.7 QCloudVoiceLogger 日志设置说明

// 设置log等级为DEBUG级,上生产环境可选择VOICE_SDK_ERROR_LEVEL级别的log
[QCloudVoiceLogger setLoggerLevel:VOICE_SDK_DEBUG_LEVEL];
// 将log写入本地磁盘,demo工程默认打开,宿主层接入上生产环境需要关闭。
[QCloudVoiceLogger needLogFile:YES];
// (可选)注册log回调
[QCloudVoiceLogger registerLoggerListener:^(VoiceLoggerLevel loggerLevel, NSString * _Nonnull logInfo) {
NSLog(@"[ASR]-%@",logInfo);
} withNativeLog:NO];

3. 常见问题指引

3.1 回音消除指引

本小节主要介绍如何通过 iOS 原生 API 实现回音消除,下面将介绍实现方案(完整代码参考 Demo工程中的 QCloudAECDataSource 类的实现方法)。

3.1.1 回声消除方案介绍

1. 设置AVAudioSession支持边播放边录音的模式
AVAudioSession* session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord mode:AVAudioSessionModeDefault options:AVAudioSessionCategoryOptionDefaultToSpeaker error:&error];
2. 通过AVAudioEngine添加播放节点构建音频处理图
self.engine = [[AVAudioEngine alloc] init];
self.play_node = [[AVAudioPlayerNode alloc] init];
[self.engine attachNode:self.play_node];
[self.engine connect:self.play_node to:self.engine.outputNode format:nil];
3. 通过调用输入节点的setVoiceProcessingEnabled开启回声消除
[self.engine.inputNode setVoiceProcessingEnabled:YES error:&error];
4. 启动音频处理图
[self.engine startAndReturnError:&error];

3.1.2 回声消除方案适配的机型列表

1. 回声消除要求系统版本不低于iOS 13.0
2. 回声消除适配还会受到机型及系统的影响,以下列举已测试机型和系统的适配情况
机型
系统
适配
备注
iPhone 11 Pro
13.4
回声消除导致播放音量变化
iPhone 11 Pro Max
14.4.2
回声消除导致播放音量变化
iPhone 12
14.1
回声消除导致播放音量变化
iPhone 12 Pro
14.1
回声消除导致播放音量变化
iPhone 6s Plus
15.1
回声消除导致播放音量变化
iPhone 8 Plus
14.0.1
回声消除导致播放音量变化
iPhone SE2
17.0(beta5)
回声消除导致播放音量变化
iPhone X
15
回声消除导致播放音量变化
iPhone XR
16.6
回声消除导致播放音量变化
iPhone XS Max
14.2
回声消除导致播放音量变化
iPhone 12 mini
14.1
回声消除不生效
iPhone 13 mini
15
回声消除不生效
iPhone 14
16
回声消除不生效
iPhone 14 Plus
16.0.2
回声消除不生效
iPhone 14 Pro
16
回声消除不生效
iPhone 14 Pro Max
16
回声消除不生效
iPhone 11
16.1.1
-
iPhone 12 Pro Max
16.3.1
-
iPhone 13
15.0.1
-
iPhone 13 Pro
15.0.2
-
iPhone 13 Pro Max
15.0.2
-
iPhone SE3
15.4
-
iPhone XS
14.4
-


3.2 话者分离版常见问题

3.2.1 speaker_context_id 的作用?

speaker_context_id 是服务端返回的声纹 ID(24h 内有效)。将上次返回的 ID 通过 setApiParam:value: 传入下次识别任务,可使同一说话人的 ID 保持连续,适用于多轮对话场景。

3.2.2 sentence_type=0sentence_type=1 的区别?

sentence_type=0:中间态(非稳态),可能被后续结果修正,建议实时显示时使用灰色样式。
sentence_type=1:确定态(稳态),不会再改变,适合最终展示。

3.2.3 cancelstop 的区别?

stop:自然结束当前识别任务,等待服务端返回最终结果后再关闭连接。
cancel:立即终止识别,不等待服务端返回任何结果,直接关闭 WebSocket 连接。