2012-03-05 133 views
0

我掙扎了好幾天,現在把這個東西排除出去,根本找不到方法。我想在應用程序退出時播放背景音樂,或者當我點擊鏈接時轉到Safari,但我不會轉到背景模式。請幫忙。背景音頻不會播放

FirstViewController.h文件:

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

@interface RygestopFirstViewController : UIViewController <AVAudioPlayerDelegate> { 

    IBOutlet UIButton     *playButton; 
    IBOutlet UISlider     *volumeSlider; 
    IBOutlet UISlider     *progressBar; 
    IBOutlet UILabel     *currentTime; 
    IBOutlet UILabel     *duration; 

    AVAudioPlayer      *player; 
    UIImage        *playBtnBG; 
    UIImage        *pauseBtnBG; 
    NSTimer        *updateTimer; 

    BOOL        inBackground; 

} 

- (IBAction)playButtonPressed:(UIButton*)sender; 
- (IBAction)volumeSliderMoved:(UISlider*)sender; 
- (IBAction)progressSliderMoved:(UISlider*)sender; 

@property (nonatomic, retain) UIButton  *playButton; 
@property (nonatomic, retain) UISlider  *volumeSlider; 
@property (nonatomic, retain) UISlider  *progressBar; 
@property (nonatomic, retain) UILabel   *currentTime; 
@property (nonatomic, retain) UILabel   *duration; 

@property (nonatomic, retain) NSTimer   *updateTimer; 
@property (nonatomic, assign) AVAudioPlayer   *player; 

@property (nonatomic, assign) BOOL   inBackground; 

@end 

FirstViewController.m代碼:

// amount to skip on rewind or fast forward 
#define SKIP_TIME 1.0   
// amount to play between skips 
#define SKIP_INTERVAL .2 

@implementation RygestopFirstViewController 

@synthesize playButton; 
@synthesize volumeSlider; 
@synthesize progressBar; 
@synthesize currentTime; 
@synthesize duration; 
@synthesize updateTimer; 
@synthesize player; 
@synthesize inBackground; 

-(void)updateCurrentTimeForPlayer:(AVAudioPlayer *)p 
{ 
    currentTime.text = [NSString stringWithFormat:@"%d:%02d", (int)p.currentTime/60, (int)p.currentTime % 60, nil]; 
    progressBar.value = p.currentTime; 
} 

- (void)updateCurrentTime 
{ 
    [self updateCurrentTimeForPlayer:self.player]; 
} 

- (void)updateViewForPlayerState:(AVAudioPlayer *)p 
{ 
    [self updateCurrentTimeForPlayer:p]; 

    if (updateTimer) 
     [updateTimer invalidate]; 

    if (p.playing) 
    { 
     [playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal]; 

     updateTimer = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:@selector(updateCurrentTime) userInfo:p repeats:YES]; 
    } 
    else 
    { 
     [playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal]; 
     updateTimer = nil; 
    } 

} 

- (void)updateViewForPlayerStateInBackground:(AVAudioPlayer *)p 
{ 
    [self updateCurrentTimeForPlayer:p]; 

    if (p.playing) 
    { 
     [playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal]; 
    } 
    else 
    { 
     [playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal]; 
    } 
} 

-(void)updateViewForPlayerInfo:(AVAudioPlayer*)p 
{ 
    duration.text = [NSString stringWithFormat:@"%d:%02d", (int)p.duration/60, (int)p.duration % 60, nil]; 
    progressBar.maximumValue = p.duration; 
    volumeSlider.value = p.volume; 
} 

-(void)pausePlaybackForPlayer:(AVAudioPlayer*)p 
{ 
    [p pause]; 
    [self updateViewForPlayerState:p]; 
} 

-(void)startPlaybackForPlayer:(AVAudioPlayer*)p 
{ 
    if ([p play]) 
    { 
     [self updateViewForPlayerState:p]; 
    } 
    else 
     NSLog(@"Could not play %@\n", p.url); 
} 

- (IBAction)playButtonPressed:(UIButton *)sender 
{ 
    if (player.playing == YES) 
     [self pausePlaybackForPlayer: player]; 
    else 
     [self startPlaybackForPlayer: player]; 
} 

- (IBAction)volumeSliderMoved:(UISlider *)sender 
{ 
    player.volume = [sender value]; 
} 

- (IBAction)progressSliderMoved:(UISlider *)sender 
{ 
    player.currentTime = sender.value; 
    [self updateCurrentTimeForPlayer:player]; 
} 

- (void)dealloc 
{ 
    [super dealloc]; 

    [playButton release]; 
    [volumeSlider release]; 
    [progressBar release]; 
    [currentTime release]; 
    [duration release]; 

    [updateTimer release]; 
    [player release]; 

    [playBtnBG release]; 
    [pauseBtnBG release]; 
} 

#pragma mark AVAudioPlayer delegate methods 

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)p successfully:(BOOL)flag 
{ 
    if (flag == NO) 
     NSLog(@"Playback finished unsuccessfully"); 

    [p setCurrentTime:0.]; 
    if (inBackground) 
    { 
     [self updateViewForPlayerStateInBackground:p]; 
    } 
    else 
    { 
     [self updateViewForPlayerState:p]; 
    } 
} 

- (void)playerDecodeErrorDidOccur:(AVAudioPlayer *)p error:(NSError *)error 
{ 
    NSLog(@"ERROR IN DECODE: %@\n", error); 
} 

// we will only get these notifications if playback was interrupted 
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)p 
{ 
    NSLog(@"Interruption begin. Updating UI for new state"); 
    // the object has already been paused, we just need to update UI 
    if (inBackground) 
    { 
     [self updateViewForPlayerStateInBackground:p]; 
    } 
    else 
    { 
     [self updateViewForPlayerState:p]; 
    } 
} 

- (void)audioPlayerEndInterruption:(AVAudioPlayer *)p 
{ 
    NSLog(@"Interruption ended. Resuming playback"); 
    [self startPlaybackForPlayer:p]; 
} 

#pragma mark background notifications 
- (void)registerForBackgroundNotifications 
{ 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(setInBackgroundFlag) 
               name:UIApplicationWillResignActiveNotification 
               object:nil]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(clearInBackgroundFlag) 
               name:UIApplicationWillEnterForegroundNotification 
               object:nil]; 
} 

- (void)setInBackgroundFlag 
{ 
    inBackground = true; 
} 

- (void)clearInBackgroundFlag 
{ 
    inBackground = false; 
} 



- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     self.title = NSLocalizedString(@"Play", @"First"); 
     self.tabBarItem.image = [UIImage imageNamed:@"Home"]; 
    } 
    return self; 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Release any cached data, images, etc that aren't in use. 
} 

//Make sure we can recieve remote control events 
- (BOOL)canBecomeFirstResponder { 
    return YES; 
} 

#pragma mark - View lifecycle 

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

    playBtnBG = [[UIImage imageNamed:@"Player.png"] retain]; 
    pauseBtnBG = [[UIImage imageNamed:@"Pause.png"] retain]; 

    [playButton setImage:playBtnBG forState:UIControlStateNormal]; 

    [self registerForBackgroundNotifications]; 

    updateTimer = nil; 

    duration.adjustsFontSizeToFitWidth = YES; 
    currentTime.adjustsFontSizeToFitWidth = YES; 
    progressBar.minimumValue = 0.0; 

    // Load the the sample file, use mono or stero sample 

    NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: [[NSBundle mainBundle] pathForResource:@"Sound1" ofType:@"m4a"]]; 

    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil]; 
    if (self.player) 
    { 
     [self updateViewForPlayerInfo:player]; 
     [self updateViewForPlayerState:player]; 
     player.numberOfLoops = 0; 
     player.delegate = self; 
    } 


    [fileURL release]; 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
} 

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [super viewDidDisappear:animated]; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    // Return YES for supported orientations 
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
} 

@end 

而且,順便說一句,我想運行在薄標籤欄的應用程序,所以背景模式必須是總是存在。

+1

[使用AVPlayer播放音頻的播放無法在後臺運行](http://stackoverflow.com/questions/8807914/airplay-of-audio-using-avplayer-does-not-work-in-背景) – bryanmac 2012-03-05 11:45:39

+0

THx的信息。但是,在哪裏放這個代碼?我是一個n00b編程,所以請幫助。 – Smugl3r 2012-03-05 11:51:22

回答