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.
Related
Have problem in playsound section.When i turn switch off - soundchecker change his value to NO,but audioplayer not stopping.What's wrong guys?
-(IBAction)Settings {
if(settingsview==nil) {
settingsview=[[UIView alloc] initWithFrame:CGRectMake(10, 130, 300, 80)];
[settingsview setBackgroundColor:[UIColor clearColor]];
UILabel *labelforSound = [[UILabel alloc]initWithFrame:CGRectMake(15, 25, 70, 20)];
[labelforSound setFont:[UIFont systemFontOfSize:18]];
[labelforSound setBackgroundColor:[UIColor clearColor]];
[labelforSound setText:#"Sound"];
SoundSwitch = [[UISwitch alloc]initWithFrame:CGRectMake(10, 50, 20, 20)];
SoundSwitch.userInteractionEnabled = YES;
if(soundchecker == YES) [SoundSwitch setOn:YES];
else [SoundSwitch setOn:NO];
[SoundSwitch addTarget:self action:#selector(playsound:) forControlEvents:UIControlEventValueChanged];
[settingsview addSubview:labelforSound];
[settingsview addSubview:SoundSwitch];
[self.view addSubview:settingsview];
}
else {
[settingsview removeFromSuperview];
[settingsview release];
settingsview=nil;
}
}
//-------Playsound------------------//
-(void)playsound:(id) sender {
NSString *pathtosong = [[NSBundle mainBundle]pathForResource:#"Teachme" ofType:#"mp3"];
AVAudioPlayer* audioplayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathtosong] error:NULL];
if(SoundSwitch.on) {
[audioplayer play];
soundchecker = YES;
}
if(!SoundSwitch.on) {
[audioplayer stop];
soundchecker = NO;
}
}
It's not stopping because every time that playsound is called you are creating a NEW AVAudioPlayer. So when you call [audioplayer stop], you are not calling it on the AVAudioPlayer that is currently playing, you are calling it on a new one you just created.
You could add the AVAudioPlayer variable to the header of your class (as a property if you want). Then you could do this:
-(void)playsound:(id) sender
{
if(SoundSwitch.on)
{
if(!audioPlayer) {
NSString *pathtosong = [[NSBundle mainBundle]pathForResource:#"Teachme" ofType:#"mp3"];
audioplayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:pathtosong] error:nil];
}
[audioplayer play];
soundchecker = YES;
} else {
if(audioPlayer && audioPlayer.isPlaying) {
[audioplayer stop];
}
soundchecker = NO;
}
}
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.
Getting red warnings for {[audioPlayer pause];}saying Expected']' and getting another red warning message for [[audioPlayer play];] saying Expected expression.
UIButton *playpauseButton = [UIButton buttonWithType:UIButtonTypeCustom];
[playpauseButton addTarget:self action:#selector(playpauseAction:) forControlEvents:UIControlEventTouchUpInside];
playpauseButton.frame = CGRectMake(0, 0, 50, 50);
[playpauseButton setImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[playpauseButton setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateSelected];
UIBarButtonItem *playpause = [[UIBarButtonItem alloc] initWithCustomView:playpauseButton];
The action code:
-(void)playpauseAction:(UIButton *)sender
{
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"theme"
ofType:#"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:fileURL error:nil];
[fileURL release];
[audioPlayer prepareToPlay];
audioPlayer.currentTime = 0;
//[audioPlayer play];
if
([audioPlayer isPlaying]){
Image:[UIImage imageNamed:#"play.png"] forState:UIControlStateSelected
setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateNormal
{[audioPlayer pause];}
} else {
setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateSelected
Image:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal
[[audioPlayer play]; ]
}
}
I need help in fixing this code.
Thanks for help.
The entire play/pause part of your method is completely invalid Objective-C. Try this instead:
if ([audioPlayer isPlaying])
{
[sender setImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[audioPlayer pause];
}
else
{
[sender setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateNormal];
[audioPlayer play];
}
Also, you really don’t need to be recreating your audioPlayer in that method. Put it (where by “it” I mean “everything in that method between the first line and the ‘if’”) in your -viewDidLoad or something.
try setting the delegate and checking for error:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"theme" ofType:#"mp3"];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: [NSURL fileURLWithPath:filePath] error:&err];
if( err ){
NSLog(#"Failed with reason: %#", [err localizedDescription]);
} else{
//set our delegate and begin playback
audioPlayer.delegate = self;
[audioPlayer play];
}
btw, you definitely don't want to be allocing the audioPlayer every time the button is pressed, unless you check if it's nil first (for the first run through).
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];
}
}
I am trying to figure out how to hook up a button to play a sound programmatically without using IB. I have the code to play the sound, but have no way of hooking the button up to play the sound? any help?
here is my code that I'm using:
- (void)playSound
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"boing_1" ofType:#"wav"];
AVAudioPlayer* myAudio = [[AVAudioPlayer alloc]
initWithContentsOfURL:[NSURL fileURLWithPath:path error:NULL]];
myAudio.delegate = self;
myAudio.volume = 2.0;
myAudio.numberOfLoops = 1;
[myAudio play];
}
[button addTarget:self action:#selector(playSound) forControlEvents:UIControlEventTouchUpInside];
UIButton inherits its target/action methods from UIControl.
To hook up the button, make your playSound method the handler for the button's UIControlEventTouchUpInside event. Assuming this is in a view controller, you might want to put this in the viewDidLoad method:
[button addTarget:self action:#selector(playSound) forControlEvents:UIControlEventTouchUpInside];
FYI, you're leaking memory because you're alloc-ing an object but never release-ing it.
You should create a new AVAudioPlayer member for the class to avoid this.
#interface MyViewController : ...
{
...
AVAudioPlayer* myAudio;
...
}
- (void)playSound
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"boing_1" ofType:#"wav"];
[myAudio release];
myAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path error:NULL]];
myAudio.delegate = self;
myAudio.volume = 2.0;
myAudio.numberOfLoops = 1;
[myAudio play];
}
Don't forget to put [myAudio release] in your dealloc method.
(I did this without declaring myAudio as a #property, but that's not strictly necessary)