2011-10-19 71 views
0

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

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

这里是我的代码:

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

回答

0

才去的代码。您需要告诉操作系统您想要在后台播放音乐的权限。 你可以做,通过设置您的应用程序的Info.plist

<key>UIBackgroundModes</key> 
    <array> 
      <string>audio</string> 
    </array> 

这样一个键,就可以播放音频时的应用程序移动到背景。

+0

我在plist.info中添加了密钥,但它仍然无法播放... – Garen

+0

但是当我在应用程序中启动音乐时,它可以在后台播放... 令我疯狂很久.. 。> _ < – Garen

0

继续samfisher的回答,请参阅apple's documentation。如果发生任何问题,也请通过previous post

+0

avaudioplayer可以在后台播放,如果我在前台启动它,但是当我使用NSTimer在后台启动时,[player prepareToPlay]方法返回NO ... – Garen

+0

那么您需要处理委托方法EndInterruption for avaudioplayer 。但是,这并不适用于我...但我阅读文档,我发现它正在工作.... – DShah

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 */ } 
1

你需要这样做的init在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]; 

这是音频初始化。在这里,用名为的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]; 
} 

现在你的音频文件正在播放的背景:-)

你也应该注意到,您的应用程序需要具有特定的权限要继续做的工作背景。您需要选中'YourTarget' - > Capabilities - > Background Modes:Audio和AirPlay下的复选框。否则,操作系统会在几分钟内在实际情况下终止您的应用(无需调试器或仪器)。

+0

这真的很有帮助,但是如果我只想在后台模式下启动声音?因为使用[self.backgroundTimer fire]会调用backgroundWork并且应用程序将播放声音 – Signo

+0

好吧,由于在'UIApplicationDidEnterBackgroundNotification'上调用了后台工作函数,所以只有当应用程序确实进入后台模式时才会播放声音。 –