UIProgressBar for AvAudioPlayer playing progress - iphone

In my app playing audiofile for that i want to show UIProgressBar on the UIToolbar for audiofile playing progress. Anyone can help me how to code for it.

I use a timer to check the current duration, and then update my progress bar every half second, like so:
tmrCounter = [NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:#selector(updateElapsedTime) userInfo:nil repeats:YES];
-(void)updateElapsedTime{
if (player) {
[prgIndicator setProgress:[player currentTime] / [player duration]];
[lblTime setText:[NSString stringWithFormat:#"%#", [self formatTime:[player currentTime]]]];
}
}
-(NSString*)formatTime:(float)time{
int minutes = time / 60;
int seconds = (int)time % 60;
return [NSString stringWithFormat:#"%#%d:%#%d", minutes / 10 ? [NSString stringWithFormat:#"%d", minutes / 10] : #"", minutes % 10, [NSString stringWithFormat:#"%d", seconds / 10], seconds % 10];
}
Hope this helps!

Related

Display timer that works out Days, hours, minutes and seconds from a date then increments in real time

I am trying to Display a timer that works out Days, hours, minutes and seconds from a date then increments in real time on a view/page.
What would be the best approach?
you can do like this way:-
- (void)viewWillAppear:(BOOL)animated
{
[self start];
[super viewWillAppear:YES];
}
int currentTime;
- (IBAction)start{
currentTime = 0;
lbl=[[UILabel alloc]init];
//creates and fires timer every second
myTimer = [[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(showTime) userInfo:nil repeats:YES]retain];
}
- (IBAction)stop{
[myTimer invalidate];
myTimer = nil;
}
- (IBAction)reset{
[myTimer invalidate];
lbl.text = #"00:00:00";
}
-(void)showTime{
currentTime++; //= [lbl.text intValue];
//int new = currentTime++;
int secs = currentTime % 60;
int mins = (currentTime / 60) % 60;
int hour = (currentTime / 3600);
int day = currentTime / (60 * 60 * 24);
lbl.text = [NSString stringWithFormat:#"%.2d:%.2d:%.2d:%.2d",day,hour, mins, secs];
NSLog(#"my lable == %#",lbl.text);
NSLog(#"my lable == %#",lbl.text);
}
The best approach is to read the Date and Time Programming Guide to learn about using the NSDate, NSCalendar, and NSDateComponents classes.

How to implement uislider so that it can be used as a scrubber in AVQueueplayer

I have implemented scrubbing using UISlider the problem is when the song is being played the slider doesnt initiate automatically ,it starts moving only when i tap on it and when the next song starts playing it moves automatically . i want the slider to move when the song starts playing ,this is the code which i am using and one more thing when i move the slider the song has to fast forward .I have added the code which i have written .can anyone help me out .Thanks
-(IBAction)slider:(id)sender
{
CMTime interval = CMTimeMake(33, 1000);
self.playbackObserver = [myPlayer addPeriodicTimeObserverForInterval:interval queue:dispatch_get_current_queue() usingBlock:^(CMTime time) {
CMTime endTime = CMTimeConvertScale (myPlayer.currentItem.asset.duration, myPlayer.currentTime.timescale, kCMTimeRoundingMethod_RoundHalfAwayFromZero);
if (CMTimeCompare(endTime, kCMTimeZero) != 0) {
double normalizedTime = (double) myPlayer.currentTime.value / (double) endTime.value;
self.timeSlider.value = normalizedTime;
}
Float64 currentSeconds = CMTimeGetSeconds(myPlayer.currentTime);
int mins = currentSeconds/60.0;
int secs = fmodf(currentSeconds, 60.0);
NSString *minsString = mins < 10 ? [NSString stringWithFormat:#"0%d", mins] : [NSString stringWithFormat:#"%d", mins];
NSString *secsString = secs < 10 ? [NSString stringWithFormat:#"0%d", secs] : [NSString stringWithFormat:#"%d", secs];
currentTimeLabel.text = [NSString stringWithFormat:#"%#:%#", minsString, secsString];
}];
}
EDIT
can u explain where am i going wrong
-(IBAction)playButtonPressed:(UIButton *)sender
{
CMTime interval = CMTimeMake(33, 1000);
self.playbackObserver = [myPlayer addPeriodicTimeObserverForInterval:interval queue:dispatch_get_current_queue() usingBlock:^(CMTime time)
{
CMTime endTime = CMTimeConvertScale (myPlayer.currentItem.asset.duration, myPlayer.currentTime.timescale, kCMTimeRoundingMethod_RoundHalfAwayFromZero);
if (CMTimeCompare(endTime, kCMTimeZero) != 0) {
double normalizedTime = (double) myPlayer.currentTime.value / (double) endTime.value;
self.timeSlider.value = normalizedTime;
}
}];
[myPlayer play];
}
-(IBAction)slider:(id)sender
{
Float64 currentSeconds = CMTimeGetSeconds(myPlayer.currentTime);
int mins = currentSeconds/60.0;
int secs = fmodf(currentSeconds, 60.0);
NSString *minsString = mins < 10 ? [NSString stringWithFormat:#"0%d", mins] : [NSString stringWithFormat:#"%d", mins];
NSString *secsString = secs < 10 ? [NSString stringWithFormat:#"0%d", secs] : [NSString stringWithFormat:#"%d", secs];
currentTimeLabel.text = [NSString stringWithFormat:#"%#:%#", minsString, secsString];
}
Your observer is being called when you tap on the uislider. This is why you have to tap on the slider first. Move the observer outside of the IBAction and possibly put it in the method that is run when the song starts.
-(IBAction)playButtonPressed:(UIButton *)sender
{
CMTime interval = CMTimeMake(33, 1000);
self.playbackObserver = [myPlayer addPeriodicTimeObserverForInterval:interval queue:dispatch_get_current_queue() usingBlock:^(CMTime time)
{
CMTime endTime = CMTimeConvertScale (myPlayer.currentItem.asset.duration, myPlayer.currentTime.timescale, kCMTimeRoundingMethod_RoundHalfAwayFromZero);
if (CMTimeCompare(endTime, kCMTimeZero) != 0) {
double normalizedTime = (double) myPlayer.currentTime.value / (double) endTime.value;
self.timeSlider.value = normalizedTime;
}
[self slider:nil];
}];
[myPlayer play];
}
Or your can look at this answer What gets called when a UISlider value changes? and setup the valueChange as an observer.

Updating the progress bar in iOS 5

I am developing an iOS audio player, and I want to implement a progress bar that will indicate the progress of the current song which is playing.
In my ViewController class, I have 2 double instances - time and duration, and a AVAudioPlayer instance called background.
- (IBAction)play:(id)sender {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"some_song" ofType:#"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
background = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
background.delegate = self;
[background setNumberOfLoops:1];
[background setVolume:0.5];
[background play];
time = 0;
duration = [background duration];
while(time < duration){
[progressBar setProgress: (double) time/duration animated:YES];
time += 1;
}
}
Could anyone explain what I am doing wrong?
Thanks in advance.
you don't update the progress of the progress bar during playback. When you start to play the sound you set the progress bar to 1, to 2, to 3, to 4, to 5... to 100%. All without leaving the current runloop. Which means you will only see the last step, a full progress bar.
You should use a NSTimer to update the progress bar. Something like this:
- (IBAction)play:(id)sender {
/* ... */
[self.player play];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.23 target:self selector:#selector(updateProgressBar:) userInfo:nil repeats:YES];
}
- (void)updateProgressBar:(NSTimer *)timer {
NSTimeInterval playTime = [self.player currentTime];
NSTimeInterval duration = [self.player duration];
float progress = playTime/duration;
[self.progressView setProgress:progress];
}
when you stop playing invalidate the timer.
[self.timer invalidate];
self.timer = nil;

iPhone : Countdown problems (00:00:00 format)

I use a UISlider to get the input in minutes (range 1 - 120) for a countdown timer and show it on a label like this "01:30:00".
i) I would like when the user sets the timer (using the slider) to adjust the hours and minutes but NOT the seconds. The seconds should start counting AFTER the user starts the countdown. How can i do that?
ii) i have trouble updating the countdownlabel. Could somebody suggest the correct code?
-(IBAction)setTime:(id)sender {
totaltime=timeSlider.value;
hours = totaltime / 60;
minutes = (totaltime % 3600) % 60;
seconds = (totaltime % 3600) * 60;
[countDownLabel setFont:[UIFont fontWithName:#"DBLCDTempBlack" size:45]];
countDownLabel.text = [NSString stringWithFormat:#"%.2i:%.2i:%.2i", hours, minutes, seconds]; }
-(void)countdown {
totaltime -=1;
if(minutes == 0) { [timer invalidate]; }
[countDownLabel setFont:[UIFont fontWithName:#"DBLCDTempBlack" size:45]];
countDownLabel.text = [NSString stringWithFormat:#"%.2i:%.2i:%.2i", hours, minutes, seconds]; }
-(IBAction)fade {
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self selector:#selector (countdown) userInfo:nil repeats:YES]; }
-(IBAction)setTime:(id)sender {
totaltime=timeSlider.value;
hours = totaltime / 60;
minutes = (totaltime % 3600) % 60;
seconds = (totaltime % 3600) * 60;
[countDownLabel setFont:[UIFont fontWithName:#"DBLCDTempBlack" size:45]];
countDownLabel.text = [NSString stringWithFormat:#"%.2i:%.2i:%.2i", hours, minutes, seconds]; }
-(void)countdown {
totaltime -=1;
totaltime=timeSlider.value;
hours = totaltime / 60;
minutes = (totaltime % 3600) % 60;
seconds = (totaltime % 3600) * 60;
countDownLabel.text = [NSString stringWithFormat:#"%.2i:%.2i:%.2i", hours, minutes, seconds];
if(minutes == 0) { [timer invalidate]; }
[countDownLabel setFont:[UIFont fontWithName:#"DBLCDTempBlack" size:45]];
countDownLabel.text = [NSString stringWithFormat:#"%.2i:%.2i:%.2i", hours, minutes, seconds]; }
-(IBAction)fade {
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self selector:#selector (countdown) userInfo:nil repeats:YES]; }
You're decrementing totalTime but not re-calculating your hours, minutes and seconds. So I imagine when you start the countdown, nothing ever changes? You need to recalculate the hours, minutes and seconds within your countdown method.

NSTimer - Stopwatch

I've trying to create a stopwatch with HH:MM:SS, code is as follows:
-(IBAction)startTimerButton;
{
myTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(showActivity) userInfo:nil repeats:YES];
}
-(IBAction)stopTimerButton;
{
[myTimer invalidate];
myTimer = nil;
}
-(void)showActivity;
{
int currentTime = [time.text intValue];
int newTime = currentTime + 1;
time.text = [NSString stringWithFormat:#"%.2i:%.2i:%.2i", newTime];
}
Although the output does increment by 1 second as expected the format of the output is XX:YY:ZZZZZZZZ , where XX are the seconds.
Anyone any thoughts ??
Your stringWithFormat asks for 3 integers but you're only passing in one ;)
Here is some code that I've used before to do what I think you're trying to do :
- (void)populateLabel:(UILabel *)label withTimeInterval:(NSTimeInterval)timeInterval {
uint seconds = fabs(timeInterval);
uint minutes = seconds / 60;
uint hours = minutes / 60;
seconds -= minutes * 60;
minutes -= hours * 60;
[label setText:[NSString stringWithFormat:#"%#%02uh:%02um:%02us", (timeInterval<0?#"-":#""), hours, minutes, seconds]];
}
to use it with a timer, do this :
...
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTimer:) userInfo:nil repeats:YES];
...
- (void)updateTimer:(NSTimer *)timer {
currentTime += 1;
[self populateLabel:myLabel withTimeInterval:time;
}
where currentTime is a NSTimeInterval that you want to count up by one every second.