iOS应用程序在后台录制时的音频中断

Den*_*nis 6 background interrupt avaudiorecorder ios

我的iPad声音应用程序(iOS 7.1)能够在后台录制.只要录制在后台不中断,一切都可以.例如,如果一个人有(愚蠢的?)想法在录制内容时开始听音乐.

我试图以不同的方式管理这种中断,但没有成功.问题是,

  - (void)audioRecorderEndInterruption:(AVAudioPlayer *)p withOptions:(NSUInteger)flags
Run Code Online (Sandbox Code Playgroud)

当应用程序在后台发生中断时,永远不会被触发.然后我尝试在另一个解决方案中实现AVAudioSessionInterruptionNotification和handleInterruption:方法as

- (void) viewDidAppear:(BOOL)animated
{
......
AVAudioSession *session=[AVAudioSession sharedInstance];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(handleInterruption:)
                                             name:AVAudioSessionInterruptionNotification
                                           object:session];
.......
}
// interruption handling

- (void)handleInterruption:(NSNotification *)notification
{
    try {
        UInt8 theInterruptionType = [[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] intValue];
        NSLog(@"Session interrupted > --- %s ---\n", theInterruptionType == AVAudioSessionInterruptionTypeBegan ? "Begin Interruption" : "End Interruption");

        .... MANAGE interruption begin    
        interruptionBeganWhileInBackgroundMode = TRUE;

        }            
        if (theInterruptionType == AVAudioSessionInterruptionTypeEnded) {

        .... MANAGE interruption end

        }
    } catch (CAXException e) {
        char buf[256];
        fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,handleInterruption:在中断开始时被触发,但不是在中断结束时(在中断类型设置为AVAudioSessionInterruptionTypeEnded时触发)

为了解决这个问题,我决定设置一个标志(interruptionBeganWhileInBackgroundMode),当中断开始时,应用程序被告知前进时发生了中断.这样我就可以管理中断的结束.

它可能看起来很聪明,但事实并非如此!这就是为什么......

我试过两个实现.

解决方案1.在handleInterruption中设置[记录器暂停]:当中断开始时,并在设置中断标志时在comingForeground:方法中管理[记录器记录].在这种情况下,当应用程序返回到前台时,记录立即进行,但是不是恢复,记录器擦除文件并重新开始新的记录,以便在中断之前记录的所有内容都丢失.

解决方案2.在handleInterruption中放置[记录器停止]:当中断开始时,保存文件,以确保保留记录的数据.保存此记录,但是当应用程序即将到来时,它会停止大约十秒钟,然后用户才能再次进行交互,就好像有一个进程(文件保存?)使UI保持冻结状态.

最后一点:我在此应用程序的iPhone版本中遇到了完全相同的问题:当应用程序处于前台并且发生电话呼叫时,一切正常.但是当我的应用程序处于后台时发生电话呼叫时,我会看到与iPad版本相同的不良行为.

我注意到iOS7 中的Apple的语音备忘录应用程序正确地管理这些后台中断(它停止并保存录制),尽管它在前景时显示文件长度为00:00:00.该的iTalk应用程序管理它完美,未来的前景时自动恢复录制.

是否有人为背景录制应用找到了音频中断管理的解决方法?我发现很多人在很多开发者网站上都在寻找,但没有回答......谢谢!

小智 2

我自己也经历过同样的问题。iOS7 AVAudioRecorder 似乎在处理中断的方式上存在一个错误。它没有像我相信文档所说的那样暂停,而是关闭文件。我无法弄清楚是什么让应用程序回到前台时停止运行。就我而言,10 秒后我会看到 AVAudioRecorder 完成(成功标志设置为 NO)。

我最终使用音频队列重写了录音机。我在这里找到了一些示例代码(git@github.com:vecter/Audio-Queue-Services-Example.git),它们有助于在 Objective-C 环境中进行设置,并且 Apple SpeakHere 演示有一些处理中断通知的代码。

本质上,我在中断开始时停止录制,并打开一个警报以供用户保存文件。如果应用程序在后台时启动中断,则此警报将推迟到通过 UIApplicationDidBecomeActiveNotification 为止。

另一件需要注意的事情是,音频队列中似乎存在一个小错误,即 AudioQueueStart 方法有时会返回 -50。如果你添加

AudioSessionInitialize(NULL, NULL,nil,(__bridge  void *)(self));
UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
                        sizeof(sessionCategory),
                        &sessionCategory
                        );
AudioSessionSetActive(true);
Run Code Online (Sandbox Code Playgroud)

在任何 AudioQueue 方法之前,错误都会消失。这些方法被标记为已弃用,但似乎是必要的。