【发布时间】:2015-07-10 03:15:17
【问题描述】:
我有一个应用程序,其中录音是主要和最重要的部分。但是用户可以切换到表格视图控制器,其中显示所有记录并且不执行记录。
问题是哪种方法更好:“启动和停止音频系统或只是启动它”。显然第一个更正确,例如“在需要时分配,在使用时释放”。我将在这个问题上展示我的想法,并希望在技术人员中获得赞同或反对意见。
当我第一次构造 AudioController.m 时,我实现了打开/关闭音频会话和启动/停止音频单元的方法。我想在录制未激活时停止音频系统。我使用了以下代码:
- (BOOL)startAudioSystem {
// open audio session
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
if (![audioSession setActive:YES error:&err] ) {
NSLog(@"Couldn't activate audio session: %@", err);
}
// start audio unit
OSStatus status;
status = AudioOutputUnitStart([self audioUnit]);
BOOL noErrors = err == nil && status == noErr;
return noErrors;
}
和
- (BOOL)stopAudioSystem {
// stop audio unit
BOOL result;
result = AudioOutputUnitStop([self audioUnit]) == noErr;
HANDLE_RESULT(result);
// close audio session
NSError *err;
HANDLE_RESULT([[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&err]);
HANDLE_ERROR(err);
BOOL noErrors = err == nil && result;
return noErrors;
}
我发现这种方法存在问题,原因如下:
- 音频系统启动延迟。这意味着,recording_callback() 有一段时间没有被调用。我怀疑是 AudioOutputUnitStart 负责。我试图用这个函数调用注释掉这一行并将其移至初始化。延迟消失了。
- 如果用户在录制视图和表格视图之间切换非常非常快(音频系统的启动和停止也非常快),它会导致媒体服务的死亡(我知道观察 AVAudioSessionMediaServicesWereResetNotification 在这里可以有所帮助,但它不是点)。
为了解决这些问题,我用我设法发现的其他方法修改了 AudioController.m:在应用程序激活时启动音频系统,并且在应用程序终止之前不要停止它 在这种情况下,有还有几个问题:
- CPU 使用率
- 如果音频类别设置为仅录制,则当用户浏览表视图控制器时无法播放其他音频。
如果像这样取消recording_callback()中的任何处理,第一个令人惊讶的是不是什么大问题:
static OSStatus recordingCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
AudioController *input = (__bridge AudioController*)inRefCon;
if(!input->shouldPerformProcessing)
return noErr;
// processing
// ...
//
return noErr;
}
在不需要录制且不执行其他操作时,在真实设备上执行此 CPU 使用率等于 0%。
第二个问题可以通过将音频类别切换到 RecordAndPlay 并启用混合或忽略该问题来解决。例如,在我的情况下,应用程序需要外部设备使用 mini Jack,因此不能并行使用耳机。
尽管如此,第一种方法更适合我,因为我喜欢在不再需要时关闭/清理每个流/资源。而且我想确定除了启动音频系统之外确实没有其他选择。请确保我不是唯一提出此解决方案的人,而且它是正确的。
【问题讨论】:
标签: ios audio audiounit recording audiosession