Seek functionality not working in AVAudioPlayer in iPhone App? - iphone

I am using below code for that but when I slide the slider it is calling updateTime method but stuck at player.currentTime and not playing further
On single sliding of slider it gets stuck
-(IBAction)slide
{
[player setCurrentTime:slider.value];
//NSLog(#"slider value in slide : %f",[slider value]);
}
-(void) updateTime:(NSTimer *)timer
{
slider.value = player.currentTime;
//NSLog(#"player current time in update time : %f",[player currentTime]);
}
- (IBAction)play:(id)sender {
NSError *error;
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Sing_for_me.mp3" ofType:nil]];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if(!player) NSLog(#"Error : %#",&error);
[player prepareToPlay];
slider.continuous=YES;
slider.maximumValue = [player duration];
//NSLog(#"player duration : %f",[player duration]);
// NSLog(#"slider duration : %f",slider.value);
//NSLog(#"player current time : %f",[player currentTime]);
slider.value=0.0;
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTime:) userInfo:nil repeats:YES];
[player play];
}
what could be wrong?

Related

How to start the same timer which is stop in the past in iphone

I am new to iphone.I am working on audio player in that timers are involved when play button clicked in audio player i wrote this code
- (IBAction)playButtonClicked:(id)sender {
bookTitleString=[[selectBook titleLabel]text];
startChapterString =[[startChapter titleLabel]text];
NSString *string = [[NSBundle mainBundle]pathForResource:startChapterString ofType:#"mp3" inDirectory:bookTitleString];
NSLog(#"string is %#",string);
NSURL *url = [NSURL fileURLWithPath:string isDirectory:YES];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
AVURLAsset *audioAsset = [AVURLAsset assetWithURL:url];
CMTime audioDuration = audioAsset.duration;
audioDurationInSeconds = CMTimeGetSeconds(audioDuration);
NSLog(#"audioDurationInSeconds is %f",audioDurationInSeconds);
slider.userInteractionEnabled= YES;
slider.minimumValue = 0.0;
slider.maximumValue = audioDurationInSeconds;
slider.value = 0.0;
slider.continuous = YES;
audioPlayer.delegate = self;
if(audioPlayer == nil){
NSLog(#"audio player is nil");
}
else
{
NSLog(#"audio player is not nil");
NSLog(#"audioplayer.deviceCurrentTime is %f",audioPlayer.deviceCurrentTime);
[audioPlayer play];
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(sliderTintChanged:) userInfo:nil repeats:YES];
}
}
in above i will take a timer as a class variable
after complete the playing of song it goes to AVAudioPlayerDelegate that is
audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
here the code for this audioPlayerDidFinishPlaying
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
[timer invalidate];
NSLog(#"song finished playing");
NSString *startSongNumber = [[startChapter titleLabel]text];
NSLog(#"startSongNumber is %#",startSongNumber);
int songNumber = [startSongNumber intValue];
NSLog(#"songNumber is %d",songNumber);
songNumber = songNumber+1;
NSLog(#"songNumber is %d",songNumber);
NSString *nextSongNumber = [NSString stringWithFormat:#"%d",songNumber];
NSLog(#"next song number is %#",nextSongNumber);
NSString *string = [[NSBundle mainBundle]pathForResource:nextSongNumber ofType:#"mp3" inDirectory:bookTitleString];
NSLog(#"string is in playerdidfinish is %#",string);
NSURL *url = [NSURL fileURLWithPath:string isDirectory:YES];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
AVURLAsset *audioAsset = [AVURLAsset assetWithURL:url];
CMTime audioDuration = audioAsset.duration;
audioDurationInSeconds = CMTimeGetSeconds(audioDuration);
NSLog(#"audioDurationInSeconds is %f",audioDurationInSeconds);
[audioPlayer play];
}
here above at the starting i am invalidate the timer and then get the next song path and start play but i don't know how to start the timer which is stopped in above method
if any body know this please help me..
Exactly like you did in playButtonClicked method...
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(sliderTintChanged:) userInfo:nil repeats:YES];
timer is generally use for time increment, it is in seconds.
in your method
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(sliderTintChanged) userInfo:nil repeats:YES];
the timer call method after every one second.
-(void)sliderTintChanged
{
//you can use a variable which will keep timer value
//like this
count++;
}
count is an integer variable assign int count=0;
when timer will be stopped count has the time in seconds and you can use it.
and NSTimer "fire date" keeps the fire detail in which time the method is call.
for more detail read fire date.

audio files does not play properly depending on timer in iphone

I am displaying countdown timer from 5 to 1 in label .When my countdown timer is displayed i am trying to play audio in background for particular label i.e if 5 is displayed audio sound of 5 should be played and if 4 is displayed after 1 sec, audio sound of 4 should be played and so on.I have done the code but the problem is all the audio sounds of 5,4,3,2,1 are played at the same time.This is my code.
-(void)viewWillAppear:(BOOL)animated
{
countDown = 7;
exitcountdown = 0;
lblCountdown.hidden = YES;
btnCancel.hidden = YES;
lblCancel.hidden = YES;
countDownTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateTime:) userInfo:nil repeats:YES];
[countDownTimer fire];
}
-(void)updateTime:(NSTimer*)timerParam
{
countDown--;
if (countDown==5)
{
lblCountdown.hidden = NO;
lblCountdown.text = [NSString stringWithFormat:#"%d",countDown];
NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%d",countDown] ofType:#"mp3"];
if ([player isPlaying])
{
[player stop];
}
player= [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
player.delegate = self;
[player stop];
[player setCurrentTime:0.0];
[player setVolume:100.0];
[player play];
lblCancel.hidden = NO;
btnCancel.hidden = NO;
lblWarning.hidden = YES;
lblGps.hidden = YES;
[countDownTimer fire];
}
else if (countDown==0)
{
[self sendRequest];
countDownTimerexit = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(exitBackground:) userInfo:nil repeats:YES];
[countDownTimerexit fire];
NSString *phoneLinkString = [NSString stringWithFormat:#"tel://%#", self.emergencyphonenumber];
NSURL *phoneLinkURL = [NSURL URLWithString:phoneLinkString];
[[UIApplication sharedApplication] openURL:phoneLinkURL];
[self clearCountDownTimer];
btnCancel.hidden = YES;
lblCancel.hidden = YES;
}
lblCountdown.text = [NSString stringWithFormat:#"%d",countDown];
}
lblCountdown is the label where the countDown is being printed as 5,4,3,2,1.
countDown is an int variable
countDownTimer is NSTimer Variable
What is happening in your code as i think is displaying text on the label is fast process than playing a sound. 5 is displayed and you requested for play sound before sound for 5 reach to end your counter becomes 4 and after that you stop the player and request for next file.
try to insert some delay between playing sound and showing next number.

Using a UISlider to track the duration played of a soundfile

I play a sound file:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/recordTest.caf", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
[audioPlayer play];
sliderUpdater = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(sliderUpdateTimer)
userInfo:nil
repeats:YES];
So the sound plays, and i start the NSTimer calling my method sliderUpdateTimer.
So the method is
- (void) sliderUpdateTimer
{
NSLog(#"Dur: %f",audioPlayer.duration );
NSLog(#"Cur: %f",audioPlayer.currentTime );
[seekSlider setValue:100 * (audioPlayer.duration) / (audioPlayer.currentTime)];
}
Duration and currentTime both appear to be 0.
What part of this am I doing wrong?
audioPlayer.duration and currentTime return a NSTimerInterval which i believe is a double.
Many Thanks,
-Code
These combinations worked fine for me,
-(IBAction)playAction
{
paused = NO;
[audioPlayer play];
audioSlider.maximumValue = [audioPlayer duration];
audioSlider.value = 0.0;
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTime:) userInfo:nil repeats:YES];
}
- (void)updateTime:(NSTimer *)timer
{
audioSlider.value = audioPlayer.currentTime;
audioTimer.text = [NSString stringWithFormat:#"%d", audioSlider.value];
}

Play/Pause with the same button [AVAudioPlayer]

How can I play a sound with an IBAction by pressing on a UIbutton once and pause it by pressing the button again using AVAudioPlayer? Also I want to change the state of that UIButton when the sound is playing and when it's not.
Here's my code:
- (IBAction)Beat
{
if ([Media2 isPlaying])
{
[Media2 pause];
[Button17 setSelected:NO];
}
else
{
Path = [[NSBundle mainBundle] pathForResource:#"Beat" ofType:#"mp3"];
AVAudioPlayer *Media2 = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:Path] error:NULL];
[Media2 setDelegate:self];
[Media2 play];
[Button17 setSelected:YES];
}
}
Here's is simple method using BOOL Variable.
Set playing = NO in viewDidLoad.
-(void)PlayStop{
if (playing==NO) {
// Init audio with playback capability
[play setBackgroundImage:[UIImage imageNamed:#"hmpause.png"] forState:UIControlStateNormal];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:______ error:&err];
[audioPlayer prepareToPlay];
audioPlayer.delegate=self;
[audioPlayer play];
playing=YES;
}
else if(playing==YES){
[play setBackgroundImage:[UIImage imageNamed:#"Audioplay.png"] forState:UIControlStateNormal];
[audioPlayer pause];
playing=NO;
}
}
Keep your audioPlayer instance ready to play using the below method.
/*
Prepares the audio file to play.
*/
-(void) initWithAudioPath:(NSString *) audioPath {
// Converts the sound's file path to an NSURL object
NSURL *audioPathURL = [[NSURL alloc] initFileURLWithPath:audioPath];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioPathURL error:nil];
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
[audioPathURL release];
}
-(void) pausePlaybackForPlayer:(AVAudioPlayer *) player {
[player pause];
}
-(void) startPlaybackForPlayer:(AVAudioPlayer *) player {
if (![player play]) {
NSLog(#"Could not play %#\n", player.url);
}
}
- (IBAction)Beat {
if (audioPlayer.playing == NO) {
// Audio player is not playing.
// Set the button title here to "stop"...
[self startPlaybackForPlayer:audioPlayer];
}else {
// Audio player is playing.
// Set the button title here to "play"...
[self pausePlaybackForPlayer:audioPlayer];
}
}

Audio File continues to play even on leaving the view

What I am doing is
-(void)viewWillAppear:(BOOL)animated{
[NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:#selector(clickEvent:) userInfo:nil repeats:YES];
}
-(void)clickEvent:(NSTimer *)aTimer{
NSDate* finishDate = [NSDate date];
if([finishDate timeIntervalSinceDate: self.startDate] > 11 && touched == NO){
NSString *mp3Path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"test.mp3"];
[self playMusicFile:mp3Path];
NSLog(#"Timer from First Page");
[aTimer invalidate];
//[touchCheckTimer release];
aTimer = nil;
}
else{
}
-(void)playMusicFile:(NSString *)mp3Path{
NSURL *mp3Url = [NSURL fileURLWithPath:mp3Path];
NSError *err;
AVAudioPlayer *audPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:mp3Url error:&err];
[self setAudioPlayer1:audPlayer];
if(audioPlayer1)
[audioPlayer1 play];
[audPlayer release];
}
Now, on pushing another view this audio file keeps playing in the background.
Please help!
Well it is very common mistake
when you are leaving the view call stop method on the AVAudioPlayer variable pointer that you used to play the audio with