Skip to main content

AI Recording (TSAudioRecordInterface)

The recording contract includes normal device recording and AI recording. AI recording may be app-initiated or device-initiated and returns transcripts, events, runtime errors, and a final report through one provider-neutral model.

Interface and feature query​

TSAIContext *context = [TSAIKit sharedInstance].activeContext;
id<TSAudioRecordInterface> audioRecord = context.audioRecord;
ScenarioFeature
Normal recordingTSAIFeatureNormalAudioRecording
On-site AI recordingTSAIFeatureAIAudioRecording
Call AI recordingTSAIFeatureCallAudioRecording

Data models​

TSAIAudioRecordConfig​

PropertyTypeDescription
audioRouteConfigurationTSAIAudioRouteConfiguration *Input route; output must be None; nil requests automatic routing
recordingSceneTSAIAudioRecordSceneOn-site or call recording
languageTSAILanguageInput language; Unknown uses the current app language
allowRecordingWhileOfflineBOOLAllow supported providers to record offline and sync later
enableSpeakerDiarizationBOOLEnable speaker diarization

defaultConfig uses on-site recording and disables offline recording and diarization.

TSAIAudioRecordSessionResult​

typeValid fieldsDescription
Transcripttext, sentenceIndex, isSentenceFinal, speakerSegmentsStreaming transcript
EventeventType, timestamp, evidence, detailsSession event
ErrorerrorRuntime error
Finishtranscripts, sessionEvents, rawAudioFilePathFinal session report

The final report also exposes isStoppedByInterruption, isOfflineRecording, and hadNetworkDisconnection.

Transcript results also expose languageCode, sequence, and requestId; event results expose timeSinceSessionStart. A TSAIAudioRecordSpeakerSegment contains speakerId, startTimeMilliseconds, endTimeMilliseconds, associatedTranscriptSequence, and text.

Normal recording​

- (void)setNormalAudioRecordingMaximumDuration:(NSUInteger)maximumDuration
completion:(TSAICompletionBlock)completion;
- (void)getNormalAudioRecordingMaximumDuration:(nullable TSAudioRecordMaximumDurationResultBlock)completion;
- (void)startNormalAudioRecording:(TSAICompletionBlock)startCompletion
finishHandler:(nullable TSAudioRecordFinishHandler)finishHandler;
- (void)stopNormalAudioRecording:(TSAICompletionBlock)completion;

Maximum duration is in minutes and must be from 1 through 240.

[audioRecord startNormalAudioRecording:^(BOOL success, NSError *error) {
if (!success) {
TSLog(@"Normal recording failed to start: %@", error.localizedDescription);
}
} finishHandler:^(TSAudioRecordStopReason reason, NSError *error) {
TSLog(@"Normal recording ended: %lu", (unsigned long)reason);
}];

AI recording​

- (void)startAIAudioRecordingWithConfig:(nullable TSAIAudioRecordConfig *)config
startCompletion:(TSAICompletionBlock)startCompletion
didReceiveAudioData:(nullable TSAudioRecordDataReceivedBlock)didReceiveAudioData
didReceiveSessionResult:(nullable TSAIAudioRecordSessionResultHandler)didReceiveSessionResult
finishHandler:(nullable TSAudioRecordFinishHandler)finishHandler;
- (void)stopAIAudioRecording:(TSAICompletionBlock)completion;
TSAIAudioRecordConfig *config = [TSAIAudioRecordConfig defaultConfig];
config.language = TSAILanguageEnglishUS;
config.enableSpeakerDiarization = YES;

[audioRecord startAIAudioRecordingWithConfig:config
startCompletion:^(BOOL success, NSError *error) {
if (!success) {
TSLog(@"AI recording failed to start: %@", error.localizedDescription);
}
}
didReceiveAudioData:^(NSData *audioData) {
// Avoid blocking I/O in this high-frequency callback.
}
didReceiveSessionResult:^(TSAIAudioRecordSessionResult *result) {
if (result.type == TSAIAudioRecordSessionResultTypeTranscript) {
TSLog(@"Transcript: %@", result.text);
} else if (result.type == TSAIAudioRecordSessionResultTypeFinish) {
TSLog(@"Session complete: %@", result.transcripts);
}
}
finishHandler:^(TSAudioRecordStopReason reason, NSError *error) {
TSLog(@"Audio stream ended: %lu", (unsigned long)reason);
}];

finishHandler means only that the underlying audio stream ended. The semantic AI session ends when didReceiveSessionResult receives a Finish result.

Device-initiated recording​

- (void)registerOnRequestStartAIAudioRecording:(nullable TSAIAudioRecordRequestStartBlock)block;
- (void)registerOnRequestStopAIAudioRecording:(nullable dispatch_block_t)block;
- (void)registerAIAudioRecordingDidInterrupt:(nullable TSAIAudioRecordInterruptBlock)block;
- (void)registerOnAIAudioRecordingVoiceDataReceived:(nullable TSAudioRecordVoiceDataReceivedBlock)block;
- (void)registerAIAudioRecordingStateDidChanged:(nullable TSAIAudioRecordStateBlock)block;
[audioRecord registerOnRequestStartAIAudioRecording:^(TSAIAudioRecordScene scene) {
TSAIAudioRecordConfig *config = [TSAIAudioRecordConfig defaultConfig];
config.recordingScene = scene;
// Eligibility already passed. Prepare locally but do not open UI yet.
}];

[audioRecord registerOnRequestStopAIAudioRecording:^{
[audioRecord stopAIAudioRecording:^(BOOL success, NSError *error) {
TSLog(@"Device stop request: %@", success ? @"handled" : error.localizedDescription);
}];
}];

The start callback runs only after exact eligibility passes. Prepare locally with startAIAudioRecordingWithConfig:... and open the recording UI only after startCompletion succeeds, when both app and device are active.

Report a real state transition to the device with:

- (void)reportAIAudioRecordingStartSuccessWithScene:(TSAIAudioRecordScene)scene
completion:(nullable TSAICompletionBlock)completion;
- (void)reportAIAudioRecordingStoppedWithCompletion:(nullable TSAICompletionBlock)completion;

Do not report success before the recording has actually started or stopped.

Key enums​

TSAIAudioRecordSceneDescription
UnknownUnknown scene
OnSiteOn-site recording
CallCall recording
TSAIAudioRecordStateDescription
UnknownUnknown state
IdleIdle
StartingStarting
RecordingRecording
StoppingStopping
InterruptedInterrupted
TSAIAudioRecordInterruptReasonDescription
UnknownUnknown reason
LowBatteryDevice battery is low
IncomingCallIncoming call interruption
OtherOther interruption

Stop reasons and session-result types​

EnumValues and raw values
TSAudioRecordStopReasonUnknown = 0, UserInitiated = 1, MaxDurationReached = 2, DeviceError = 3, StorageFull = 4, Disconnected = 5, Interrupted = 6
TSAIAudioRecordSessionResultTypeTranscript = 0, Event = 1, Error = 2, Finish = 3

Add the corresponding enum prefix to shortened values, for example TSAudioRecordStopReasonUserInitiated.

Important notes​

  1. Obtain explicit user consent and show a clear recording indicator.
  2. Recording input language does not accept TSAILanguageAuto.
  3. Avoid expensive work in audio, transcript, and event callbacks.
  4. Unregister all device-request, data, interruption, and state listeners when leaving the feature.
  5. Offline recording works only when both the provider and the configuration allow it.