跳到主要内容

设备主动 AI 场景

TopStepAIKit 可以响应设备发起的 AI 对话、录音、语音翻译、AI 问答、语音表盘和语音打车,也支持 App 发起同一套设备协同会话。DeviceBridge 与 Provider 编排由 SDK 内部完成;App 负责本地资源准备、页面生命周期和业务输出。

启动资格​

supportsAIFeatures: 只能用于展示入口,不能授权启动。设备协同请求必须通过完整的 TSAIStartRequest 调用 startEligibilityForRequest:,详见能力与启动资格。

通用设备协同会话​

TSAIContext 遵循 TSAIDeviceAISessionInterface。通用入口适用于语音翻译、语音问答、语音表盘和语音打车;AI 对话与录音继续使用各自专用接口。

注册设备发起路由​

TSAIContext *context = [TSAIKit sharedInstance].activeContext;

[context registerDeviceAISessionHandlerForUseCase:TSAIUseCaseVoiceTranslation
prepareHandler:^(TSAIStartRequest *request, TSAICompletionBlock completion) {
// 仅准备本地非 UI 资源,例如 AudioSession、播放器和业务上下文。
completion(YES, nil);
}
activationHandler:^(TSAIStartRequest *request) {
// App 与设备都已就绪;只能从这里打开业务页面。
}
inputCompletionHandler:^(TSAIStartRequest *request) {
// 设备采音自然结束;ASR、翻译和 TTS 仍可继续。
}
terminationHandler:^(TSAIStartRequest *request, BOOL interrupted, NSError *error) {
// 幂等释放本地资源并关闭页面。
}
voiceDataHandler:nil];
- (void)registerDeviceAISessionHandlerForUseCase:(TSAIUseCase)useCase
prepareHandler:(nullable TSAIDeviceAISessionPrepareHandler)prepareHandler
activationHandler:(nullable TSAIDeviceAISessionActivationHandler)activationHandler
inputCompletionHandler:(nullable TSAIDeviceAISessionInputCompletionHandler)inputCompletionHandler
terminationHandler:(nullable TSAIDeviceAISessionTerminationHandler)terminationHandler
voiceDataHandler:(nullable TSAIDeviceAISessionVoiceDataHandler)voiceDataHandler;

注册时 inputCompletionHandler 必填。语音打车使用 Opus 输入时 voiceDataHandler 也必填;它按顺序提供 opusData、可用时的 pcmData 和 isFinal。

App 发起与停止​

TSAIStartEligibility *eligibility = [context startEligibilityForRequest:request];
if (eligibility.support == TSAICapabilitySupported) {
[context startDeviceAISessionFromAppWithRequest:request
completion:^(BOOL success, NSError *error) {
if (!success) {
TSLog(@"设备协同启动失败: %@", error.localizedDescription);
}
}];
}

[context stopDeviceAISessionWithRequest:request completion:nil];
- (void)startDeviceAISessionFromAppWithRequest:(TSAIStartRequest *)request
completion:(nullable TSAICompletionBlock)completion;
- (void)stopDeviceAISessionWithRequest:(TSAIStartRequest *)request
completion:(nullable TSAICompletionBlock)completion;

启动 completion 只有在本地准备与设备同步均完成后才成功。停止时必须传 Handler 收到或启动时使用的同一个请求对象。

对话翻译产品模式​

- (void)startDeviceConversationTranslationWithMode:
(TSAIConversationTranslationMode)mode
completion:(nullable TSAICompletionBlock)completion;
- (void)stopDeviceConversationTranslationWithCompletion:
(nullable TSAICompletionBlock)completion;

产品模式包括 FaceToFace、Private 和 Portable,它们只控制设备页面与拾音组合;具体每轮翻译仍通过设备协同会话处理。

设备发起 AI 对话​

通过 AI 助手监听设备请求:

[context.assistant registerOnAIChatDeviceEvent:^(TSAIChatDeviceEvent event) {
switch (event) {
case TSAIChatDeviceEventRequestStart:
// 调用 startChatWithConfig: 准备会话;此时不要打开页面。
break;
case TSAIChatDeviceEventRequestEnd:
// 调用 stopChatWithTaskId: 并关闭页面
break;
case TSAIChatDeviceEventInterrupted:
// 结束页面并提示中断原因
break;
}
}];

设备事件只表示请求,不代表 SDK 业务会话已自动改变状态。收到 RequestStart 后先启动本地会话,只有 onEvent 收到 TSAIChatEventTypeSessionStarted 才能打开页面。

设备发起麦克风识别​

设备请求录音但 App 无法继续时,应明确拒绝:

[context.speech rejectDeviceMicRecognitionWithCompletion:^(BOOL success, NSError *error) {
if (!success) {
TSLog(@"拒绝设备麦克风请求失败: %@", error.localizedDescription);
}
}];

可以继续时,使用 recognizeSpeechWithDeviceMicConfig: 启动识别,并通过 stopDeviceMicRecognitionWithTaskId: 正常结束。

设备发起语音翻译​

AIKit 负责设备音频接入、ASR、翻译和 TTS;App 实现 TSAIDeviceVoiceTranslationOutputSink,负责缓存并播放有符号 Int16 小端 PCM。

注册输出对象​

[context registerDeviceVoiceTranslationOutputSink:self];

Context 对输出对象使用弱引用,业务对象销毁前应传 nil 注销。

输出协议​

- (void)prepareForTaskId:(NSString *)taskId
sampleRate:(NSInteger)sampleRate
channelCount:(NSInteger)channelCount;

- (void)appendInt16PCMData:(NSData *)pcmData taskId:(NSString *)taskId;
- (void)finishAndPlayTaskId:(NSString *)taskId;
- (void)setPlaybackState:(TSAIDeviceVoicePlaybackState)state
forTaskId:(NSString *)taskId;
- (void)discardTaskId:(NSString *)taskId;
播放指令App 行为
Stopped停止播放并释放当前资源
Playing开始播放
Paused暂停当前任务
Resumed恢复当前任务

同一 taskId 的 PCM 必须按回调顺序追加,不要混合多个任务的缓冲区。

设备发起 AI 问答​

AIKit 负责 ASR、答案生成和 TTS;App 实现完整音频输出协议:

@interface MyPlayer () <TSAIDeviceQuestionAnswerOutputSink>
@end

[context registerQuestionAnswerOutputSink:self];
- (void)playQuestionAnswerTTSResult:(TSAITTSResult *)result
taskId:(NSString *)taskId
completion:(nullable TSAICompletionBlock)completion;

- (void)stopQuestionAnswerPlaybackWithTaskId:(NSString *)taskId;

如果播放器支持边生成边播放,可额外遵循 TSAIDeviceQuestionAnswerStreamingOutputSink:

- (void)appendQuestionAnswerTTSStreamChunk:(TSAITTSStreamChunk *)chunk
taskId:(NSString *)taskId;

- (void)finishQuestionAnswerTTSStreamWithTaskId:(NSString *)taskId
completion:(nullable TSAICompletionBlock)completion;

流式分片由 AIKit 在主线程按 sequenceIndex 顺序调用。如果输出对象不支持流式扩展,SDK 回退到完整 TSAITTSResult 播放。

设备发起 AI 录音​

[context.audioRecord registerOnRequestStartAIAudioRecording:^(TSAIAudioRecordScene scene) {
// 检查隐私授权、存储、网络和互斥任务后启动
}];

[context.audioRecord registerOnRequestStopAIAudioRecording:^{
// 停止 AI 录音并向设备回报状态
}];

详见 AI 录音。

生命周期清理​

[context registerDeviceVoiceTranslationOutputSink:nil];
[context registerQuestionAnswerOutputSink:nil];
[context.assistant registerOnAIChatDeviceEvent:nil];
[context.speech registerDeviceMicRecognitionStateDidChanged:nil];
[context.audioRecord registerOnRequestStartAIAudioRecording:nil];
[context.audioRecord registerOnRequestStopAIAudioRecording:nil];

注意事项​

  1. App 对所有设备主动请求仍拥有最终授权权;精确资格失败时由 AIKit 拒绝,App 本地准备失败时必须通过 completion 返回错误。
  2. PCM 和 TTS 播放由 App 选择音频路由,必须正确处理来电、AudioSession 抢占和页面退出。
  3. 输出对象的完成回调必须调用一次,否则 AIKit 无法结束对应播放流程。
  4. 切换 Context 前停止所有正在进行的设备主动任务并注销输出对象。
  5. inputCompletionHandler 表示输入租约释放,不是取消或会话终态,不得因此终止下游任务。