AVAudioPlayer plays on silent mode when MPMoviePlayer plays - iphone

The issue is that AVAudioPlayer in itself behaves as it should. It plays background music when the device is not in silent mode (silent/ringer switch is on). When the silent switch is on, it also respects this state and does not play the background music.
However, one peculiar scenario that the AVAudioPlayer plays in silent mode is when I play a video in MPMoviePlayer.
In my app, the BG sound is played first before playing the movie.
Can anyone help? This only occurs when I play the movie.
For other details:
BG Loop used - m4a type
Movie type used - m4v
I also found out that this scenario repeatedly surfaces in iOS 5 but it sometimes happen even in the latest versions.
I've researched everywhere in Google, Apple's documents, and in SO but I couldn't find anything regarding this particular scenario.
I even tried explicitly setting the AVAudioSession's category to AVAudioSessionCategoryAmbient and then calling setActive. (Also tried the setCategory:withOptions:error method but the app crashes for some reason -- tested on device)
I even tried setting the delegate and implementing methods when I tried to use the AVAudioPlayerDelegate.
Help anyone? :(

NSURL *url = [NSURL URLWithString:self.videoURL];
MPMoviePlayerViewController *mpvc = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
NSError *_error = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &_error];
[self presentMoviePlayerViewControllerAnimated:mpvc];
Add this framework
#import <AVFoundation/AVFoundation.h>
try like this...

try to set the audio session in this way
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err){
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}
[audioSession setActive:YES error:&err];
err = nil;
if(err){
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}

Related

AVAudioSession use AVAudioSessionPortOverrideNone and AVAudioSessionModeVideoRecording

Hi guys I'm doing an enterprise app to detect when an iOS device as a failing microphone or speaker.
I need to use the secondary microphone (the one used when recording video) and the only way I found it was using AVAudioSessionModeVideoRecording but I also need to use lower speaker and I am using AVAudioSessionPortOverrideNone, but the problem is that when I use AVAudioSessionModeVideoRecording the audio always goes thru the speaker and not the default earpiece.
here is my code
AVAudioSession* session = [AVAudioSession sharedInstance];
BOOL success;
NSError* error;
success = [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
if (!success) NSLog(#"AVAudioSession error setting category:%#",error);
success = [session overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&error];
if (!success) NSLog(#"AVAudioSession error on output audio port: %#",error);
success = [session setMode:AVAudioSessionModeVideoRecording error:&error];
if (!success) NSLog(#"AVAudioSession error setting mode: %#",error);
thanks guys

Audio file doesn't play in iPhone 5

I use a code for playing a .caf audio file, the same code works good in an iPhone 4s and an iPad 2 but doesn't play at all in a iPhone 5...
this is the code:
-(IBAction)checkSound:(id)sender
{
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/Lunatic.caf", [[NSBundle mainBundle] resourcePath]]];
NSLog(#"%#",url);
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
self.audioPlayer.numberOfLoops = 0;
self.audioPlayer.volume = 1;
NSLog(#"log audioplayer: %#",audioPlayer);
if (audioPlayer != nil)
{
[self.audioPlayer prepareToPlay];
[self.audioPlayer play];
}
if (audioPlayer.playing == NO)
{
NSLog(#"not playing, error: %#",error);
}
if([[NSFileManager defaultManager] fileExistsAtPath:#"file://localhost/var/mobile/Applications/0D3F5169-8DB1-4398-A09A-DB2FBADF57EF/myApp.app/Lunatic.caf"])
{
NSLog(#"file exist");
}
else
{
NSLog(#"file doesn't exist");
}
}
and this is the log output:
2013-08-07 20:05:52.694 myApp[7006:907] file://localhost/var/mobile/Applications/0D3F5169-8DB1-4398-A09A-DB2FBADF57EF/myApp.app/Lunatic.caf
2013-08-07 20:05:52.697 myApp[7006:907] log audioplayer: (null)
2013-08-07 20:05:52.701 myApp[7006:907] not playing, error: Error Domain=NSOSStatusErrorDomain Code=-43 "The operation couldn’t be completed. (OSStatus error -43.)"
2013-08-07 20:05:52.703 myApp[7006:907] file doesn't exist
As you can see the audioplayer log gives "null" and the error log says error -43....
but I repeat... with iphone 4s everything works good....
Any clue why is this happening? Did they change something with audio in iPhone 5? Could it be a setting in my iPhone 5 that's preventing the sound to play? Any help would be greatly appreciated
Have you called [audioPlayer prepareToPlay] prior to calling play? Also have you double checked the audioRoutes to ensure it is playing out of the proper channel?
Two good sanity checks are to:
1.) Call [audioPlayer isPlaying] and see if it returns yes or no after you call play.
2.) Set the AVAudioPlayerDelegate and wait for the callback on audioPlayerDidFinishPlaying: and see if it gets called after the length of your audio.
http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioPlayerClassReference/Reference/Reference.html
EDIT:
Since you're file actually isn't playing, that most likely means you have something wrong with the path you're calling.
Print out your path with an NSLog and also check to see if the file actually exists using:
if([[NSFileManager defaultManager] fileExistsAtPath:yourPath])
{
}

iPhone vibration while playing audio

My application plays audio using AudioQueue and AudioSession. I can't stop playing according to application workflow. Currently, my customer ask me to perform iPhone vibration according to some conditions. I've tried to perform it with AudioServices playing vibration as system sound or alert sound. There is not positive result. Could somebody help me and tell how to implement it? I'm making legal application for non jailbreaked iPhones and can't use custom freamworks because Apple can reject application.
Thank you.
Solved using this solution :)
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayback error:&err];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
This is how I get the vibration:
#import <AudioToolbox/AudioToolbox.h>
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayback error:&err];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
Hope it helps
For reference, I'm not using AudioQueue but an AVAudioEngine to record something, and for my case I pinpointed it down to having to pause the input in order to play the vibration properly with AudioServicesPlaySystemSound during a record session.
So in my case, I did something like this
audioEngine?.pause()
AudioServicesPlaySystemSound(1519)
do {
try audioEngine.start()
} catch let error {
print("An error occurred starting audio engine. \(error.localizedDescription)")
}

Record and play audio same time

I am trying to make the audio record and play back at the same time. Here is the code. It will only record and play back later. I want it to play back simultaneously over the speakers. Any help. I am not even sure I am using the right classes.
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession setActive:YES error:nil];
temporaryRecFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithString:#"VoiceFile"]]];
recorder = [[AVAudioRecorder alloc] initWithURL:temporaryRecFile settings:nil error:nil];
[recorder setDelegate:self];
[recorder prepareToRecord];
[recorder record];
AVAudioPlayer * player = [[AVAudioPlayer alloc] initWithContentsOfURL:temporaryRecFile error:nil];
player.volume = 1;
[player play];
Are you recording from the iPhone microphone? Chances are you'll get feedback if you try to play the recording back while recording it. The microphone will hear what the speakers are playing and rerecord it at a slight delay. This would snowball until your recording sounds like a train wreck.
You are using correct classes but I think you must add AutioUnits also.
Apple has a sample code aurioTouch2 and I think it contains what you need.

How to use MPMusicPlayerController with AVAudioPlayer

I am trying to play an in app audio with ipod the code I am using to play the audio file is:
Code:
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];
UInt32 doSetProperty = 1;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty);
[[AVAudioSession sharedInstance] setActive: YES error: nil];
if(error)
{
NSLog(#"Some error happened");
}
NSString *path = [[NSBundle mainBundle] pathForResource:effect ofType:type];
myPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
myPlayer.delegate = self;
myPlayer.numberOfLoops = -2;
myPlayer.volume = 1.0f;
[myPlayer play];
and to play the ipod music I am using
Code:
player = [MPMusicPlayerController iPodMusicPlayer];
My ipod plays fine until the audio starts playing but once the audio stops I am not able to get back to the ipod to play. I am using
Code:
NSString *value = [[NSUserDefaults standardUserDefaults] stringForKey:#"sound"];
if([value compare:#"ON"] == NSOrderedSame && myPlayer != nil)
{
[myPlayer stop];
[myPlayer release];
myPlayer = nil;
}
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&error];
if(error)
{
NSLog(#"Some error happened");
}
to stop the audio and then just call
Code:
[player play];
to play the ipod music but it does not play the music, it says the title to be null.
I would really appreciate if some one could help me with this.
Regards,
Ankur
I suggest moving the audio session setup (including the Ambient category) to your application delegate's didFinishLaunchingWithOptions and not using the Playback category at all. You can still play AVAudio sounds just fine with the Ambient setting.
If you want to kill iPod music whenever you play AV sounds, then you should only be using the Playback category. (I'm not exactly sure what you're trying to do.)
The error that you're getting when you try to resume the iPod music suggests that your MPMusicPlayerController object resets its song queue when it is stopped by the AVAudio sounds, and that you'll have to set up the MP player again. "Title is null" definitely sounds like a dangling pointer or the like in the MP player.
It's not possible to play iPod audio in AVAudioPlayer. You need to convert the library Asset link from ipod, using *AVURLAsset to an mp3 or wav and save it to the documents library. IOS.5 currently has a bug in the conversion (AudioExportSession) from ipod to mp3 file, so it's NOT POSSIBLE. Sorry.
You need to resume iPod player after myPlayer finish playing.
-(void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[player play];
}