AVAudioPlayer无法在后台播放带有NSTimer的音乐

时间:2011-10-19 03:13:50

标签: iphone ios4 background nstimer avaudioplayer

我想使用NSTimer播放AVAudioPlayer音乐,但[player prepareToPlay]返回NO&不在后台播放。

有人可以给我一些想法吗?

这是我的代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(playMusic:) userInfo:nil repeats:NO];
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)playMusic:(NSTimer *)timer{
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    NSString *fileName = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Apologize.mp3"];
    NSURL *fileUrl = [NSURL fileURLWithPath:fileName];
    NSError *error;
    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:&error];
    if ([player prepareToPlay]) {
        [player play];
        NSLog(@"start!");
    }else{
        NSLog(@"error msg :%@",error);
    }
}

- (void)applicationDidEnterBackground:(UIApplication *)application {

    if ([[UIApplication sharedApplication] respondsToSelector:@selector(beginReceivingRemoteControlEvents)]){
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    }

    UIBackgroundTaskIdentifier backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
    //        /* just fail if this happens. */
        [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
    }];
}

3 个答案:

答案 0 :(得分:1)

您需要在 viewDidLoad

中执行此初始化操作
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:@"test"
                                                          ofType:@"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL
                                                          error:nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];

这是用于音频初始化。在这里,使用名为 test 的MP3,在项目中导入。 请注意, beginReceivingRemoteControlEvents 部分非常重要。没有它,你就无法从背景开始播放,只是继续听已经从前台播放的音乐。

现在您需要收听事件 didEnterInBackGround (您可以使用应用委托的 applicationDidEnterBackground ,但这样您可以将代码放入类中属于):

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(didEnterBG:)
                                             name:UIApplicationDidEnterBackgroundNotification
                                           object:nil];

现在用 didEnterBG 方法:

self.backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(backgroundWork) userInfo:nil repeats:YES];
[self.backgroundTimer fire];

在这里,我出于个人原因每10秒重复一次这个声音,但是你需要做任何事情。 最后, backgroundWork 方法:

- (void)backgroundWork{
    [self.audioPlayer prepareToPlay];
    [self.audioPlayer play];
}

现在您的音频文件正在后台播放: - )

您还应该注意,您的应用需要具备在后台继续工作的特定权利。您需要选中'您的目标' - >能力 - >背景模式:音频和AirPlay。否则,操作系统将在几分钟内在实际条件下终止您的应用程序(没有调试器或仪器)。

答案 1 :(得分:0)

在去代码之前。你需要告诉操作系统你想要在后台播放音乐的权限。 您可以通过在应用的info.plist

中设置密钥来实现
<key>UIBackgroundModes</key>
    <array>
            <string>audio</string>
    </array>

这样做,当应用程序移动到后台时,您将能够播放音频。

答案 2 :(得分:0)

我有同样的问题,但我从这篇文章找到了解决方案:http://developer.apple.com/library/ios/#qa/qa1668/_index.html

#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

AVAudioSession *audioSession = [AVAudioSession sharedInstance];

NSError *setCategoryError = nil;
[audioSession setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
if (setCategoryError) { /* handle the error condition */ }

NSError *activationError = nil;
[audioSession setActive:YES error:&activationError];
if (activationError) { /* handle the error condition */ }