Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to play multiple audio files in a row with AVAudioPlayer?

I have 5 songs in my app that I would like to play one after the other with AVAudioPlayer.

Are there any examples of this? How can I accomplish this?

Any example code would be greatly appreciated!

Thanks!

like image 960
dot Avatar asked Nov 12 '11 02:11

dot


4 Answers

AVQueuePlayer work for this situation.

AVQueuePlayer is a subclass of AVPlayer you use to play a number of items in sequence.

like image 157
Ken Avatar answered Nov 10 '22 17:11

Ken


Instead of AVAudioPlayer you can use AVQueuePlayer which suits this use case better as suggested by Ken. Here is a bit of code you can use:

@interface AVSound : NSObject 

@property (nonatomic, retain) AVQueuePlayer* queuePlayer;

- (void)addToPlaylist:(NSString*)pathForResource ofType:(NSString*)ofType;
- (void)playQueue;

@end

@implementation AVSound
- (void)addToPlaylist:(NSString*)pathForResource ofType:(NSString*)ofType
{
    // Path to the audio file
    NSString *path = [[NSBundle mainBundle] pathForResource:pathForResource ofType:ofType];

    // If we can access the file...
    if ([[NSFileManager defaultManager] fileExistsAtPath:path])
    {

        AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:path]];

        if (_queuePlayer == nil) {
            _queuePlayer = [[AVQueuePlayer alloc] initWithPlayerItem:item];
        }else{
            [_queuePlayer insertItem:item afterItem:nil];
        }
    }

}


- (void)playQueue
{
    [_queuePlayer play];
}
@end

Then to use it: In your interface file:

@property (strong, nonatomic) AVSound *pageSound;

In your implementation file:

- (void)addAudio:(Book*)book pageNum:(int)pageNum
{

    NSString *soundFileEven = [NSString stringWithFormat:@"%02d", pageNum-1];
    NSString *soundPathEven = [NSString stringWithFormat:@"%@_%@", book.productId,     soundFileEven];
    NSString *soundFileOdd = [NSString stringWithFormat:@"%02d", pageNum];
    NSString *soundPathOdd = [NSString stringWithFormat:@"%@_%@", book.productId, soundFileOdd];

    if (_pageSound == nil) {
        _pageSound = [[AVSound alloc]init];
        _pageSound.player.volume = 0.5;
    }

    [_pageSound clearQueue];

    [_pageSound addToPlaylist:soundPathEven ofType:@"mp3"];
    [_pageSound addToPlaylist:soundPathOdd ofType:@"mp3"];
    [_pageSound playQueue];
}

HTH

like image 38
Nathan Noble Avatar answered Nov 10 '22 18:11

Nathan Noble


For every song you want to make make a single AVPlayer.

NSURL *url = [NSURL URLWithString:pathToYourFile];
AVPlayer *audioPlayer = [[AVPlayer alloc] initWithURL:url];
[audioPlayer play];

You can get a Notification when the player ends. Check AVPlayerItemDidPlayToEndTimeNotification when setting up the player:

  audioPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; 

  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(playerItemDidReachEnd:)
                                               name:AVPlayerItemDidPlayToEndTimeNotification
                                             object:[audioPlayer currentItem]];

this will prevent the player to pause at the end.

in the notification:

- (void)playerItemDidReachEnd:(NSNotification *)notification
{
    // start your next song here
}

You can start your next song as soon as you get a notification that the current playing song is done. Maintain some counter which is persistent across selector calls. That way using counter % [songs count] will give you an infinite looping playlist :)

Don't forget un unregister the notification when releasing the player.

like image 26
Srikar Appalaraju Avatar answered Nov 10 '22 18:11

Srikar Appalaraju


Unfortunately, AVAudioPlayer can only play one file. To play two files, you have to kill the first instance of the AVAudioPlayer and recreate it a second time (it can be initiated using - (id)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError). The problem with this approach is that there is a slight delay between when the first file finishes playing and when the second file starts playing. If you want to get rid of this delay you have to dig into Core Audio and come up with a much more complex solution.

like image 30
Michael Frederick Avatar answered Nov 10 '22 18:11

Michael Frederick