AVAudioPlayer only calls audioPlayerDidFinishPlaying twice - iphone

I'm trying to create a sort of audio playlist using AVAudioPlayer. So I've used the following code:
.h
<AVAudioPlayerDelegate>
{
AVAudioPlayer *audioPlayer;
}
#property (nonatomic, retain) AVAudioPlayer *audioPlayer;
.m
#synthesize audioPlayer;
- (void)viewDidLoad
{
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
audioPlayer.numberOfLoops = 0;
audioPlayer.delegate = self;
[audioPlayer play];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
if (flag)
{
[player release];
currentSong = currentSong + 1;
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[songs objectAtIndex:currentSong] ofType:#"mp3"]];
artist.text = [artists objectAtIndex:currentSong];
song.text = [songs objectAtIndex:currentSong];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
audioPlayer.delegate = self;
audioPlayer.numberOfLoops = 0;
[audioPlayer initWithContentsOfURL:url error:nil];
[audioPlayer play];
}
}
This works for two songs, but after this there isn't any audio. Any idea why this is?
Thanks,
Denis

In this line you are initing an audio player:
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
Then you are initing it again in this line (unneeded duplication, and probably an additional retain):
[audioPlayer initWithContentsOfURL:url error:nil];
Then the next time the loop comes around, even though you release it using the line
[player release];
…there is a problem as it is still in memory, tying up a hardware codec or wasting resources. Try removing the second initWithContents… line as it is unnecessary.

1.Just maintain an array.
2.Once you create an instance of audioPlayer - add to the array and call play and release the instance of audioPlayer(since it will get retained once you added to array).
3.In audioPlayerDidFinishPlaying remove the audioPlayer from that array.
So you can play multiple files at a time

Related

After recording audio and save to document directory unable to play audio file with AVAudioPlayer

I'm working on application which has record audio and play that recorded file which is store in document directory.
Here is my code:
Record button method.
(IBAction)stopButtonPressed:(id)sender{
UIButton *button = (UIButton *)sender;
if (button.selected) { // Play recorded file.
self.stopButton.selected = NO;
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioRecorder.url error:&error];
self.audioPlayer.delegate = self;
self.audioPlayer.volume = 1.0;
[self.audioPlayer prepareToPlay];
[self.audioPlayer play];
}
else{ // Stop recording.
self.stopButton.selected = YES;
if (recordTimer) {
[recordTimer invalidate];
}
[self.audioPlayer stop];
self.recordButton.selected = NO;
[audioRecorder stop];
self.readyLabel.text = #"READY";
[self insertNewRecording];
}
}
I take it you're using ARC, in which case you'll need to retain the AVAudioPlayer as it sets to nil automatically. In your header file enter the following`
#property (nonatomic, strong) AVAudioPlayer *audioPlayer;
Hope this works for you,
Cheers Jim
um..I am not sure. But as a test, maybe you can try if you can play the file by specifying its name? E.g. you got a forest.mp3 to play and the key part of the code can be like this:
path = [[NSBundle mainBundle] pathForResource:#"forest" ofType:#"mp3"];
NSData *sampleData = [[NSData alloc] initWithContentsOfFile:path];
NSError *audioError = nil;
av = [[AVAudioPlayer alloc] initWithData:sampleData error:&audioError];
If everything went well, maybe it's something to do with audioRecorder.url in your code?
Hope this gives you some ideas.

XCODE IOS memory leak for AVAudioPlayer

I use ARC.
Here is the method for starting the audio in my code:
.h file:
#property (retain,nonatomic)AVAudioPlayer *myAudio;
and .m files
-(void)myPlaySound:(NSString *)mySoundFile NumberOfLoops:(int)loopsCount ofType:(NSString *)fileType
{
if([myAudio isPlaying])
{
[myAudio stop];
}
NSURL* musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:mySoundFile
ofType:fileType]];
NSError *error;
myAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:&error];
self.theAudio = myAudio;
myAudio.volume = audioVolume;
myAudio.numberOfLoops = loopsCount;
myAudio.currentTime = 0.0;
[myAudio prepareToPlay];
if([myAudio play] == NO)
{
NSLog(#"error");
}
}
Based on the button press, I play different audio files of different length and bit rate and types.
Its working, but I get memory leak issue.

How to auto play music as soon as my app starts?

I need some help with my app I have recently started. I am a very big starter to coding so please do help me, it'll mean a lot. I need a piece of music to play as soon as the user enters my app, i have followed other youtube tutorials but they only work for the older Xcode versions, so please help thank you so much.
How about putting it in you application didFinishLaunching but be sure to instantiate it in you .h and .m.
Something like this should do your problem:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
resourcePath = [resourcePath stringByAppendingString:#"/YOURMUSICNAME.wav"];
NSLog(#"Path to play: %#", resourcePath);
NSError* err;
//Initialize our player pointing to the path to our resource
player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:resourcePath] error:&err];
if( err ){
//bail!
NSLog(#"Failed with reason: %#", [err localizedDescription]);
}
else{
//set our delegate and begin playback
player.delegate = self;
[player play];
player.numberOfLoops = -1;
player.currentTime = 0;
player.volume = 1.0;
}
}
Then if you want to stop it:
[player stop];
or pause it :
[player pause];
and also import it in your header file:
#import <AVFoundation/AVFoundation.h>
EDIT:
You should to ofcourse declare it in your header, then synthesize it.
//.h and add the bold part:
#interface ViewController : UIViewController <AVAudioPlayerDelegate> {
AVAudioPlayer *player;
}
#property (nonatomic, retain) AVAudioPlayer *player;
//.m
#synthesize player;
You can use the AVAudioPlayer. It pretty straight forward to use:
NSURL *path = [[NSURL alloc] initFileURLWithPath:[DataPersister getQualifiedPathForFileInDirectory:DataPersisterPathBundle fileName:#"music.mp3"]];
NSError *outError;
AVAudioPlayer *musicSound = [[AVAudioPlayer alloc] initWithContentsOfURL:path error:&outError];
[musicSound play];
[path release];
Remember to import
#import <AVFoundation/AVFoundation.h>
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/MUSIC.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = -1;
[audioPlayer play];
audioPlayer.volume = 1.0;
audioPlayer.currentTime = 2;
Use this at - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method will play music for sure
Happy Coding ;)

Handle audio interruptions AVAudioPlayer

I am playing "sound effects" in my app when buttons are clicked and such and I have been having some difficulties getting the delegates to work properly within the AVAudioPlayer class to keep the music playing after the sound. I have the framework imported and delegates set but I can not seem to get the AVAudioSession shared instance to work... I know I am missing something but can not seem to find a clear answer anywhere even within apples docs. Here is the code I am using trying to accomplish this.
#import "AVFoundation/AVAudioPlayer.h
#import "MediaPlayer/MediaPlayer.h"
#interface HomeViewController : UIViewController <AVAudioPlayerDelegate, MPMediaPlayback
> {
When a button is pushed
-(IBAction)About
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"button" ofType:#"caf"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
AboutViewController *about = [[AboutViewController alloc] init];
[self presentModalViewController:about animated:YES];
NSString *path1 = [[NSBundle mainBundle] pathForResource:#"move" ofType:#"caf"];
AVAudioPlayer* theAudio1 = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path1] error:NULL];
theAudio.delegate = self;
[theAudio1 play];
}
Delegates trying to either play my sound as a "ambient noise" or just resume play after my sound happens
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
}
-(void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error
{
}
-(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{
}
-(void)audioPlayerEndInterruption:(AVAudioPlayer *)player withFlags:(NSUInteger)flags
{
if (flags)
{
AVAudioPlayer *audio = [[AVAudioPlayer alloc] init];
[audio setDelegate:self];
[audio play];
}
}
Now the last delegate from what I understand is the only delegate of use really in my case and what I have will not work since I need to be using the [AVAudioSession SharedInstance] like this but I can not seem to get the AVAudioSession to work!
-(void)audioPlayerEndInterruption:(AVAudioPlayer *)player withFlags:(NSUInteger)flags
{
if (flags == AVAudioSessionFlags_ResumePlay)
{
[player play];
}
}
Any help or suggestions would be greatly appreciated. I basically just need to know how to get the [AVAudio SharedInstance] so if anyone knows what class I need to import or framework I need to add to get this working it would be very much obliged!
Thanks

iOS - How to stop background music when changing views

How to stop background music when changing views? I have no clue. If i press a button which takes me to a new view, there is new background music. But the old background music (which goes in an infinite loop) keeps on going. Please help! also sample some code please, here is mine:
- (void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] pathForResource:#"MathMusic2" ofType:#"wav"];
AVAudioPlayer* theAudio= [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
theAudio.numberOfLoops = -1;
[super viewDidLoad];
}
I just need to know how to make the background music from the new view stop playing. And vice versa when i press the back button from the new view
Create a property for the AVAudioPlayer *theAudio so you can access the audioPlayer from any point in your class.
Header file of viewController
...
AVAudioPlayer *theAudio;
...
#property (nonatomic, retain) AVAudioPlayer *theAudio;
Implentation file of viewController
...
#synthesize theAudio;
...
- (void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] pathForResource:#"MathMusic2" ofType:#"wav"];
self.theAudio= [[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]] autorelease];
theAudio.delegate = self;
[theAudio play];
theAudio.numberOfLoops = -1;
[super viewDidLoad];
}
If viewWillDisappear is called you can then just stop the audio with
- (void)viewWillDisappear
{
[theAudio stop];
}
it gaves errors in here :
"theAudio.delegate = self;" as something like assigning to id...
its yellow anyway..
still when i change view and go to another class music not stoping....