Reputation: 31
I am trying to code a music player for an assignment and I am stuck with trying to get the slider to update as the song is playing. I have been able to make it so that if the user were to slide the slider the song will rewind/fast-forward to that part of the song. Does anyone know why the slider doesn't continuously update as the song is playing?
Here is the .h file
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
@interface AS3MPViewController : UIViewController <MPMediaPickerControllerDelegate>{
IBOutlet UIButton *playButton;
IBOutlet UIButton *stopButton;
IBOutlet UIButton *pauseButton;
IBOutlet UISlider *volumeSlider;
AVAudioPlayer *musicPlayer;
IBOutlet UIButton *pickSongButton;
IBOutlet UISlider *timeSlider;
NSTimer *timer;
}
@property (nonatomic, retain) UIButton *playButton;
@property (nonatomic, retain) UIButton *stopButton;
@property (nonatomic, retain) UIButton *pauseButton;
@property (nonatomic, retain) UISlider *volumeSlider;
@property (nonatomic, retain) AVAudioPlayer *musicPlayer;
@property (nonatomic, retain) UIButton *pickSongButton;
@property (nonatomic, retain) UISlider *timeSlider;
@property (nonatomic, retain) NSTimer *timer;
- (IBAction) play;
- (IBAction) stop;
- (IBAction) pause;
- (IBAction) changeVolume: (UISlider *)sender;
- (IBAction) chooseSong: (UIButton *)sender;
- (IBAction) changeTime: (UISlider *)sender;
- (void)setTimeSliderOptions;
@end
Here is the .m file
#import "AS3MPViewController.h"
@interface AS3MPViewController ()
@end
@implementation AS3MPViewController
@synthesize playButton = _playButton;
@synthesize stopButton = _stopButton;
@synthesize pauseButton = _pauseButton;
@synthesize musicPlayer = _musicPlayer;
@synthesize volumeSlider = _volumeSlider;
@synthesize pickSongButton = _pickSongButton;
@synthesize timeSlider = _timeSlider;
@synthesize timer;
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"animals001" ofType:@"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
self.musicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
[self.musicPlayer prepareToPlay];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction) play {
[self.musicPlayer play];
}
- (IBAction) stop {
[self.musicPlayer stop];
self.musicPlayer.currentTime = 0;
}
- (IBAction) pause {
[self.musicPlayer pause];
}
- (IBAction) changeVolume: (UISlider *)sender {
self.musicPlayer.volume = [sender value];
}
- (IBAction)chooseSong:(UIButton *)sender {
MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeAnyAudio];
[mediaPicker setDelegate:self];
[mediaPicker setAllowsPickingMultipleItems:NO];
mediaPicker.prompt = NSLocalizedString(@"Add Some Songs To Play", "Prompt In Media Item Picker");
[self presentModalViewController: mediaPicker animated:YES];
}
- (void) mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker {
[self dismissModalViewControllerAnimated:YES];
}
- (void) mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems: (MPMediaItemCollection *)mediaItemCollection {
MPMediaItem *item = [[mediaItemCollection items] objectAtIndex:0];
NSURL *url = [item valueForProperty:MPMediaItemPropertyAssetURL];
//AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:url];
//AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
self.timeSlider.maximumValue = [self.musicPlayer duration];
self.musicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[self.musicPlayer play];
timer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(songCurrentTime) userInfo:nil repeats:YES];
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)changeTime: (UISlider *)sender {
self.musicPlayer.currentTime = self.musicPlayer.duration * sender.value;
}
- (void)songCurrentTime {
timeSlider.value = (self.musicPlayer.currentTime / self.musicPlayer.duration);
}
@end
Upvotes: 3
Views: 1900
Reputation: 1061
There was transparent view over my UISlider in my case and i was overlooking in to it.
Upvotes: 0
Reputation: 2817
For me the issue was different i need to set initial value to slider, but it was a silly mistake that i am updating slider value before setting maximum and minimum value.
Wrong code :
float value = [self getSliderDefaultValue];
[slider setValue:value animated:NO];
slider.maximumValue = numberOfSteps;
slider.minimumValue = 0;
Working code :
slider.maximumValue = numberOfSteps;
slider.minimumValue = 0;
float value = [self getSliderDefaultValue];
[slider setValue:value animated:NO];
Hope it will help others!!!
Upvotes: 0
Reputation: 1001
check in the connections that you are connected the IBAction method with slider with ValueChanged EX:
- (IBAction)changeTime: (UISlider *)sender {
check whether this method is connected with ValueChanged while IB connection
Upvotes: 2
Reputation: 11
I think your problem is that you are updating the value of the slider from a thread other than the main one. Try modifying the songCurrentTime method so that it calls another one on the main thread that updates the value of the slider.
- (void)songCurrentTime {
[self performSelectorOnMainThread:@selector(songCurrentTimeMain) withObject:nil waitUntilDone:YES];
}
- (void)songCurrentTimeMain {
timeSlider.value = (self.musicPlayer.currentTime / self.musicPlayer.duration);
}
Of course to get correct results make sure the minimum value of the slider is 0 and the maximum is 1.
Best Regards
Upvotes: 1
Reputation: 31016
timeSlider
and self.timeSlider
are not the same thing. Most of the iVars that you have declared are unnecessary (and misleading) because you synthesize your properties using the underscore form of the property name. For example, you have a timeSlider
property that's backed by a _timeSlider
iVar, and a timeSlider
iVar that's a different thing entirely.
Use self.timeSlider.value = ...
.
Upvotes: 0
Reputation: 2512
When you set your slider value, the value is always less than or equal to 1 because self.musicPlayer.currentTime
is always less than or equal to self.musicPlayer.duration
. Instead, try this
timeSlider.value = self.musicPlayer.currentTime;
Upvotes: 0
Reputation: 73
I've done something similar within this tutorial and the way I added a slider was the same as you did except for the fact that I used
musicPlayer.currentPlaybackTime
as a value to assign to the slider.
It may be that the result of (self.musicPlayer.currentTime / self.musicPlayer.duration) is an inaccurate assignment to your slider value.
Upvotes: 0