audio files does not play properly depending on timer in iphone - 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.

Related

Repeat (Loop) UIButton besides Play button

Basically in app have a play button for audio file, want to add another UIButton Besides Play button so that whenever it is pressed it will repeat audio file for some number of times or may be infinite until it is pressed again to stop repetition of playing audio file. How can this be achieved.
Below is the code for play/pause toggle button
_playButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_playButton addTarget:self action:#selector(playAction:) forControlEvents:UIControlEventTouchUpInside];
_playButton.frame = CGRectMake(80, 40, 25, 25);
[_playButton setImage:[UIImage imageNamed:#"1play.png"] forState:UIControlStateNormal];
[_playButton setImage:[UIImage imageNamed:#"audiopause.png"] forState:UIControlStateSelected];
UIBarButtonItem *play = [[UIBarButtonItem alloc] initWithCustomView:_playButton];
// Get the file path to the song to play.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Theme"ofType:#"mp3"];
// Convert the file path to a URL.
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
//Initialize the AVAudioPlayer.
player = [[AVAudioPlayer alloc]
initWithContentsOfURL:fileURL error:nil];
player.delegate = self;
- (void)playAction:(id)sender
{
if([player isPlaying])
{
[sender setImage:[UIImage imageNamed:#"1play.png"] forState:UIControlStateSelected];
[player pause];
//[timer invalidate];
//timer = nil;
//[self pauseTimer];
}else{
[sender setImage:[UIImage imageNamed:#"audiopause.png"] forState:UIControlStateNormal];
[player play];
slidertimer = [NSTimer timerWithTimeInterval:1.0 target:self selector:#selector(updateProgressBar:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:slidertimer forMode:NSRunLoopCommonModes];
timer = slidertimer;
}
}
It looks like all you need is to execute an action every x number of seconds. You can move the code the UIButton is executing to a method, and then have a NSTimer looping that executes that method for n number of times, then invalidate the NSTimer when you are done.
I have finally worked it out like this
-(void) RepeatAction:(id)sender{
if (player && player.playing) {
[player stop];
player = nil;
[_playButton setImage:[UIImage imageNamed:#"1play.png"] forState:UIControlStateNormal];
return;
}
// Get the file path to the song to play.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Theme"ofType:#"mp3"];
// Convert the file path to a URL.
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
//Initialize the AVAudioPlayer.
player = [[AVAudioPlayer alloc]
initWithContentsOfURL:fileURL error:nil];
player.delegate = self;
player.numberOfLoops = -1;
[player play];
}
Now only problem i m facing is that play/pause toggle button is disturbed with this. How to fix that.

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.

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];
}

Seek functionality not working in AVAudioPlayer in iPhone App?

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?

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