AVAudioPlayer crashing when calling stop - ios

I am trying to run 3 audio files for a specific amount of time then stop them. I can play all 3 audio files at the same time no worries, but when I try to stop them I receive this error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ViewController stopMusic:]: unrecognized selector sent to instance
This is what my code looks like to play the file:
- (void)backgroundTap {
[customerNameTextField resignFirstResponder];
[customerEmailTextField resignFirstResponder];
if ((audioPlayer) || (audioPlayer2) || (audioPlayer3)) {
NSLog(#"still playing");
} else {
[NSTimer scheduledTimerWithTimeInterval:10.0
target:self
selector:#selector(stopMusic:)
userInfo:nil
repeats:NO];
// create audio session
[[AVAudioSession sharedInstance] setDelegate: self];
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];
if (setCategoryError)
NSLog(#"Error setting category! %#", setCategoryError);
// path
NSString *soundPath =[[NSBundle mainBundle] pathForResource:#"tuiSong" ofType:#"mp3"];
NSURL *soundURL = [NSURL URLWithString:soundPath];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error];
audioPlayer.numberOfLoops = 0;
[audioPlayer setVolume: 0.1];
// path
NSString *soundPath2 =[[NSBundle mainBundle] pathForResource:#"beachSong" ofType:#"mp3"];
NSURL *soundURL2 = [NSURL URLWithString:soundPath2];
NSError *error2;
audioPlayer2 = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL2 error:&error2];
audioPlayer2.numberOfLoops = 0;
[audioPlayer2 setVolume: 0.06];
// path
NSString *soundPath3 =[[NSBundle mainBundle] pathForResource:#"CicadaSong" ofType:#"mp3"];
NSURL *soundURL3 = [NSURL URLWithString:soundPath3];
NSError *error3;
audioPlayer3 = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL3 error:&error3];
audioPlayer3.numberOfLoops = 5;
[audioPlayer3 setVolume: 0.05];
// play bells
if (!audioPlayer) {
NSLog(#"localizedDescription : %#", [error localizedDescription]);
} else {
if (![audioPlayer isPlaying]) {
[audioPlayer play];
}
if (![audioPlayer2 isPlaying]) {
[audioPlayer2 play];
}
if (![audioPlayer isPlaying]) {
[audioPlayer3 play];
}
}
}
}
And then this is what I do to stop the audio.
- (void)stopMusic {
if ([audioPlayer isPlaying]) {
[audioPlayer stop];
audioPlayer = nil;
}
if ([audioPlayer2 isPlaying]) {
[audioPlayer2 stop];
audioPlayer2 = nil;
}
if ([audioPlayer3 isPlaying]) {
[audioPlayer3 stop];
audioPlayer3 = nil;
}
}

The error message is describing the problem perfectly. Your NSTimer is calling stopMusic:. But there is no method stopMusic:. There is a method stopMusic. stopMusic is not the same as stopMusic: (with a colon). You must get the name exactly right.

Related

AVAudioPlayer successfully calls play method but not playing sound

AVAudioPlayer successfully calls play method and is working properly in the simulator but it is not playing sound. The device has iOS 7.1.1. This is the code that I have used.
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath = [mainBundle pathForResource:#"miata-hn" ofType:#"wav"];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
NSError *error = nil;
/* Start the audio player */
self.playerAudio = [[AVAudioPlayer alloc] initWithData:fileData error:&error];
self.playerAudio.volume = 1;
if (error)
{
NSLog(#"error localized description %#",[error localizedDescription]);
}
if (self.playerAudio != nil)
{
/* Set the delegate and start playing */
self.playerAudio.delegate = self;
if ([self.playerAudio prepareToPlay] && [self.playerAudio play])
{
NSLog(#"player success");
}
else
{
NSLog(#"sound player failed to play audio");
}
}
else
{
/* Failed to instantiate AVAudioPlayer */
}
I got The solution. After adding this line of code the audio is audible in app.
AVAudioSession should be activated.
**
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
[[AVAudioSession sharedInstance] setActive:YES error:&error];
**
Try using:
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];

AVAudioPlayer not playing sounds simultaneously

I am trying to play a couple of sounds files at the same time for the AVAudioPlayer. I read a thread explaining how to do it # AVAudioPlayer Help: Playing multiple sounds simultaneously, stopping them all at once, and working around Automatic Reference Counting . It seems to be a weird issue as I when i try to only play one file at a time (when self.options.on is ON), it works, but when I try creating multiple instances (the else statements) and play them nothing plays. I checked to see if the outputfile URL is correct and it is, so what is the reason that it isn't working?
Thanks!
- (void)playTapped:(id)sender
{
if (!recorder.recording)
{
if(self.options.on)
{
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
[NSString stringWithFormat:#"sound%i.m4a",last],
nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:outputFileURL error:nil];
NSLog(#"%#",player.url);
[player setDelegate:self];
[player play];
}
else
{
// trying to play all sounds at once
for (NSString *str in self.soundsCreated){
NSLog(#"%#",str);
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
[NSString stringWithFormat:#"sound%#.m4a",str],
nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:outputFileURL error:nil];
NSLog(#"%#",audioPlayer.url);
[audioPlayer prepareToPlay];
[audioPlayer setDelegate:self];
[audioPlayer play];
}
}
}
}
NOTE
I tried initializing with NSError check but i'm not getting any errors:
NSError *sessionError = nil;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:outputFileURL error:&sessionError];
if (sessionError)
{
NSLog(#"Error in audioPlayer: %#",[sessionError localizedDescription]);
}
SOLUTION
It seemed to be an issue with the initialization of my NSMutableArrays.
I changed them from:
self.soundsCreated = [[NSMutableArray alloc]init];
self.playerArray = [[NSMutableArray alloc]init];
to
self.soundsCreated = [NSMutableArray new];
self.playerArray = [NSMutableArray new];
and that fixed it
I have faced the same while played a small file:
Here is my solution (example)
- (void)dropSoundWhileRefresh
{
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&sessionError];
[[AVAudioSession sharedInstance] setActive:YES error:&sessionError];
[[AVAudioSession sharedInstance] setDelegate:self];
NSURL *musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"waterDrops" ofType:#"mp3"]];
dropSound = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
[dropSound setDelegate:self];
[dropSound setVolume:0.10];
[dropSound setNumberOfLoops:0];
[dropSound play];
}
Instead of passing error as nil try this and check if initialization is working correct.
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if (error)
{
DebugLog(#"Error in audioPlayer: %#",[error localizedDescription]);
}

Memory issue with AVAudioPlayer

For some reason, the cleanupPlayer method is a little buggy and isn't releasing the audio player correctly. My application crashes from time to time, and I suspect it's due to a memory issue. Also, when I try to play an audio file twice (on button click), the second time the audio sometimes cuts out. I'm a bit of a newbie, so any help would be greatly appreciated!
Here is a snippet of code:
.h file:
#property (retain,nonatomic)AVAudioPlayer *player;
.m file:
-(void)playSound:(NSString *)fileName
{
// Play
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:fileName ofType:kSoundFileType]];
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
_player.delegate = self;
[_player prepareToPlay];
[_player play];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
[self cleanupPlayer];
}
-(void)cleanupPlayer
{
if(_player != nil) {
[_player release];
}
try this...
-(void)playSound:(NSString *)fileName
{
if (_player.isPlaying) {
[_player stop];
}
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:fileName ofType:#"mp3"]];
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
_player.delegate = self;
[_player prepareToPlay];
[_player play];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
[self cleanupPlayer];
}
-(void)cleanupPlayer
{
_player =nil;
}

My apps is crashing when player is play

I have a very simple app that is supposed to only play an audio file on view. Instead my Xcode is crashing.
I am using Xcode version 6. I have implemented the AVFoundation Framework
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *audioPath = [[NSBundle mainBundle] pathForResource:#"Crowd_cheering"
ofType:#"m4a" ];
NSURL *audioURL = [NSURL fileURLWithPath:audioPath];
NSError *error;
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];
[self.player play];
}
//Try like this with error condition:
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"Moderato"
ofType:#"mp3"]];
NSError *error;
_audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
if (error)
{
NSLog(#"Error in audioPlayer: %#",
[error localizedDescription]);
} else {
_audioPlayer.delegate = self;
[_audioPlayer prepareToPlay];
}
//Before that add import AVFoundation/AVFoundation.h and add delegate AVAudioPlayerDelegate
//then Implement the AVAudioPlayerDelegate Protocol Methods like this
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
}
-(void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error
{
}
-(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{
}
-(void)audioPlayerEndInterruption:(AVAudioPlayer *)player
{
}
Make sure u connected ur play button properly or not and also check whether you Added an Audio File to the Project Resources properly.

how can i play remote .mp3 file in my ios application?

I'm trying to play remote .mp3 file
but its giving the following error.
The operation couldn’t be completed. (OSStatus error -43.)
here is my code :
- (void)viewDidLoad
{
[super viewDidLoad];
isPlaying = NO;
/*
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"Dar-e-Nabi-Per" ofType:#"mp3"]];
*/
NSURL *url = [NSURL
URLWithString:#"http://megdadhashem.wapego.ru/files/56727/tubidy_mp3_e2afc5.mp3"];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
if (error)
{
NSLog(#"Error in audioPlayer: %#",
[error localizedDescription]);
}
else
{
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
}
}
Can anyone please guide me where i'm doing mistake
For steaming audio from a remote server, use AVPlayer instead of AVAudioPLayer.
AVPlayer Documentation
Sample Code:
- (void)playSampleSong:(NSString *)iSongName {
NSString *aSongURL = [NSString stringWithFormat:#"http://megdadhashem.wapego.ru/files/56727/tubidy_mp3_e2afc5.mp3"];
// NSLog(#"Song URL : %#", aSongURL);
AVPlayerItem *aPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:aSongURL]];
AVPlayer *anAudioStreamer = [[AVPlayer alloc] initWithPlayerItem:aPlayerItem];
[anAudioStreamer play];
// Access Current Time
NSTimeInterval aCurrentTime = CMTimeGetSeconds(anAudioStreamer.currentTime);
// Access Duration
NSTimeInterval aDuration = CMTimeGetSeconds(anAudioStreamer.currentItem.asset.duration);
}
Use this to play song from URL
NSData *songData=[NSData dataWithContentsOfURL:url];
self.player = [[AVAudioPlayer alloc] initWithData:songData error:nil];
self.player.numberOfLoops=0;
_player.delegate=self;
[_player prepareToPlay];
[_player play]

Resources