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]);
}
Related
Hi in my application I am using UILocalNotifications and AVAudiopPlayer to play a song. When a notification comes I am trying to play a song when I select notification alert. Here is the code, I am getting the sound but isplaying property is setting as YES.
In AppDelegate:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
MainViewController *main=[[MainViewController alloc]init];
[main playSong:notification.soundName];
}
-(void)playSong:(NSString *)songName
{
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:songName ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
[_audioPlayer setDelegate:self];
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
_audioPlayer.numberOfLoops = -1; //Infinite
[_audioPlayer prepareToPlay];
[_audioPlayer play];
}
Replace your code with following code and then try it may be help you.
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
MainViewController *main=[[MainViewController alloc]init];
[main playSong:notification.soundName];
}
-(void)playSong:(NSString *)songName
{
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:songName ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
[_audioPlayer setDelegate:self];
_audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL: soundFileURL fileTypeHint:AVFileTypeMPEGLayer3 error:&errorAudio];
_audioPlayer.numberOfLoops = -1; //Infinite
[_audioPlayer prepareToPlay];
[_audioPlayer play];
}
I’m trying to play a music with volume normalization, applyied by iVolume.
The music play 1 or 2 seconds and just after apply the volume normalization. Apparently the music is correctly, on native iPod player works fine.
After two days searching and testing, I can’t find any solution or tips.
I’m using AVAudioPlayer, because I need to get external audios.
Follow the music:
https://db.tt/52qohzJn
Piece of code:
NSError *setCategoryError = nil;
NSError *setAVError = nil;
NSString *path = [NSString stringWithFormat:#"%#/02GreenDay.m4a", [[NSBundle mainBundle] resourcePath]];
NSURL *soundUrl = [NSURL fileURLWithPath: path];
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: soundUrl error:&setAVError];
NSLog(#"Error: %#",[setAVError localizedDescription]);
AVAudioSession *session = [AVAudioSession sharedInstance];
if (![session setCategory:AVAudioSessionCategoryPlayback
error:&setCategoryError])
{
NSLog(#"%#",[setCategoryError localizedDescription]);
NSLog(#"Error AudioSession");
}
[session setActive:YES error:nil];
[_audioPlayer prepareToPlay];
[_audioPlayer play];
The _audioPlayer is a property.
Any ideas?
Thanks!
I a button that records audio when isNotRecording is false and plays audio when isNotRecording is true. Here is my code in the viewDidLoad function:
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemo.m4a",
nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
// Setup audio session
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
// Define the recorder setting
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
// Initiate and prepare the recorder
recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:NULL];
recorder.delegate = self;
recorder.meteringEnabled = YES;
[recorder prepareToRecord];
Here is my code to play the sound or record:
if (isNotRecording==NO){
if (player.playing) {
[player stop];
}
if (!recorder.recording) {
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
// Start recording
[recorder record];
}
}
else{
if (!recorder.recording){
player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
[player setDelegate:self];
[player play];
}
}
And here is my code to stop the playing/recording:
[recorder stop];
[player stop];
Now, everything works almost perfectly (i.e. I can record and play sounds fine). However, there are two issues. The major one is that after I close out the app and try to play the sound, it does not have a sound to play. I want it to play the previous recording. That is my main issue, but it would also be great if I could reduce the lag from when I press the button and the sound plays. Sometimes, if I press the button and release it very fast, no sound plays at all. Any suggestions are greatly appreciated. However, again, the main issue I need fixed is that the recording doesn't save after I close out the app.
I think what's happening is that when you initialize your AVAudioRecorder when the view loads then that will delete any existing file at the target location, irrespective of whether you start recording at that stage. So I think that's how the file is going missing.
Simplest may be just not to call [recorder prepareToRecord]; when you do, as I suspect that's when your recording is getting deleted.
Or you might want to use a temporary file while recording and move it to the final location when you're notified that the recording is finished, in order to avoid that issue. Code is something like:
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemoTemp.m4a",
nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
// Setup audio session
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
// Define the recorder setting
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
// Initiate and prepare the recorder
recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:NULL];
recorder.delegate = self;
recorder.meteringEnabled = YES;
[recorder prepareToRecord];
if (isNotRecording==NO){
if (player.playing) {
[player stop];
}
if (!recorder.recording) {
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
// Start recording
[recorder record];
}
}
else{
if (!recorder.recording){
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemo.m4a",
nil];
NSURL *inputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:inputFileURL error:nil];
[player setDelegate:self];
[player play];
}
}
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder
successfully:(BOOL)flag
{
if (successfully) {
// Copy temp file used during recording to replace that used when playing
//
pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemo.m4a",
nil];
NSURL *targetFileURL = [NSURL fileURLWithPathComponents:pathComponents];
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtURL:targetFileURL error:&error];
error = nil;
[[NSFileManager defaultManager] copyItemAtURL:recorder.url toURL:targetFileURL error:&error];
}
}
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];
My audio plays from the speaker and I want it play from the receiver (with a button).
At first I am trying to force the sound to output from the receiver. (I want to be compatible with iOS 3.2)
Here is what i have just after the [super viewDidLoad];
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error: nil];
// UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
[[AVAudioSession sharedInstance] setActive:YES error:nil];
and later when I call the play :
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:lblText.text
ofType:#"mp3"]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
if (error)
{
NSLog(#"Error in audioPlayer: %#",
[error localizedDescription]);
} else {
audioPlayer.delegate = self;
}
[self playAudio];
MPVolumeView *volumeView = [[[MPVolumeView alloc] initWithFrame:[volumeSlider frame]] autorelease];
[volumeSlider removeFromSuperview];
[self.view addSubview:volumeView];
What am I doing wrong ?
Here is the answer :
The override is only applicable to the kAudioSessionCategory_PlayAndRecord category and not to AVAudioSessionCategoryPlayback.
https://developer.apple.com/library/ios/#qa/qa1754/_index.html