iOS play audio through iPhone receiver (phone speaker) - ios

I am currently working on an application which should play Audio files through the iPhone receiver. I know it was easily possible before iOS 6/7, but those methods are deprecated now.
So does anybody know how it works on iOS 7?
This is my code, which does not work:
_audioSession = [AVAudioSession sharedInstance];
[_audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[_audioSession overrideOutputAudioPort:AVAudioSessionPortBuiltInReceiver error:nil];
NSString *ringtone = [[NSUserDefaults standardUserDefaults] stringForKey:#"ringtone"];
ringtone = [ringtone stringByReplacingOccurrencesOfString:#".m4r" withString:#""];
NSString *path;
path = [[NSBundle mainBundle] pathForResource:#"abto_ringbacktone" ofType:#"wav"];
NSError *error;
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:&error];
if (error) {
NSLog(#"Error: %#",error.localizedDescription);
}
}
[_player setNumberOfLoops:10];
[_player prepareToPlay];
[_player play];
[_player setVolume:0.1];

You cannot pass AVAudioSessionPortBuiltInReceiver to the overrideOutputAudioPort:error: because it takes enum as an argument, not a string.
Correct way to do this is to configure session as follows for Receiver:
[_audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[_audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:nil];
and for Speaker:
[_audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[_audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];

Related

How to play sound during phone call from application

I want to use the same feature in app like VOYPI in iOS.
Playing a background sound during a call.
I have used the below code for playing background sound during call.
Link for the reference app is here.
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:self.bgAudioFileName ofType: #"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath ];
myAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
myAudioPlayer.numberOfLoops = -1;
NSError *sessionError = nil;
// Change the default output audio route
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
// get your audio session somehow
[audioSession setCategory:AVAudioSessionCategoryMultiRoute error:&sessionError];
BOOL success= [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&sessionError];
[audioSession setActive:YES error:&sessionError];
if(!success)
{
NSLog(#"error doing outputaudioportoverride - %#", [sessionError localizedDescription]);
}
[myAudioPlayer setVolume:1.0f];
[myAudioPlayer play];
}
This code will playbackground sound on ongoing carrier call using avaudioplayer.
I have set category AVAudioSessionCategoryMultiRoute.
Using this category receiver will able to listen background sound during ongoing carrier call from app.
But there was one problem with this it will create echo on receiver side.
Help me in this code.

Playing music with audio normalize using AVAudioPlayer

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!

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]);
}

Output sound to receiver and not to speaker

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

Resources