2011-10-19 97 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'上調用了後臺工作函數,所以只有當應用程序確實進入後臺模式時纔會播放聲音。 –