AVAudioRecorder in iOS 9 Not working - ios

I'm using AVAudioRecorder to record a audio file. The code I'm using works perfectly fine in iOS 8 and below but since the latest update of iOS 9 the recording seems to have stopped working.
I tried logging the properties of AVAudioRecorder object and even after calling the "record" function in AVAudioRecorder the isRecording is showing as NO and when the "stop" function is called i get the call back in the delegate
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag; with success flag as NO
audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err){
NSLog(#"audioSession: %# %ld %#", [err domain], (long)[err code], [[err userInfo] description]);
return;
}
[audioSession setActive:YES error:&err];
recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:16000.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];
[recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVEncoderBitRateKey];
[recordSetting setValue :[NSNumber numberWithInt:8] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
[recordSetting setValue :[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey];
recorderFilePath = [NSString stringWithFormat:#"%#/%#.m4a", DOCUMENTS_FOLDER,#"sample"];
NSLog(#"RecorderFilePath : %#",recorderFilePath);
NSURL *url = [NSURL fileURLWithPath:recorderFilePath];
err = nil;
recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];
//prepare to record
[recorder setDelegate:self];
[recorder prepareToRecord];
recorder.meteringEnabled = YES;
BOOL audioHWAvailable = audioSession.inputAvailable;
[recorder record];
Please advise if i'm doing something wrong in the code.

Try this:
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryRecord error:nil];
// Define the recorder setting
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:kAudioFormatMPEG4AAC], AVFormatIDKey, [NSNumber numberWithFloat:44100.0], AVSampleRateKey, [NSNumber numberWithInt: 2], AVNumberOfChannelsKey,nil];
// [recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
// Initiate and prepare the recorder
if (recorderHelium)
{
recorderHelium = nil;
}
recorderHelium = [[AVAudioRecorder alloc] initWithURL:[NSURL fileURLWithPath:recordedAudioFilePath] settings:recordSetting error:nil];
recorderHelium.delegate = self;
recorderHelium.meteringEnabled = YES;
[recorderHelium prepareToRecord];
[recorderHelium record];
And also import and include these files:
#import <AudioToolbox/AudioServices.h>
#include <AudioToolbox/AudioToolbox.h>

Related

AVAudioRecorder 256 Kbps recording in iOS

I wants to record an audio in iOS (AVAudioRecorder) below code working fine
_fileName = [NSString stringWithFormat:#"Record_%#.m4a",[DateAndTimeUtil stringFromDate:[NSDate date] withFormatterString:#"HH_mm_ss_dd_MM_yyyy"]];NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
_fileName,
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
audioRecorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:nil];
audioRecorder.delegate = self;
audioRecorder.meteringEnabled = YES;
[audioRecorder prepareToRecord];`
The problem is that the recorded file shows the bit rate as 44 Kbps but I want to record audio of an average bitrate of 256Kbps with a preference for AAC codec, but also compatible with the MP3 codec and the MP4 Audio codec.
Please help me out.
_fileName = [NSString stringWithFormat:#"Record_%#.mp4",[DateAndTimeUtil stringFromDate:[NSDate date] withFormatterString:#"HH_mm_ss_dd_MM_yyyy"]];
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
_fileName,
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];
[recordSetting setValue:[NSNumber numberWithInteger:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
[recordSetting setValue:[NSNumber numberWithInt:32] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue:[NSNumber numberWithInt:128000] forKey:AVEncoderBitRatePerChannelKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVEncoderBitDepthHintKey];
// Initiate and prepare the recorder
audioRecorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:nil];
audioRecorder.delegate = self;
audioRecorder.meteringEnabled = YES;
[audioRecorder prepareToRecord];
By using above code i reach towards a positive solution as it was able to record audio with bit rate info. The audio has almost 256Kbps bit rate.

AVRecorder files deleted each time app is rebuilt - iOS

I have an app which makes recordings using AVAudioRecorder. Its works and saves the audio files just fine. But when I rebuild the app, the audio files are deleted.
Is that normal? I would have thought so, but just wanted to make sure. I can't find anything about this online. Does Xcode delete any new files made by the app, each time a new build is made?
UPDATE
The code I am using to record the audio is as follows:
// Setup audio recorder to save file.
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession setActive:YES error:nil];
[audio_recorder setDelegate:self];
// Set the recording options such as quality.
NSMutableDictionary *settings = [NSMutableDictionary dictionary];
[settings setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[settings setValue:[NSNumber numberWithFloat:8000.0] forKey:AVSampleRateKey];
[settings setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
[settings setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[settings setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[settings setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
[settings setValue:[NSNumber numberWithInt:AVAudioQualityMax] forKey:AVEncoderAudioQualityKey];
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath_ = [searchPaths objectAtIndex:0];
NSString *pathToSave = [documentPath_ stringByAppendingPathComponent:currentDate];
// Construct the audio file save URL.
NSURL *url = [NSURL fileURLWithPath:pathToSave];
// Setup the audio recorder.
NSError *error;
audio_recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
if (error == nil) {
// Now begin the recording.
[audio_recorder prepareToRecord];
[audio_recorder record];
}
Thanks for your time, Dan.

Record the Background Playing song in iOS7

I am Trying to record the background Playing song using AVAudioRecorder. My code is as Below:
//Initialize audio session
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
//Override record to mix with other app audio, background audio not silenced on record
UInt32 allowMixing = true;
OSStatus propertySetError = 0;
propertySetError = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing);
NSLog(#"Mixing: %lx", propertySetError); // This should be 0 or there was an issue somewhere
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
[[AVAudioSession sharedInstance] setActive:YES error:nil];
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] initWithCapacity:0];
if (recordEncoding == ENC_PCM) {
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
[recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
} else {
NSNumber *formatObject;
switch (recordEncoding) {
case ENC_AAC:
formatObject = [NSNumber numberWithInt:kAudioFormatMPEG4AAC];
break;
case ENC_ALAC:
formatObject = [NSNumber numberWithInt:kAudioFormatAppleLossless];
break;
case ENC_IMA4:
formatObject = [NSNumber numberWithInt:kAudioFormatAppleIMA4];
break;
case ENC_ILBC:
formatObject = [NSNumber numberWithInt:kAudioFormatiLBC];
break;
case ENC_ULAW:
formatObject = [NSNumber numberWithInt:kAudioFormatULaw];
break;
default:
formatObject = [NSNumber numberWithInt:kAudioFormatAppleIMA4];
break;
}
[recordSetting setValue:formatObject forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
[recordSetting setValue:[NSNumber numberWithInt:12800] forKey:AVEncoderBitRateKey];
[recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *recDir = [paths objectAtIndex:0];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/recordTest.caf", recDir]];
NSError *error = nil;
audioRecorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&error];
if (!audioRecorder) {
NSLog(#"audioRecorder: %# %d %#", [error domain], [error code], [[error userInfo] description]);
return;
}
// audioRecorder.meteringEnabled = YES;
//
BOOL audioHWAvailable = audioSession.inputIsAvailable;
if (! audioHWAvailable) {
UIAlertView *cantRecordAlert =
[[UIAlertView alloc] initWithTitle: #"Warning"
message: #"Audio input hardware not available"
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[cantRecordAlert show];
[cantRecordAlert release];
return;
}
if ([audioRecorder prepareToRecord]) {
[audioRecorder record];
NSLog(#"recording");
} else {
// int errorCode = CFSwapInt32HostToBig ([error code]);
// NSLog(#"Error: %# [%4.4s])" , [error localizedDescription], (char*)&errorCode);
NSLog(#"recorder: %# %d %#", [error domain], [error code], [[error userInfo] description]);
}
but here the session Depreciated in ios7 warning occurs at:
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
can any one Help me to remove this warning without Changing the Functionality

AVAudioRecorder cannot save to file

I am trying to create a Simple AVAudioRecorder wrapper.
As far as I know, after [recorder stop], the audio file will save to the path automatically.
However in my class, it won't save to the path.
Console log:
2014-01-23 15:34:55.754 AudioRecorderDemo[4496:60b] contentURL: file:///var/mobile/Applications/C20F5A5A-14A9-45D4-80A3-999976AC4055/Documents/MyAudio-someDemo.m4a
2014-01-23 15:34:55.756 AudioRecorderDemo[4496:60b] fileExist? : no
Thanks for helping.
The class file on GitHub:
AudioRecorder.h
AudioRecorder.m
// Code when start:
-(void)prepare
{
NSError *error;
// Setup audio session
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
if (error)
{
NSLog(#"Error in AVAudioSession: %#", error.description);
return;
}
// 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
NSURL *contentURL = [STLAudioRecorder contentsOfURLFromUniqueID:self.uniqueID fileNameFormat:self.fileNameFormat];
self.recorder = [[AVAudioRecorder alloc] initWithURL:contentURL settings:recordSetting error:&error];
if (error)
{
NSLog(#"Error in AVAudioRecorder: %#", error.description);
return;
}
self.recorder.delegate = self;
self.recorder.meteringEnabled = YES;
[self.recorder prepareToRecord];
}
-(void)startRecording
{
if (!self.recorder) [self prepare];
if (!self.recorder.isRecording)
{
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
[self.recorder record];
NSLog(#"startRecording, url: %#", self.recorder.url.absoluteString);
}
}
// Code when stop:
-(void)stopRecording
{
if (self.recorder && self.recorder.isRecording)
{
NSError *error;
[self.recorder stop];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setActive:NO error:&error];
if (error) NSLog(#"Error in stopRecording: %#", error.description);
}
else
{
NSLog(#"stopRecording: !(self.recorder && self.recorder.isRecording)");
}
}
Try this one,
-(void) initAudioSession {
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];
[audioSession setActive:YES error: &error];
}
-(void) recordStart {
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
tempFilePath = [NSURL fileURLWithPath:[docsDir stringByAppendingPathComponent:[NSString stringWithFormat: #"%#.%#",audioFileName, #"caf"]]];
NSMutableDictionary* recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
stringByAppendingPathComponent: [NSString stringWithFormat: #"%#.%#",audioFileName, #"caf"]]];
recorder = [[ AVAudioRecorder alloc] initWithURL:tempFilePath settings:recordSetting error:&error];
[recorder setDelegate:self];
[recorder prepareToRecord];
[recorder record];
}
-(void) stopRecording{
[recorder stop];
}
-(void) playRecord{
avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:tempFilePath error:&error];
[avPlayer prepareToPlay];
[avPlayer play];
}

Recorder delegate method not called

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];
[recorder prepareToRecord];
recorder.meteringEnabled = YES;
//Start the actual Recording
[recorder record];
[recorder updateMeters];
level = [recorder peakPowerForChannel:0];
NSLog(#"%f",level);
i have used this code in viewDidload() method to record a sound sound get in level.
i want to call the deleget method when device get the sound.
-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{
NSLog(#"Level is %f",level);
}
this method not called.
i am setting recorder delegate in .h file but not called this method why this is happening.
help me to do this.
Thanks in advance.
Are you actually storing the AVAudioRecorder instance somewhere? If you are not then it is likely deallocated by the time the above code finishes.
Try this
-(void)initialiceAudio{
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemo.m4a",
nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
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:5000.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;
[player setVolume: 1.0];
[recorder prepareToRecord];
}
-(IBAction)record:(id)sender {
if (!recorder.recording) {
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
recordBtn.selected=YES;
tabBtn.selected = YES;
tabBtn.userInteractionEnabled = NO;
// Start recording
[recorder record];
} else {
}
}
-(void) audioRecorderDidFinishRecording:(AVAudioRecorder *)avrecorder successfully:(BOOL)flag{
recorder = nil;
player = nil;
spinnerView = nil;
UploadAudioViewController *upload = [[UploadAudioViewController alloc]initWithNibName:#"UploadAudioViewController" bundle:nil];
NSLog(#"recorder url----%#",recorderurl);
upload.audioURL = recorderurl;
[self.navigationController pushViewController:upload animated:YES];
}
and make sure - you used AVAudioRecorderDelegate and AVAudioPlayerDelegate

Resources