Toggle play/pause button with loop playback - ios

I have a button that toggles between a play and a pause image when tapped. When play image is shown a looped sound is playing, when pause image is shown sound stops playing.
I have manage to get this to work, but there is one issue. When you tap the button to pause (stop) it plays the sound one last time (so the pause action is delayed by the number of seconds of the sound).
Here's my code:
#implementation ViewController
AVAudioPlayer *myAudio;
- (void)viewDidLoad {
[super viewDidLoad];
[self.myButton setImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[self.myButton setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateSelected];
}
- (IBAction)buttonTapped:(id)sender {
NSURL *musicFile;
musicFile = [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:#"sound" ofType:#"mp3"]];
myAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
if(self.myButton.selected)
[self.myButton setSelected:NO];
else
[self.myButton setSelected:YES];
if(self.myButton.selected)
[myAudio setNumberOfLoops:-1];
[myAudio play];
}

What you're doing is creating a player every time you tap on the button.
You should try and create one AVPlayer (in viewDidLoad), and use it's play and pause functions in the buttonTapped: function.
- (void)viewDidLoad {
[super viewDidLoad];
[self.myButton setImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[self.myButton setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateSelected];
NSURL *musicFile = [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:#"sound" ofType:#"mp3"]];
myAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
}
- (IBAction)buttonTapped:(id)sender {
[self.myButton setSelected:!self.myButton.selected];
if (self.myButton.selected) {
[player seekToTime:kCMTimeZero];
[player play];
}
else {
[player pause];
}
}
Clicking on the button would first toggle it's state (selected or not) and then based on its state, the player will rewind and start playing, or pause itself (instantly).

Related

How to stop an avaudioplayer playing previous song while clicking on newsong?

I created a view with a button songs.
When we click on button it goes to a table which contains list of songs.
When we select a song it goes to another view and plays the song.
Whenever the song is playing we can go back to main view or to the table of songs the song will be playing in background its fine upto here.
But whenever I try to play another song from the table of songs the previous song is not stopped and it continues to play along with the selected song.
My aim is play the song when it is switched to a different view. I have done this one but what I want is whenever I select another song from the table of songs it must stop the previous song and play the selected song.
-(void)playOrPauseButtonPressed:(id)sender
{
[self.view addSubview:today_slokaText];
if(playing==NO)
{
[UIApplication sharedApplication].networkActivityIndicatorVisible=YES;
[playButton setBackgroundImage:[UIImage imageNamed:#"Pause.png"] forState:UIControlStateNormal];
[self.view addSubview:today_slokaText];
// Here Pause.png is a image showing Pause Buttomn
NSError *err=nil;
if (!audioPlayer)
{
[self loadSongAtIndex: selectedIndex];
playing=YES;
}
audioPlayer.numberOfLoops = 0;
[audioPlayer prepareToPlay];
[audioPlayer play];
audioPlayer.delegate=self;
if(!audioPlayer.playing)
{
[audioPlayer play];
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[self.view addSubview:self.activityIndicator];
self.activityIndicator.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
[self.activityIndicator startAnimating];
[playButton setBackgroundImage:[UIImage imageNamed:#"Pause.png"] forState:UIControlStateNormal];
[bg_Image addSubview:activityIndicator];
}
playing=YES;
}
else if (playing==YES)
{
[self.activityIndicator stopAnimating];
self.activityIndicator.alpha=0.0;
// [bg_Image addSubview:activityIndicator];
[playButton setBackgroundImage:[UIImage imageNamed:#"play12.png"] forState:UIControlStateNormal];
[self.view addSubview:today_slokaText];
[audioPlayer pause];
playing=NO;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateViewForPlayerState) userInfo:nil repeats:YES];
[self.view addSubview:today_slokaText];
}
}
/******************************************
load the song from service
*******************************************/
- (void)loadSongAtIndex:(NSInteger) songIndex
{
audioSession=[AVAudioSession sharedInstance];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
urlsArray=[[NSMutableArray alloc]initWithObjects:#"http://01_ARDHANAREESWARASTOTRAM.mp3",#"http://02_AshtaLakshmiStotram.mp3",#"http://03_AYIGIRINANDININANDITHAMEDINI.mp3",, nil];
NSString *sourcePath = [urlsArray objectAtIndex:songIndex];
NSURL *audioURL=[NSURL URLWithString:sourcePath];
NSData *data=[NSData dataWithContentsOfURL:audioURL];
audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:NULL];
audioPlayer.numberOfLoops = 0;
[audioPlayer prepareToPlay];
[audioPlayer play];
audioPlayer.delegate=self;
if(!audioPlayer.playing)
{
[audioPlayer play];
}
if (self.audioPlayer)
{
[self updateViewForPlayerInfo];
[self updateViewForPlayerState];
[self.audioPlayer setDelegate:self];
}
}
You are creating the instance of your audio player everytime you load a song from the table. This creates multiple instances. So whenever you play a song it will be played in the new audio player instance and the previous songs(with different audio player instances) will also keep playing. So what i suggest is that you should create audio player at the class level and not create instances everytime. This will hold the single instance and will play a single song for you.

AVPlayer - how to reset play button

Im working on a app which stream a audio file online. The code below is working, but when the audio file ends, the play button don't reset. The button is still pressed, and before the user can play the audio file again, the user have to press the button 2 times.
My question is: How do i reset the play button automatically after the audio file ends?
Here is my code:
-(IBAction)togglePlayPauseTapped:(id)sender
{
if(self.togglePlayPause.selected) {
[self.audioPlayer pause];
[self.togglePlayPause setSelected:NO];
} else {
[self.audioPlayer play];
[self.togglePlayPause setSelected:YES];
self.audioPlayer = [[AVPlayer alloc] init];
NSString *urlString = #"MYURL";
NSURL* urlStream = [NSURL URLWithString:urlString];
AVPlayerItem * currentItem = [AVPlayerItem playerItemWithURL:urlStream];
[self.audioPlayer replaceCurrentItemWithPlayerItem:currentItem];
[self.audioPlayer play];
}
}`
Set the delegate of audioPlayer to self and make sure the designated ViewController can receive AVAudioPlayer Delegate calls. Then implement the audioPlayerDidFinishPlaying method and call your togglePlayPauseTapped method:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
[self togglePlayPauseTapped:nil];
}
The total should look something like this:
Edit:
And change this
self.audioPlayer = [[AVPlayer alloc] init];
To this:
self.audioPlayer = [[AVAudioPlayer alloc] init];

How to display Pause Button if user click the Play button in AVAudioPlayer in ios

Hi i am developing AVAudioplayer according to my project requirement.I am creating audioplayer programatically. I want to display pause button if user clicks the play button.I wrote some code.But pause button should not displayed if i click the play button.so please help me anybody. Thanks in advance.
-(void)viewDidLoad
{
playButton=[[UIButton alloc]init];
playButton.frame=CGRectMake(125, 120, 29, 29);
playButton.backgroundColor=[UIColor clearColor];
playbackgroundImage=[UIImage imageNamed:#"play.png"];
[playButton setImage:playbackgroundImage forState:UIControlStateNormal];
[playButton addTarget:self action:#selector(playOrPauseButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:playButton];
}
-(void)playOrPauseButtonPressed:(id)sender
{
if(playing==NO)
{
[playButton setBackgroundImage:[UIImage imageNamed:#"Pause.png"] forState:UIControlStateNormal];
// Here Pause.png is a image showing Pause Button.
NSError *err;
AVAudioSession *audioSession=[AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
NSData *data=[NSData dataWithContentsOfURL:url];
audioPlayer=[[AVAudioPlayer alloc]initWithData:data error:&err];
[audioPlayer prepareToPlay];
audioPlayer.delegate=self;
[audioPlayer play];
playing=YES;
}
else if (playing==YES)
{
[playButton setBackgroundImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[audioPlayer pause];
playing=NO;
}
}
The problem is that you are setting Setimage first time and on playOrPauseButtonPressed you are setting SetBackgroundImage.
so replace this method in viewDidLoad
[playButton setBackgroundImage:playbackgroundImage forState:UIControlStateNormal];

ipad movie paused rather play when page is loaded

I have a movie that loads fine and plays fine but it plays as soon as the page loads. I would like it to load in a paused state requiring the user to hen press play to watch.
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *moviePath = [[NSBundle mainBundle] pathForResource:#"iobserve1" ofType:#"mov"];
NSURL *movieURL = [NSURL fileURLWithPath:moviePath];
moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
moviePlayerController.view.frame = CGRectMake(60, 44, 900, 656); // player's frame must match parent's
[self.movieView addSubview:moviePlayerController.view];
moviePlayerController.controlStyle = MPMovieControlStyleEmbedded;
[moviePlayerController prepareToPlay];
[moviePlayerController pause];
}
The pause on the last line does not seem to do anything. Any help? Thanks
Put your code blurb you've written above in viewwillappear.
Then add play at the end like so:
-(void) viewWillAppear: (BOOL) animated {
NSString *moviePath = [[NSBundle mainBundle] pathForResource:#"iobserve1" ofType:#"mov"];
NSURL *movieURL = [NSURL fileURLWithPath:moviePath];
moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
moviePlayerController.view.frame = CGRectMake(60, 44, 900, 656); // player's frame must match parent's
[self.movieView addSubview:moviePlayerController.view];
moviePlayerController.controlStyle = MPMovieControlStyleEmbedded;
[moviePlayerController prepareToPlay];
[moviePlayerController play];
}
at the end of it.
In a viewdidappear do a
-(void) viewDidAppear: (BOOL) animated {
[moviePlayerController pause];
}
Remember to remove code from viewDidLoad
You might want to try setting the MPMoviePlayerController property shouldAutoplay to NO.
Add the following line before your prepareToPlay call;
moviewPlayerController.shouldAutoplay = NO;
From the reference:
shouldAutoplay
A Boolean that indicates whether a movie should begin playback automatically.
#property (nonatomic) BOOL shouldAutoplay
Discussion
The default value of this property is YES. This property determines
whether the playback of network-based content begins automatically
when there is enough buffered data to ensure uninterrupted playback.
Availability
Available in iOS 3.2 and later.
Declared In

iOS How to play multiple videos on one view

I was wondering how to play multiple videos in one page, like where you have two buttons, and when you press one, it plays a video, and when you press the other it plays a different one. I have this code so far:
-(void)WelcomeVideo1
{
NSURL *url31 = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"DirectorsWelcome" ofType:#"mp4"]];
welcomePlayer1 = [[MPMoviePlayerController alloc]
initWithContentURL:url31];
welcomePlayer1.controlStyle = MPMovieControlStyleDefault;
welcomePlayer1.shouldAutoplay = YES;
[self.view addSubview:welcomePlayer1.view];
[welcomePlayer1 setFullscreen:YES animated:YES];
}
-(void) moviePlayBackDidFinish:(NSNotification *)aNotification{
[welcomePlayer1.view removeFromSuperview];
welcomePlayer1 = nil;
}
- (void)moviePlayerWillExitFullscreen:(NSNotification*) aNotification {
[welcomePlayer1 stop];
[welcomePlayer1.view removeFromSuperview];
welcomePlayer1 = nil;
}
-(void)storyVideo1
{
NSURL *url4 = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"OurStory" ofType:#"mp4"]];
storyPlayer1 = [[MPMoviePlayerController alloc]
initWithContentURL:url4];
storyPlayer1.controlStyle = MPMovieControlStyleDefault;
storyPlayer1.shouldAutoplay = YES;
[self.view addSubview:storyPlayer1.view];
[storyPlayer1 setFullscreen:YES animated:YES];
}
-(void) moviePlayBackDidFinish2:(NSNotification *)aNotification{
[storyPlayer1.view removeFromSuperview];
storyPlayer1 = nil;
}
- (void)moviePlayerWillExitFullscreen2:(NSNotification*) aNotification {
[storyPlayer1 stop];
[storyPlayer1.view removeFromSuperview];
storyPlayer1 = nil;
}
but whenever I try to play both videos, the 2nd one I play crashes the app. Any ideas?
Use AVPlayer and AVPlayerLayer instead of MPMoviePlayerController.
Take a look into following apple example.

Resources