iPhone:保持录音应用程序在后台运行

iPhone:保持录音应用程序在后台运行,iphone,background,avplayer,avaudiorecorder,Iphone,Background,Avplayer,Avaudiorecorder,我已经为我的问题寻找了合适的答案,但到目前为止,我没有找到任何有用的答案。 我想记录环境中的分贝。如果超过特定阈值,应用程序应播放声音或歌曲文件。到目前为止一切正常,但我很难让应用程序在后台运行。 我已经添加了属性“应用程序不在后台运行”,并将其值设置为“否”。我读过,应该在“所需背景模式”中添加“外部附件”元素。我也补充了这一点,但仍然不起作用。 我正在使用AVAudioRecorder录制声音,使用AVPlayer播放声音/音乐文件。首先,我使用了mpmediaccontrolleriPod

我已经为我的问题寻找了合适的答案,但到目前为止,我没有找到任何有用的答案。 我想记录环境中的分贝。如果超过特定阈值,应用程序应播放声音或歌曲文件。到目前为止一切正常,但我很难让应用程序在后台运行。 我已经添加了属性“应用程序不在后台运行”,并将其值设置为“否”。我读过,应该在“所需背景模式”中添加“外部附件”元素。我也补充了这一点,但仍然不起作用。 我正在使用
AVAudioRecorder
录制声音,使用
AVPlayer
播放声音/音乐文件。首先,我使用了
mpmediaccontroller
iPodMusicPlayer
,但它会抛出一个异常以及属性“Required background modes”

编辑: 我在iOS 6上使用xCode 4.5

编辑2: 当我将字符串viop添加到“必需的后台模式”时,它似乎在后台继续录制。但它在后台时仍然不播放音乐文件。我也尝试添加“音频”值,但没有帮助

编辑3: 我已经咨询了苹果的开发者参考。似乎您必须配置AVAudioSession。有了这个,它似乎起作用了()。但现在我在播放多个文件时遇到麻烦,因为一旦第一首曲目播放完毕,应用程序将再次进入暂停模式。据我所知,不可能用多个文件初始化AVPlayer或AVAudioPlayer。我使用委派方法AudioPlayerDidFinishPlay:成功:设置下一个曲目,但它不起作用

编辑4:好的,一种可能是避免停止录音机,即删除[record stop],这样它甚至可以在播放音乐时录制声音。这是一个可行的解决方案,但我仍然很欣赏任何其他(更好的)解决方案。一个解决方案,不需要让录音机一直运行

有关守则: 我初始化viewDidLoad方法中的所有内容:

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view.

    //[MPMusicPlayerController applicationMusicPlayer];

    NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];

NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithFloat: 44100.0],                 AVSampleRateKey,
                          [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
                          [NSNumber numberWithInt: 1],                         AVNumberOfChannelsKey,
                          [NSNumber numberWithInt: AVAudioQualityMax],         AVEncoderAudioQualityKey,
                          nil];

NSError *error;

recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
lowPassResults = -120.0;
thresholdExceeded = NO;

if (recorder) {
    [recorder prepareToRecord];
    recorder.meteringEnabled = YES;
    [recorder record];
            levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.03 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];

    } else {
    NSString* errorDescription = [error description];
    NSLog(errorDescription);
    }
}
每0.03秒调用一次的levelTimer回调:

- (void)levelTimerCallback:(NSTimer *)timer {
//refreshes the average and peak power meters (the meter uses a logarithmic scale, with -160 being complete quiet and zero being maximum input
[recorder updateMeters];

const double ALPHA = 0.05;

float averagePowerForChannel = [recorder averagePowerForChannel:0]; 

    //adjust the referential
    averagePowerForChannel = averagePowerForChannel / 0.6;

    //converts the values 
    lowPassResults = ALPHA * averagePowerForChannel + (1.0 - ALPHA) * lowPassResults;   

    float db = lowPassResults + 120;
    db = db < 0? 0: db;

    if(db >= THRESHOLD)
    {
        [self playFile];
    }
}
有人能帮我解决这个问题吗?我还错过了什么吗?

试试这个

AppDelegate.m

- (void)applicationDidEnterBackground:(UIApplication *)application
{
   __block UIBackgroundTaskIdentifier task = 0;
   task=[application beginBackgroundTaskWithExpirationHandler:^{
   NSLog(@"Expiration handler called %f",[application backgroundTimeRemaining]);
   [application endBackgroundTask:task];
   task=UIBackgroundTaskInvalid;
   }];
}

我和你遇到了同样的问题。你完成了吗?你能分享一下你的发现吗?感谢muchIt现在已经是几个月前的事了,但我想我保留了我在上面的帖子(编辑4)中描述的解决方案。不幸的是,我没有机会再次查找代码,因为我不再在那家公司工作了,在那里我开发了一个有这个问题的应用程序。
- (void)applicationDidEnterBackground:(UIApplication *)application
{
   __block UIBackgroundTaskIdentifier task = 0;
   task=[application beginBackgroundTaskWithExpirationHandler:^{
   NSLog(@"Expiration handler called %f",[application backgroundTimeRemaining]);
   [application endBackgroundTask:task];
   task=UIBackgroundTaskInvalid;
   }];
}