AVAudioSession use AVAudioSessionPortOverrideNone and AVAudioSessionModeVideoRecording - iphone

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

Related

AVAudioPlayer plays on silent mode when MPMoviePlayer plays

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

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.

iPhone SdK: AVPlayer will not play a composition after adding a audio track

After adding an audio track (recorded with AVAudioRecorder) to a composition AVPlayer will not play it. AVPlayer.status = 1 and AVPlayer.error = null.
I have looked at the WWDC10 AVEdit demo code and it's pretty much similar. Could it be an audio format incompatibility?
the original composition allready contains a video and audio track from a video asset.
after removing the newly added audio track the player still does not play
after removing the original audio track the player will play.
I'm also finding it hard to get debug information that would point me to the problem. If anyone has a suggestion it would be greatly appreciated.
Here is my code for adding the audio track
any help is most welcome
Jean-Pierre
-(void)editAudioViewController:(EditAudioViewController *)editAudioViewController didEditAudio:(NSURL *)url
{
[self dismissModalViewControllerAnimated:TRUE];
BOOL result;
NSError * error = nil;
if (url)
{
AVURLAsset * asset = [AVURLAsset URLAssetWithURL:url options:nil] ;
CMTimeRange audioTimeRange = CMTimeRangeMake(kCMTimeZero , asset.duration);
if (CMTIME_COMPARE_INLINE(CMTimeRangeGetEnd(audioTimeRange), >, [composition duration]))
audioTimeRange.duration = CMTimeSubtract([composition duration], audioTimeRange.start);
AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *audioTrack = [asset compatibleTrackForCompositionTrack:compositionAudioTrack];
result = [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioTimeRange.duration) ofTrack:audioTrack atTime:audioTimeRange.start error:&error];
if (!result)
{
NSLog(#"%#", [error description]);
}
[mp replaceCurrentItemWithPlayerItem:[AVPlayerItem playerItemWithAsset:composition]];
[mp seekToTime:kCMTimeZero];
}
}
I had two separate sessions in my audio recorder code one for recording and one for playback.
I switched to a single record/play session and this somehow fixed the problem:
audioSession = [AVAudioSession sharedInstance];
if (!audioSession.inputIsAvailable)
{
NSLog(#"No input available");
}
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
NSError * error = nil;
[audioSession setActive:TRUE error:&error];
if (error)
{
NSLog(#"%#", [error description]);
}

iphone, how to play sound even in silent or mute mode?

as topic... is it possible ?
Thanks
again, I have attached the code as follows, please check which step is wrong .thanks.
//#step
AudioSessionInitialize (NULL, NULL, NULL, NULL);
AudioSessionSetActive(true);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
OSStatus error = AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof(sessionCategory),&sessionCategory);
if (error)
printf("ERROR AudioSessionSetProperty ! %d\n", error);
//#step
NSString* filePath = #"AlarmClockBell.caf";
[Util restoreResourceFile:filePath];
filePath =[Util getFileFullPathFromSysDoc:filePath];
NSURL *soundFileURL = [NSURL fileURLWithPath:filePath];
NSError* error ;
AVAudioPlayer * audioPalyer = [[AVAudioPlayer alloc] initWithContentsOfURL: soundFileURL error: &error];
if (nil == audioPalyer)
{
AppTrace3(self, #"Faild to play", soundFileURL, error);
return FALSE;
}
[audioPalyer prepareToPlay];
[audioPalyer setVolume: 5 ];
[audioPalyer setDelegate: self];
audioPalyer.numberOfLoops = 10;
[audioPalyer play];
thanks...
If you look in the docs under Audio Session Categories, you'll find a number of modes that you can set to tell the system how your app plans to use audio. The default is AVAudioSessionCategorySoloAmbient which tracks the ring/silent switch and the screen lock.
To have your app ignore the ring/silent switch settings, you could try changing the category:
#import <AudioToolbox/AudioToolbox.h>
AudioSessionInitialize (NULL, NULL, NULL, NULL);
AudioSessionSetActive(true);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory,
sizeof(sessionCategory),&sessionCategory);
If you want to allow iPod audio to continue playing in the background, you'll also want to check kAudioSessionProperty_OverrideCategoryMixWithOthers.
As of iOS 6, there is an alternative method that's more compact than Ramin's answer.
#import <AVFoundation/AVFoundation.h>
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
error:nil];
To allow background audio from other apps to continue playing, add the AVAudioSessionCategoryOptionMixWithOthers option:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionMixWithOthers
error:nil];
There's further details in Apple's AVAudioSession Class Reference.
It must be, there's been a couple games I've had which (even when its in mute mode) will play sound. Unfortunately this was discovered whilst attempting to play games covertly in class.
As to how to actually do it, I really don't have any idea.