I was Created AVAudio Player, its playing perfectly,Click the play button song is playing and its shows pause button,click pause button song is paused and its shows play button,but click the play button is playing from starting onwards.i want play resume song. how to control this issue. this is my code , please check once's.
-(void)playAudio
{
// [progreetimer invalidate];
// if([audioPlayer isPlaying]==YES)`enter code here`
if(self.isPlaying)
{
[self.play setBackgroundImage:[UIImage imageNamed:#"audioplayer_play.png"]
forState:UIControlStateNormal];
NSLog(#"Pausing Music");
if (self.progreetimer) {
[self.progreetimer invalidate];
progreetimer =nil;
}
[audioPlayer pause];
self.isPlaying = NO;
}
else {
// Init audio with playback capability
[self.play setBackgroundImage:[UIImage imageNamed:#"audioplayer_pause.png"] forState:UIControlStateNormal];
// NSString *urlstr = #"http://jesusredeems.in/media/Media Advt/mp3_player/Songs/viduthalaiyin geethangal_vol1/93.Ellame Koodum.mp3";
NSString *urlstr =#"http://www.abstractpath.com/files/audiosamples/sample.mp3";
urlstr = [urlstr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlstr];
NSData *data = [NSData dataWithContentsOfURL:url];
audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:nil];
audioPlayer.volume = 1.9f;
// [audioPlayer prepareToPlay];
SongProgressBar.maximumValue = [audioPlayer duration];
SongProgressBar.value = 0.0;
NSLog(#"Playing music");
//start a timer to update the time label display
self.progreetimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self
selector:#selector(updateTime:) userInfo:nil repeats:YES];
self.progreetimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self
selector:#selector(updateSlider) userInfo:nil repeats:YES];
[progreetimer fire];
audioPlayer.delegate=self;
[audioPlayer play];
self.isPlaying = YES;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.SongProgressBar.minimumValue = 30;
self.SongProgressBar.maximumValue = 30;
[self.SongProgressBar setThumbImage:[UIImage imageNamed:#"thumbslider.png"]
forState:UIControlStateNormal];
// [self.SongProgressBar setThumbImage:[UIImage imageNamed:#"slider_icon.png"]
// forState:UIControlStateHighlighted];
[self.SongProgressBar setMinimumTrackImage:[UIImage imageNamed:#"slider_max.png"]
forState:UIControlStateNormal];
[self.SongProgressBar setMaximumTrackImage:[UIImage imageNamed:#"slider_icon.png"]
forState:UIControlStateNormal];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[audioPlayer pause]; // Or pause
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[audioPlayer play];
}
- (IBAction)songprogressbar:(id)sender {
// Fast skip the music when user scroll the UISlider
[audioPlayer stop];
[audioPlayer setCurrentTime:SongProgressBar.value];
[audioPlayer prepareToPlay];
[audioPlayer play];
}
- (IBAction)backword:(id)sender {
if ([self.audioPlayer isPlaying]) {
NSTimeInterval desiredTime = audioPlayer.currentTime -15.0f;
if (desiredTime < 0) {
audioPlayer.currentTime =0.0f;
} else {
audioPlayer.currentTime = desiredTime;
}
}
}
- (IBAction)play:(id)sender {
[self playAudio];
}
- (void)updateSlider {
// Update the slider about the music time
SongProgressBar.value = audioPlayer.currentTime;
}
- (void)setCurrentAudioTime:(float)value {
[self.audioPlayer setCurrentTime:value];
}
//Stops the timer when the music is finished
- (void)audioPlayerDidFinishPlaying : (AVAudioPlayer *)player successfully : (BOOL)flag {
// Music completed
if (flag) {
[progreetimer invalidate];
NSLog(#"Finished playing the song");
}
}
- (IBAction)forword:(id)sender {
if ([audioPlayer isPlaying]) {
NSTimeInterval desiredTime = audioPlayer.currentTime +15.0f;
if (desiredTime < audioPlayer.duration) {
audioPlayer.currentTime = desiredTime;
}
}
}
- (IBAction)volume:(id)sender {
audioPlayer.volume=volume.value;
}
-(NSString*)timeFormat:(float)value{
float minutes = floor(lroundf(value)/60);
float seconds = lroundf((value) - (minutes * 60));
int roundedSeconds = lroundf(seconds);
int roundedMinutes = lroundf(minutes);
NSString *time = [[NSString alloc]
initWithFormat:#"%d:%02d",
roundedMinutes, roundedSeconds];
return time;
}
- (void)updateTime:(NSTimer *)timer {
self.starttimer.text = [NSString stringWithFormat:#"%#",
[self timeFormat: ceilf(audioPlayer.currentTime)]];
self.endtimer.text = [NSString stringWithFormat:#"-%#", [self timeFormat: (audioPlayer.duration - ceilf(audioPlayer.currentTime))]];
}
You should try this. see else part of method
-(void)playAudio
{
// [progreetimer invalidate];
// if([audioPlayer isPlaying]==YES)`enter code here`
if(self.isPlaying)
{
//Code to pause audioPlayer
[audioPlayer pause];
self.isPlaying = NO;
}
else
{
if(audioPlayer.url != nil && audioPlayer.duration != 0)
{
[audioPlayer play];
}
else
{
//Code to add new audioPlayer
}
}
}
Use the following code
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL error: nil];
[player prepareToPlay];
player.currentTime = 0;
[player play];
Related
I am using the AVAudioPlayer class to play audio. I have implemented a timer slider that progresses as the music is playing.
Here is my code:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
AudioBool = YES;
}
- (IBAction)play:(id)sender
{
// Code to read the file from resource folder and sets it in the AVAudioPlayer
// Sets the audio timer in 1 sec intervals
sliderTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTime) userInfo:nil repeats:YES];
// Sets the slider maximum value
slider.maximumValue = player.duration;
// Sets the valueChanged target
[slider addTarget:self action:#selector(sliderChanged : ) forControlEvents : UIControlEventValueChanged];
// Play the audio
// [player prepareToPlay];
[player play];
if(AudioBool == YES)
{
[player play];
AudioBool = NO;
}
else
{
[player pause];
AudioBool = YES;
}
}
- (void)updateTime
{
// Updates the slider about the music time
slider.value = player.currentTime;
NSString *time = [self timeFormatted:slider.value];
self.timerLabe.text = time;
}
- (NSString *)timeFormatted:(int)totalSeconds
{
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
//int hours = totalSeconds / 3600;
//return [NSString stringWithFormat:#"%02d:%02d:%02d",hours, minutes, seconds];
return [NSString stringWithFormat:#"%02d:%02d", minutes, seconds];
}
- (IBAction)sliderChanged : (UISlider *)sender
{
// skips music with slider changged
[player pause];
[player setCurrentTime:slider.value];
// [player prepareToPlay];
[player play];
}
// Stops the timer when audio finishes
- (void)audioPlayerDidFinishPlaying : (AVAudioPlayer *)player successfully :
(BOOL)flag
{
// Music completed
if (flag)
{
[sliderTimer invalidate];
}
}
2 issues I have:
I can't seem to pause the audio. When I re-tap the play button, it re-starts the audio at the beginning instead of pausing it.
The slider also re-starts at the beginning instead of pausing.
How do I fix these issues?
Thanks
try this solution, you need to make changes in play method basically..shift the slider initialisation in viewDidLoad also play/pause based on isPlaying property (AudioBool property in your code)
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
#property (nonatomic, strong) AVAudioPlayer *audioPlayer;
#property (nonatomic) BOOL isPlaying;
#property (nonatomic, strong) NSTimer *sliderTimer;
#property (weak, nonatomic) IBOutlet UISlider *slider;
#property (weak, nonatomic) IBOutlet UILabel *timerLabel;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath = [mainBundle pathForResource:#"10101" ofType:#"mp3"];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
self.isPlaying = NO;
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
[self.audioPlayer prepareToPlay];
[self.slider addTarget:self action:#selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];
self.slider.minimumValue = 0;
self.slider.maximumValue = self.audioPlayer.duration;
}
- (IBAction)play:(id)sender {
if (self.isPlaying)
{
// Music is currently playing
[self.audioPlayer pause];
self.isPlaying = !self.isPlaying;
}
else
{
// Music is currenty paused/stopped
[self.audioPlayer play];
self.isPlaying = !self.isPlaying;
self.sliderTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTime) userInfo:nil repeats:YES];
}
}
- (void)sliderChanged:(UISlider *)sender
{
// skips music with slider changged
[self.audioPlayer pause];
[self.audioPlayer setCurrentTime:self.slider.value];
[self.audioPlayer play];
}
- (void)updateTime
{
// Updates the slider about the music time
self.slider.value = self.audioPlayer.currentTime;
NSString *time = [self timeFormatted:self.slider.value];
self.timerLabel.text = time;
}
- (NSString *)timeFormatted:(int)totalSeconds
{
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
return [NSString stringWithFormat:#"%02d:%02d", minutes, seconds];
}
// Stops the timer when audio finishes
- (void)audioPlayerDidFinishPlaying : (AVAudioPlayer *)player successfully:(BOOL)flag
{
// Music completed
if (flag)
{
[self.sliderTimer invalidate];
}
}
In my application, I'm using both iPod Player for playing background music(Music App) and AvAudioPlayer for playing the songs from URL's. I want to put fading effect for the songs while switching between these players. I tried the way by decreasing the volume of one player and increasing the other, but it did not give me the fading effect. Can anyone help me how to achieve this?
Thanks in advance
This is my code
- (IBAction)play:(id)sender
{
timerCount = 0;
playAndPauseTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(playTimer) userInfo:nil repeats:YES];
}
-(void)playTimer
{
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
if(timerCount < 10) {
timerCount++;
float volume = musicPlayer.volume;
if(volume>0) {
volume = musicPlayer.volume-0.02f;
[musicPlayer setVolume:volume];
}
} else {
[playAndPauseTimer invalidate];
[musicPlayer setVolume:initialVolume];
[audioplayer play];
pauseButton.hidden = NO;
startButton.hidden = YES;
}
}
- (IBAction)pause:(id)sender
{
//[self pauseTimer];
timerCount=0;
playAndPauseTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(pauseTimer) userInfo:nil repeats:YES];
}
-(void)pauseTimer
{
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
if(timerCount < 10) {
timerCount++;
float volume = musicPlayer.volume;
if(volume > 0){
volume = musicPlayer.volume-0.02f;
[musicPlayer setVolume:volume];
}
} else {
[playAndPauseTimer invalidate];
[audioplayer pause];
[musicPlayer setVolume:initialVolume];
pauseButton.hidden = YES;
startButton.hidden = NO;
}
}
I am trying to create AVAudioPlayer Programatically.I Have small issue if i play audioplayer.
I am displaying 12 audio items in UITableview.If i click first item that corresponding song will play.I should not click any pass button.i click back button and click second item.if i click second item the audio view controller will display.I click play button the song display.In first song and second song play simultaneously.This is my issue.Please help me anybody.
-(void)playOrPauseButtonPressed:(id)sender
{
if(playing==NO)
{
[playButton setBackgroundImage:[UIImage imageNamed:#"Pause.png"] forState:UIControlStateNormal];
// Here Pause.png is a image showing Pause Button.
NSError *err=nil;
AVAudioSession *audioSession=[AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
NSLog(#"%# %d",urlsArray,selectedIndex);
NSString *sourcePath=[urlsArray objectAtIndex:selectedIndex];
NSData *objectData=[NSData dataWithContentsOfURL:[NSURL URLWithString:sourcePath]];
audioPlayer = [[AVAudioPlayer alloc] initWithData:objectData error:&err];
audioPlayer.numberOfLoops = 0;
[audioPlayer prepareToPlay];
audioPlayer.delegate=self;
[audioPlayer play];
playing=YES;
}
else if (playing==YES)
{
[playButton setBackgroundImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[audioPlayer pause];
playing=NO;
}
if (self.audioPlayer)
{
[self updateViewForPlayerInfo];
[self updateViewForPlayerState];
[self.audioPlayer setDelegate:self];
}
}
-(void)updateViewForPlayerInfo
{
self.songDuration.text = [NSString stringWithFormat:#"%d:%02d", (int)self.audioPlayer.duration / 60, (int)self.audioPlayer.duration % 60, nil];
NSLog(#"%f", self.audioPlayer.duration);
self.progressBar.maximumValue = self.audioPlayer.duration;
self.volumeSlider.value = self.audioPlayer.volume;
}
-(void)updateViewForPlayerState
{
[self updateCurrentTime];
if (self.updatedTimer)
{
[self.updatedTimer invalidate];
}
if (self.audioPlayer.playing)
{
self.updatedTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(updateCurrentTime) userInfo:self.audioPlayer repeats:YES];
}
}
-(void)updateCurrentTime
{
//NSLog(#"self.audioPlayer.currentTime = %f", self.audioPlayer.currentTime);
self.currentTime.text = [NSString stringWithFormat:#"%d:%02d", (int)self.audioPlayer.currentTime / 60, (int)self.audioPlayer.currentTime % 60, nil];
self.progressBar.value = self.audioPlayer.currentTime;
}
-(void)volumeSliderMoved:(UISlider *)sender
{
self.audioPlayer.volume=[sender value];
}
before creating a new instance of AVAudioPlayer, deallocate or nil the existing instance of player by using following lines
sourcePath=Nil;
[audioPlayer stop];
audioPlayer = Nil;
Stop the player when you go back. Maybe in ViewWillDisappear or before you create a new instance of audioplayer, you can call
if(self.audioplayer) {
[self.audioPlayer stop];
self.audioPlayer = nil;
}
Before initializing the AVAudioPlayer remove all the instances that are running before.
//YOUR STUFF
NSString *sourcePath=[urlsArray objectAtIndex:selectedIndex];
NSData *objectData=[NSData dataWithContentsOfURL:[NSURL URLWithString:sourcePath]];
for (AVAudioPlayer *a in urlsArray)
[a stop];
audioPlayer = [[AVAudioPlayer alloc] initWithData:objectData error:&err];
audioPlayer.numberOfLoops = 0;
//REST STUFF
I would like to check whether the audio has ended playing. If so, I need to change the button to a play button instead of a pause button. How do i do it in iOS?
My code looks like this:
-(void)playAudioFile:(BOOL)status
{
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"audio" ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSError *error;
if(status)
{
if(!audioPlayer)
{
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];
audioPlayer.currentTime = currentPlayTime;
audioPlayer.numberOfLoops = 0; //Infinite
audioDuration = audioPlayer.duration;
audioPlaySlider.minimumValue = 0;
audioPlaySlider.maximumValue = audioDuration;
audioPlaySlider.value = currentPlayTime;
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(audioTimer:) userInfo:[NSDictionary dictionaryWithObject:audioPlayer forKey:#"playerObject"] repeats:YES];
}
[audioPlayer play];
if([audioPlayer rate] != 1.0 )
{
[audioPlayer play];
}
else
{
[self->audioPlayBtn setBackgroundImage:[UIImage imageNamed:#"playBtn.png"] forState:UIControlStateNormal];
}
NSLog(#"Play duration : %f",audioDuration);
}
else
{
if(audioPlayer && audioPlayer.playing)
{
[audioPlayer pause];
}
}
NSLog(#"Error for file : %#",error);
}
I tried this:
if([audioPlayer rate] != 1.0 )
{
[audioPlayer play];
}
else
{
[self->audioPlayBtn setBackgroundImage:[UIImage imageNamed:#"playBtn.png"] forState:UIControlStateNormal];
}
But not working.. Need some guidance...
Use the AVAudioPlayerDelegate's method
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
Your viewcontroller/class with the audioplayer instance must be the delegate for the audio player. The method will be called when the audio player finishes playback.
http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioPlayerDelegateProtocolReference/Reference/Reference.html
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!
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];
}