繁体   English   中英

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

[英]Audio interruption when iOS application is recording in background

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

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

  - (void)audioRecorderEndInterruption:(AVAudioPlayer *)p withOptions:(NSUInteger)flags

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

- (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));
    }
}

在这种情况下,在中断开始时会触发handleInterruption:,但在中断结束时不会触发(应在将InterruptionType设置为AVAudioSessionInterruptionTypeEnded的情况下触发)

为了解决这个问题,我决定在中断开始时设置一个标志( interruptBeganWhileInBackgroundMode ),以使应用程序得知在进入前台时发生了中断。 这样我就可以管理中断的结束了。

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

我尝试了两种实现。

解决方法1 在中断开始时,将[记录器暂停]放入handleInterruption:中,并在设置了中断标志时在comeingForeground:方法中管理[记录器记录]。 在这种情况下,当应用程序返回到前台时,录制会立即继续进行, 但不是恢复,而是由录制器擦除文件并重新开始新的录制,因此中断之前录制的所有内容都会丢失

解决方案2 在handleInterruption中放置[recorder stop]:当中断开始时,要保存文件,以确保保留记录的数据。 该记录已保存, 但是当应用程序进入前台时,它将停顿约十秒钟,然后用户才能再次进行交互 ,就好像有一个使UI冻结的进程(保存文件?)一样。

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

我注意到,iOS7中的Apple 语音备忘录应用程序可以正确管理这些背景中断(它停止并保存录音),尽管它在进入前景时显示00:00:00文件长度。 iTalk应用程序可以完美地管理它,当到达前台时会自动恢复记录。

是否有人为后台录制应用程序的音频中断管理找到解决方法? 我在许多开发者网站上找到了很多人在寻找它,但是没有答案……谢谢!

我本人也一直在经历同样的问题。 似乎iOS7 AVAudioRecorder中存在一个如何处理中断的错误。 它不会关闭文件,而是像我认为文档所述那样暂停了文件。 我还无法弄清是什么原因使应用程序重新回到前台。 就我而言,我会在10秒钟后看到AVAudioRecorder完成(成功标志设置为NO)。

我最终使用Audio Queues重写了录音机。 我在这里(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);

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

不知道/认为这将与该主题的原始作者有关,但是这是我的经验:

由于AVAudioSessionInterruptionNotification的缘故,我到了这里。 .began风味符合预期,但.end风味没有。 就我而言,这是因为我使用了两个AVPlayer实例:一个用于播放音乐,另一个用于静音,而第一个实例则努力开始播放新曲目(否则,如果下一首曲目,iOS将在后台暂停我的应用程序加载速度不够快)。

事实证明,这不是最聪明的解决方案,并且以某种方式弄乱了通知系统。 放弃第二个AVPlayer(静音播放其中一个)导致.end被按预期方式触发。 当然,我找到了通知问题的答案/解决方案,但现在剩下的是旧的... :-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM