Thursday, June 6, 2013

AVAudioPlayer prepareToPlay example in Objective C (iOS).


AVAudioPlayer prepareToPlay

Prepares the audio player for playback by preloading its buffers.

- (BOOL)prepareToPlay

Return Value of [AVAudioPlayer prepareToPlay]
Returns YES on success, or NO on failure.

Discussion of [AVAudioPlayer prepareToPlay]
Calling this method preloads buffers and acquires the audio hardware needed for playback, which minimizes the lag between calling the play method and the start of sound output.

Calling the stop method, or allowing a sound to finish playing, undoes this setup.

AVAudioPlayer prepareToPlay example.
- (void)viewDidLoad{
    // initialization ...
    [super viewDidLoad];
    [self performSelector:@selector(primeAudioPlayer) withObject:nil afterDelay:0.1];
}

-(void)primeAudioPlayer {
    NSString *soundFile = [Card loadCardSoundPath:@"dummy"];

    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:
                             [NSURL fileURLWithPath:soundFile] error:nil];
    [audioPlayer prepareToPlay];
    [player release];
}

Example of [AVAudioPlayer prepareToPlay].
- (void)initilizeAudio
{
    NSError *error = nil;
    NSURL *audioURL = [[NSBundle mainBundle] URLForResource:@"Background" withExtension:@"mp3"];

    self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];
    if (error)
    {
        NSLog(@"Error in audioPlayer: %@", [error localizedDescription]);
    }
    else
    {
        [self.audioPlayer setDelegate:self];
        [self.audioPlayer prepareToPlay];
    }
}

AVAudioPlayer prepareToPlay example.
Use GCD to load audio data. using GCD to asynchronously load the song's data into an instance of NSData and use that as a feed to audio player. you have to do this because loading the data of an audio file, depending on the length of the audio file, can take a long time and if you are doing this on the main thread, then you are running the risk of stalling the UI experience. Because of this, you have to use global concurrent queue to ensure that your code does not run on the main thread.if it is on the main thread then problem like you are facing happens. see this sample code

     dispatch_queue_t dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(dispatchQueue, ^(void)
     {
    NSBundle *mainBundle = [NSBundle mainBundle];
        NSString *filePath = [mainBundle pathForResource:@"MySong" ofType:@"mp3"];
        NSData *fileData = [NSData dataWithContentsOfFile:filePath]; NSError *audioPlayerError = nil;
     self.audioPlayer = [[AVAudioPlayer alloc] initWithData:fileData error:&audioPlayerError];

        if (self.audioPlayer != nil)
    {
        self.audioPlayer.delegate = self;
        if ([self.audioPlayer prepareToPlay] && [self.audioPlayer play])
    {
        NSLog(@"Successfully started playing.");
        }
    else
    {
    NSLog(@"Failed to play the audio file.");
     self.audioPlayer = nil;
        }
        }
    else { NSLog(@"Could not instantiate the audio player.");
} });

End of AVAudioPlayer prepareToPlay example article.