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!
AVQueuePlayer work for this situation.
AVQueuePlayer is a subclass of AVPlayer you use to play a number of items in sequence.
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
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With