I am working on an app in Xcode which uses AVAudioPlayer.
#property (nonatomic, strong) AVAudioPlayer *player;
on tap of an image I call a function which plays the audio file:
-(void)playMusic{
if(self.player.currentTime == 0.0){
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/sound.mp3", [[NSBundle mainBundle] resourcePath]]] error:nil];
self.player.numberOfLoops = 0;
[self.player play];
}
}
on viewWillDisappear I need to stop the player, so I call:
-(void)viewWillDisappear:(BOOL)animated{
[self.player stop];
}
But the above code does not work, and the audio does not stop playing.
Can anyone please tell me what the issue could be ?
Why don't you stop Playing song with same image tap as,
if([player isPlaying] )
{
[player pause];
}
else
[player play];
Related
I play video streams with AVPlayer.
Some of streams plays only if click button "Play" for 2-5 times. (sorry, I can't provide link, and don't sure what especial in this streams, but may be problem only with full hd streams)
I do like that:
fields:
AVPlayerItem *playerItem;
AVPlayer *player;
AVPlayerViewController *playerViewController;
in viewDidLoad:
player = [[AVPlayer alloc] init];
playerViewController = [[AVPlayerViewController alloc] init];
playerViewController.player = player;
when click "Play":
NSURL *videoURL = [NSURL URLWithString:strUrl];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
playerItem = [AVPlayerItem playerItemWithAsset:asset];
[playerItem addObserver:self
forKeyPath:#"status"
options: NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:nil];
[player replaceCurrentItemWithPlayerItem:playerItem];
and observing:
NSLog(#"status changed");
if (((AVPlayerItem *)object).status == AVPlayerStatusReadyToPlay)
{
NSLog(#"ready to play");
[playerItem removeObserver:self forKeyPath:#"status"];
[self presentViewController:playerViewController animated:YES completion:nil];
[player play];
}
else if (((AVPlayerItem *)object).status == AVPlayerStatusFailed)
{
NSLog(#"failed to ready");
}
else if (((AVPlayerItem *)object).status == AVPlayerStatusUnknown)
{
NSLog(#"unknown");
}
First always "unknown" but in problem cases no messages after (but most streams play normally and I see "ready to play" message)
I've tried to observe player.status but when it ReadyToPlay and I start play I see only first frame and endless message "Loading" in top of screen.
I am making an alarm app for iPhones and want to continuously loop the audio until the button is pressed again. As of now all it does is play the audio once when pressed. Here's the code:
-(IBAction)PlayAudioButton:(id)sender {
AudioServicesPlaySystemSound(PlaySoundID);
}
- (void)viewDidLoad {
NSURL *SoundURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Sound" ofType:#"wav"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)SoundURL, &PlaySoundID);
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
Any suggestions?
Use AVAudioPlayer to play the sound. You must add AVFoundation.framework to your project for this to work. Start by declaring an AVAudioPlayer object. It must be declared either as a property with a strong attribute, e.g.
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
or as an instance variable with a __strong attribute
#interface Class : SuperClass //or #implementation Class
{
AVAudioPlayer __strong *audioPlayer;
}
Then, to load and play the file,
- (void)viewDidLoad
{
NSString *audioFilePath = [[NSBundle mainBundle] pathForResource:#"Sound" ofType:#"wav"];
NSURL *audioFileURL = [NSURL fileURLWithString:audioFilePath];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL error:nil];
audioPlayer.numberOfLoops = -1; //plays indefinitely
[audioPlayer prepareToPlay];
}
- (IBAction)PlayAudioButton:(id)sender
{
if ([audioPlayer isPlaying])
[audioPlayer pause]; //or "[audioPlayer stop];", depending on what you want
else
[audioPlayer play];
}
and, when you want to stop playing the sound, call
[audioPlayer stop];
So I have an app where I want to include background music. I use the following code for the music:
.h: (I did also add the framework)
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface ViewController : UIViewController
{
AVAudioPlayer *player;
}
.m:
- (void)viewDidAppear:(BOOL)animated {
NSURL *url = [[NSBundle mainBundle] URLForResource:#"song" withExtension:#"mp3"];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
player.numberOfLoops = -1;
[player play];
NSLog(#"playing music");
}
The path for the music file is definitly correct. The app does not crash but I just do not hear any music.
By the way: the LogMessage ("playing music") appears in the debugger.
Any ideas?
Add prepareToPlay method before [player play];
[player prepareToPlay];
Hope this will work...
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];
I have an iOS app which works like this:
First view
3 buttons that link to different views, each has its own audio file within
Imagine user opens one view, and starts to play the audio file. When they navigate around the app, the audio file still plays which is fine, Im happy with that.
However, if user then opens the second audio file and presses play, it plays on top of the first one so 2 audios are playing together.
How do I tell the code that if another play button is pressed it should stop the first audio file that is playing??
I am using AVFoundation framework to do this
Code is as follows:
NSString *stringPath = [[NSBundle mainBundle]pathForResource:#"01" ofType:#"MP3"];
NSURL *url = [NSURL fileURLWithPath:stringPath];
NSError *error;
avPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
[avPlayer setNumberOfLoops:2];
[avPlayer setVolume:self.sliderVolumeOutlet.value];
[NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:#selector(updateMyProgress) userInfo:nil repeats:YES];
-(void)updateMyProgress
{
float progress = [avPlayer currentTime]/[avPlayer duration];
self.myProgressView.progress = progress;
}
- (IBAction)sliderVolumeAction:(id)sender {
UISlider *mySlider = sender;
[avPlayer setVolume:mySlider.value];
}
- (IBAction)stopButton:(id)sender {
[avPlayer stop];
[avPlayer setCurrentTime:0];
}
- (IBAction)pauseButton:(id)sender {
[avPlayer pause];
}
- (IBAction)playButton:(id)sender {
[avPlayer play];
}
- (IBAction)backButtonEvent:(id)sender {
[self dismissViewControllerAnimated:YES completion:NULL];
}
You can check whether it is playing the previous track or not by if ([AVPlayer rate] != 0.0)
If it is playing then you can either add the next track into queue or just use this function to replace current track with the new one - (void)replaceCurrentItemWithPlayerItem:(AVPlayerItem *)item
Perhaps creating some sort of playSound function would be better suited for this. Something like this:
- (void)playSoundWithFileName:(NSString *)fileName andExtension:(NSString *)extension {
NSString *stringPath = [[NSBundle mainBundle]pathForResource:fileName ofType:extension];
NSURL *url = [NSURL fileURLWithPath:stringPath];
NSError *error;
if (avPlayer) {
[avPlayer stop];
avPlayer = nil;
}
avPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
if (error)
NSLog(#"Error");
else {
[avPlayer setNumberOfLoops:2];
[avPlayer setVolume:self.sliderVolumeOutlet.value];
[avPlayer play];
}
}
Use:
[self playSoundWithFileName:#"01" andExtension:#"MP3"];
[NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:#selector(updateMyProgress) userInfo:nil repeats:YES];
and call -(void)playSoundWithFileName whenever you want to play another sound.
Or if you were using the AVPlayer class:
- (void)playSoundWithFileName:(NSString *)fileName andExtension:(NSString *)extension {
NSString *stringPath = [[NSBundle mainBundle]pathForResource:fileName ofType:extension];
NSURL *url = [NSURL fileURLWithPath:stringPath];
AVPlayerItem *item = [AVPlayerItem playerItemWithURL:url];
if (avPlayer)
[avPlayer replaceCurrentItemWithPlayerItem:item];
else
avPlayer = [AVPlayer playerWithPlayerItem:item];
[avPlayer setVolume:self.sliderVolumeOutlet.value];
[avPlayer play];
}
Though the latter doesn't allow you set a number of loops.