Reputation: 1351
In my project, I have an AVAudioPlayer which plays a song. After I pause it, and hit play again, it starts over instead of playing where I paused. Why is that happening? Also, when I press play for the first time, it loads the song about 3-4 seconds. I thought I solved it by loading it on the other thread, but it still loads too slow (at least the view doesn't freeze anymore). How can I fix that? Here's the code:
- (IBAction)play:(id)sender {
songIsCurrentlyPaused = NO;
if(songIsCurrentlyPaused==YES){
[self.background play];
} else {
playQueue = dispatch_queue_create("volume_change", NULL);
dispatch_async(playQueue, ^{ NSString *filePath =
[[NSBundle mainBundle]pathForResource:@"some_song" ofType:@"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
self.background = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
self.background.delegate = self;
[self.background setNumberOfLoops:1];
[self.background setVolume:0.5];
[self.background play]; });
[trackNameLabel setText:@"Currently playing :\n some_song"];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(updateProgressBar) userInfo:nil repeats:YES];
}
}
- (IBAction)pause:(id)sender {
songIsCurrentlyPaused = YES;
[self.background pause];
[trackNameLabel setText:@"Currently playing : some_song (paused)"];
[self.progressBar setProgress:self.background.currentTime/self.background.duration animated:YES];
}
Thanks!
Upvotes: 1
Views: 2762
Reputation: 18865
You're setting songIsCurrentlyPaused
to NO
at the beginning of play:
Try commenting it out:
- (IBAction)play:(id)sender {
//songIsCurrentlyPaused = NO;
if(songIsCurrentlyPaused==YES){
[self.background play];
} else {
playQueue = dispatch_queue_create("volume_change", NULL);
dispatch_async(playQueue, ^{ NSString *filePath =
[[NSBundle mainBundle]pathForResource:@"some_song" ofType:@"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
self.background = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
self.background.delegate = self;
[self.background setNumberOfLoops:1];
[self.background setVolume:0.5];
[self.background play]; });
[trackNameLabel setText:@"Currently playing :\n some_song"];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(updateProgressBar) userInfo:nil repeats:YES];
}
}
- (IBAction)pause:(id)sender {
songIsCurrentlyPaused = YES;
[self.background pause];
[trackNameLabel setText:@"Currently playing : some_song (paused)"];
[self.progressBar setProgress:self.background.currentTime/self.background.duration animated:YES];
}
If you want to get rid of that initial pause you're gonna have to completely reorganize your player setup. Initialize it before user can hit play button and also call:
[self.background prepareToPlay];
which will preload the song. Also move songIsCurrentlyPaused = NO;
to some earlier place in code.
EDIT:
To get rid of initial delay you should move your initializing code to somewhere like loadView
or viweDidLoad
.
//initialization code
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"some_song" ofType:@"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
self.background = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
self.background.delegate = self;
[self.background setNumberOfLoops:1];
[self.background setVolume:0.5];
[self.background prepareToPlay];
Now this may cause a lag in UI display so you might wan't to consider preloading data in background thread.
Your IBAction
methods should then be modified:
- (IBAction)play:(id)sender
{
if (songIsCurrentlyPaused==YES)
{
[self.background play];
}
else
{
playQueue = dispatch_queue_create("volume_change", NULL);
dispatch_async(playQueue, ^{
[self.background setCurrentTime: 0.0];
[self.background play];
});
[self.progressBar setProgress:0.0 animated:YES];
[trackNameLabel setText:@"Currently playing :\n some_song"];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(updateProgressBar) userInfo:nil repeats:YES];
}
songIsCurrentlyPaused = NO;
}
- (IBAction)pause:(id)sender
{
songIsCurrentlyPaused = YES;
[self.background pause];
[trackNameLabel setText:@"Currently playing : some_song (paused)"];
[self.progressBar setProgress:self.background.currentTime/self.background.duration animated:YES];
}
Upvotes: 1