音频会话中断结束后,AVAudioRecorder无法在后台录制

时间:2015-03-13 15:34:53

标签: ios objective-c xcode avaudiorecorder avaudiosession

我正在我的应用中录制音频,包括前景和后台。我还处理AVAudioSessionInterruptionNotification以在中断开始时停止录制并在结束时再次开始。虽然在前台它按预期工作,当应用程序在后台录制并且我接到一个呼叫时,它不会在呼叫结束后再次开始录制。我的代码如下:

        - (void)p_handleAudioSessionInterruptionNotification:(NSNotification *)notification
        {
            NSUInteger interruptionType = [[[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];

            if (interruptionType == AVAudioSessionInterruptionTypeBegan) {
                if (self.isRecording && !self.interruptedWhileRecording) {

                    [self.recorder stop];

                    self.interruptedWhileRecording = YES;
                    return;
                }
            }

            if (interruptionType == AVAudioSessionInterruptionTypeEnded) {
                if (self.interruptedWhileRecording) {
                    NSError *error = nil;
                    [[AVAudioSession sharedInstance] setActive:YES error:&error];

                    NSDictionary *settings = @{
                                       AVEncoderAudioQualityKey: @(AVAudioQualityMax),
                                       AVSampleRateKey: @8000,
                                       AVFormatIDKey: @(kAudioFormatLinearPCM),
                                       AVNumberOfChannelsKey: @1,
                                       AVLinearPCMBitDepthKey: @16,
                                       AVLinearPCMIsBigEndianKey: @NO,
                                       AVLinearPCMIsFloatKey: @NO
                                       };

                    _recorder = [[AVAudioRecorder alloc] initWithURL:fileURL settings:settings error:nil];

                    [self.recorder record];

                    self.interruptedWhileRecording = NO;
                    return;
                }
            }
        }

请注意,fileURL指向NSDocumentDirectory子目录中的新caf文件。配置背景模式音频。我也试过voip和沉默,但都没有成功。

AVAudioSessionInterruptionTypeEnded块中的NSError是一个OSStatus错误560557684,我还没有找到解决方法。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:19)

错误560557684适用于dimensionIndices[0..3]。当您的后台应用程序尝试激活不与其他音频会话混合的音频会话时,会发生这种情况。后台应用程序无法启动不会与前台应用程序的音频会话混合的音频会话,因为这会中断用户当前正在使用的应用程序的音频。

要解决此问题,请务必将会话类别设置为可混合的会话类别,例如int getOffset(int [] sizes, int [] indices) { int ofs = indices[sizes.length - 1]; for (int d = sizes.length - 2; d >= 0; --d) { ofs = ofs * sizes[d] + indices[d]; } return ofs; } 。另外,请务必设置类别选项AVAudioSessionErrorCodeCannotInterruptOthers(必填)和AVAudioSessionCategoryPlayback(可选)。例如:

AVAudioSessionCategoryOptionMixWithOthers

错误代码560557684实际上是4个ascii字符'!int'在32位整数。错误代码列在AVAudioSession.h文件中(另请参阅AVAudioSession):

AVAudioSessionCategoryOptionDuckOthers

答案 1 :(得分:10)

我添加了以下内容

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

在配置AVAudioSession之前,它工作正常。仍然不知道可能会出现什么错误。

答案 2 :(得分:0)

当我的应用程序在后台使用AVSpeechSynthesizer().speak()时,我遇到了同样的错误。 @progmr的回答为我解决了这个问题,尽管我也不得不打电话给AVAudioSession.sharedInstance().setActive(true)。 为了完整起见,这是我在 Swift 5 中的代码。

application(_:didFinishLaunchingWithOptions:)中:

do {
  try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback,
                                                  options: [.mixWithOthers,
                                                            .duckOthers])

} catch let error as NSError {
  print("Error setting up AVAudioSession : \(error.localizedDescription)")
}

然后在我的视图控制器中:

do {
  try AVAudioSession.sharedInstance().setActive(true)
} catch let error as NSError {
  print("Error : \(error.localizedDescription)")
}

let speechUtterance = AVSpeechUtterance(string: "Hello, World")
let speechSynth = AVSpeechSynthesizer()
speechSynth.speak(speechUtterance)

注意:调用setActive(true)时,它会减少当时播放的其他任何东西的音量。要在以后调高音量,您需要致电setActive(false)-对我来说,这样做的最佳时间是在接到通知后,我用相应的AVSpeechSynthesizerDelegate方法完成了演讲。