ios - Recording Audio After VIdeo play - ios

I can't record audio after playing a video, if I record before playing the video no problem but then I have to close the application to record again.
I can't record audio after playing a video, if I record before playing the video no problem but then I have to close the application to record again.
Record Audio:
- (IBAction)recordAudio:(id)sender {
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
NSString *soundFilePath = [docsDir
stringByAppendingPathComponent:#"sound.caf"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSDictionary *recordSettings = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:AVAudioQualityMin],
AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16],
AVEncoderBitRateKey,
[NSNumber numberWithInt: 2],
AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],
AVSampleRateKey,
nil];
NSError *error = nil;
_audioRecorder = [[AVAudioRecorder alloc]
initWithURL:soundFileURL
settings:recordSettings
error:&error];
if (error)
{
NSLog(#"error: %#", [error localizedDescription]);
} else {
[_audioRecorder prepareToRecord];
}
if (!_audioRecorder.recording)
{
_playButton.enabled = NO;
_stopButton.enabled = YES;
[_audioRecorder record];
}
}

Do this before recording the Audio:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];

Related

How to record audio in objective c for iphone app in .amr format?

I have used following code to record audio. It works perfectly for .caf format.
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString *soundFilePath = [docsDir
stringByAppendingPathComponent:#"sound.caf"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSDictionary *recordSettings = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:AVAudioQualityMin],
AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16],
AVEncoderBitRateKey,
[NSNumber numberWithInt: 2],
AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],
AVSampleRateKey,
nil];
NSError *error = nil;
audioRecorder = [[AVAudioRecorder alloc]
initWithURL:soundFileURL
settings:recordSettings
error:&error];
But for .amr if i change extension to .amr as per below it is not working for me to record audio.
NSString *soundFilePath = [docsDir
stringByAppendingPathComponent:#"sound.amr"];
can any body guide me how to record and save audio in .amr format?
try below Code, might be useful to you..
AppDelegate *del = (AppDelegate*)[[UIApplication sharedApplication]delegate];
//set path & name for Recording Audio
NSString *dataPath=[del.path_Folder_Document copy];
NSString *filePath = [NSString stringWithFormat:#"%#/Images_Audio/%#.3gp", dataPath,[ARR_Img_File_Name_Moment objectAtIndex:pos]];
NSLog(#"Audio File Path =%#",filePath);
NSURL *tmpFileUrl = [NSURL fileURLWithPath:filePath];
//set Record Setting
NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
[NSNumber numberWithFloat:8000.0], AVSampleRateKey,
[NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
nil];
NSError *error = nil;
//Prepare Recorder to Start Recording Audio
recorder = [[AVAudioRecorder alloc] initWithURL:tmpFileUrl settings:recordSettings error:&error];
recorder.delegate = self;
[recorder prepareToRecord];
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryRecord error:nil];
[session setActive:YES error:nil];
//Start Recording Audio ..
if ([[NSFileManager defaultManager] isWritableFileAtPath:filePath]) {
NSLog(#"Writable Pathforimage_Audio 1st>> %#", filePath);
}else
{
NSLog(#"Not Writable");
}
[recorder record];
NSLog(#"its recording audio...");

What is the best microphone recording settings for AVAudio?

So I have the current code:
- (void)viewDidLoad
{
[super viewDidLoad];
//for recording audio
_stopButton.enabled = NO;
_playButton.hidden = true;
NSArray *dirPaths;
NSString *docsDir;
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
NSString *soundFilePath = [docsDir
stringByAppendingPathComponent:#"recording.caf"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatMPEG4AAC], AVFormatIDKey,
[NSNumber numberWithFloat:44100.0], AVSampleRateKey,
[NSNumber numberWithInt:1], AVNumberOfChannelsKey,
[NSNumber numberWithInt:AVAudioQualityHigh], AVSampleRateConverterAudioQualityKey,
[NSNumber numberWithInt:128000], AVEncoderBitRateKey,
[NSNumber numberWithInt:16], AVEncoderBitDepthHintKey,
nil];
NSError *error = nil;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
error:nil];
_audioRecorder = [[AVAudioRecorder alloc]
initWithURL:soundFileURL
settings:recordSettings
error:&error];
if (error)
{
NSLog(#"error: %#", [error localizedDescription]);
} else {
[_audioRecorder prepareToRecord];
}
//----------------------------
//end
}
And the player:
- (IBAction)playAudio:(id)sender {
[_playButton setEnabled:NO];
if (!_audioRecorder.recording)
{
_stopButton.enabled = YES;
_recordButton.enabled = NO;
NSError *error;
_audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:_audioRecorder.url
error:&error];
_audioPlayer.volume = 5;
_audioPlayer.delegate = self;
if (error)
NSLog(#"Error: %#",
[error localizedDescription]);
else
[_audioPlayer play];
}else{
NSLog(#"errormax");
}
}
I have the _audioPlayer.volume at 5 because any lower you can barely here it. But it peeks and sounds extremely distorted at that volume. Why can it not sound like "Voice Memos" where it plays it back at a reasonable volume without it distorting?
What are the best quality settings for this?
I personaly prefer PCM encoding, I've had better quality using it.
try:
NSDictionary *recordSettings =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
[NSNumber numberWithFloat:44100.0], AVSampleRateKey,
[NSNumber numberWithInt:2], AVNumberOfChannelsKey,
[NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
[NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
[NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey,
nil];
or to make it more readable:
NSDictionary * recordSetting;
recordSetting = [[NSMutableDictionary alloc] init];
[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];
Adjust your function like this:
- (IBAction)playAudio:(id)sender {
[_playButton setEnabled:NO];
if (!_audioRecorder.recording)
{
_stopButton.enabled = YES;
_recordButton.enabled = NO;
//force the session to play to come out of speakers!
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
NSError *error;
_audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:_audioRecorder.url
error:&error];
_audioPlayer.delegate = self;
[_audioPlayer prepareToPlay];
if (error)
NSLog(#"Error: %#",
[error localizedDescription]);
else
[_audioPlayer play];
}else{
NSLog(#"errormax");
}
}
It's because of audio session category "AVAudioSessionCategoryPlayAndRecord". It always play audio in receiver unless you explicitly change the overrideOutputAudioPort. You may have to add listener for AVAudioSessionRouteChangeNotification to change the category based on your out put. Anyway why this headache, just use AVAudioSessionCategoryRecord before you start recording and AVAudioSessionCategoryPlayback before you start player.
//Player
newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
NSError *setCategoryError = nil;
[audioSession setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];
//Recorder
newRecorder = [[AVAudioRecorder alloc]initWithURL:fileURL settings:recordSettings error:&error];
NSError *setCategoryError = nil;
[audioSession setCategory: AVAudioSessionCategoryRecord error: &setCategoryError];

Can not play .m4a file in safari that is recorded in iOS application

I am having application in which i need to record audio and than upload it on the server and mail the link of the file to the user.
Now when I try to open the mail in mac or windows it works fine and i can hear the audio. But when i try to open the link in iPhone or iPad it won't play in it.
While i had a demo application made for the project and when i try the same thing, it worked.
Please help me out.
Thank you in advance.
NSArray *dirPaths;
NSString *docsDir;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
if ([txt_RecordingName.text isEqualToString:#"Untitled"])
{
strFileName = [NSString stringWithFormat:#"Recording %d.m4a",[appDelegate.db getMaxId]];
soundFilePath = [docsDir stringByAppendingPathComponent:strFileName];
}
else
{
strFileName = [NSString stringWithFormat:#"%#.m4a",txt_RecordingName.text];
soundFilePath = [docsDir stringByAppendingPathComponent:strFileName];
}
NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
[NSNumber numberWithFloat:16000.0], AVSampleRateKey,
[NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
nil];
newURL = [NSURL fileURLWithPath:soundFilePath];
audioRecorder = [[AVAudioRecorder alloc]
initWithURL:newURL
settings:recordSettings
error:nil];
audioRecorder.delegate = self;
[audioRecorder prepareToRecord];
if (!audioRecorder.recording)
{
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryRecord error:nil];
[session setActive:YES error:nil];
[audioRecorder record];
counter = 0;
[btnPauseRecord setEnabled:TRUE];
}
recordingTime = -1;
[self showRecordingTime];
[lbl_Recording setHidden:NO];
[lbl_PressToStop setText:#"Press to pause"];
[lbl_PressToStop setHidden:NO];
[lbl_ListenToRecording setHidden:YES];
[lbl_RecordingAgain setHidden:YES];
[btn_ListenToRecording setHidden:YES];
[btn_RecordAgain setHidden:YES];
txt_RecordingName.text = strFileName;
}
else
{
[audioRecorder stop];
audioRecorder = nil;
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:NO error:nil];
isRecording = FALSE;
[btnPauseRecord setEnabled:FALSE];
[txt_RecordingName setEnabled:TRUE];
isPaused = TRUE;
[lbl_Recording setHidden:YES];
[lbl_Save setHidden:NO];
[btn_Save setHidden:NO];
[lbl_ListenToRecording setHidden:NO];
lbl_ListenToRecording.text = #"Listen to Recording";
[lbl_RecordingAgain setHidden:NO];
[btn_ListenToRecording setHidden:NO];
[btn_RecordAgain setHidden:NO];
lbl_PressToStop.text = #"Press to resume";
[lblPauseRecord setHidden:YES];
[btnPauseRecord setHidden:YES];
}

iOS, no recording sound in my iPad, in the simulator works fine

Hi I have a very strange problem in the simulator works perfect but when I charge the app to the iPad it does not work. Any idea?
Here I create all the variables to make it work.
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *dirPaths;
NSString *docsDir;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString *soundFilePath = [docsDir stringByAppendingPathComponent:#"sound.caf"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:AVAudioQualityMin],
AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16],
AVEncoderBitRateKey,
[NSNumber numberWithInt: 2],
AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],
AVSampleRateKey,
nil];
NSError *error = nil;
audioRecorder = [[AVAudioRecorder alloc] initWithURL:soundFileURL
settings:recordSettings
error:&error];
if (error)
{
NSLog(#"error: %#", [error localizedDescription]);
} else {
[audioRecorder prepareToRecord];
}
}
I have some buttons for record, play and stop. So these are the codes for all of them.
-(void) recordAudio{
if (!audioRecorder.recording){
recordButton.enabled = NO;
playButton.enabled = NO;
saveButton.enabled = NO;
stopButton.enabled = YES;
[audioRecorder record];
}
}
-(void)stop{
recordButton.enabled = YES;
playButton.enabled = YES;
saveButton.enabled = YES;
stopButton.enabled = NO;
if (audioRecorder.recording){
[audioRecorder stop];
}
else if (audioPlayer.playing){
[audioPlayer stop];
}
}
-(void) playAudio{
if (!audioRecorder.recording){
recordButton.enabled = NO;
stopButton.enabled = YES;
saveButton.enabled = NO;
if (audioPlayer)
audioPlayer=nil;
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:audioRecorder.url
error:&error];
audioPlayer.delegate = self;
if (error)
NSLog(#"Error: %#", [error localizedDescription]);
else
[audioPlayer play];
}
}
finally I found a solution. To my previous code I add this lines inside the ViewdidLoad.
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];
[audioSession setActive:YES error: &error];
and for the settings I added this:
[NSNumber numberWithInt:kAudioFormatAppleIMA4], AVFormatIDKey
I copy the code from http://www.iphoneam.com/blog/index.php?title=using-the-iphone-to-record-audio-a-guide&more=1&c=1&tb=1&pb=1 and the idea of using AVAudioSession came from How to record and play sound in iPhone app?
If you need the complete code is this one.
- (void)viewDidLoad {
[super viewDidLoad];
NSError *error = nil;
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];
[audioSession setActive:YES error: &error];
playButton.enabled = NO;
stopButton.enabled = NO;
saveButton.enabled = NO;
NSArray *dirPaths;
NSString *docsDir;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
docsDir = [HSAudioController pathToDocumentsFolder];
NSString *soundFilePath = [docsDir stringByAppendingPathComponent:#"sound.caf"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatAppleIMA4], AVFormatIDKey,
[NSNumber numberWithInt:AVAudioQualityMin], AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16], AVEncoderBitRateKey,
[NSNumber numberWithInt: 2], AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0], AVSampleRateKey,
nil];
audioRecorder = [[AVAudioRecorder alloc] initWithURL:soundFileURL
settings:recordSettings
error:&error];
NSLog(#"%#",audioRecorder.url);
if (error)
{
NSLog(#"error: %#", [error localizedDescription]);
} else {
[audioRecorder prepareToRecord];
}
}

iOS - Playback of recorded audio fails with OSStatus error -43 (file not found)

I set up an AVAudioRecorder instance the following way when my view loads:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
audioSession.delegate = self;
[audioSession setActive:YES error:nil];
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
NSString *tempDir = NSTemporaryDirectory();
NSString *soundFilePath = [tempDir stringByAppendingPathComponent:#"sound.m4a"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSLog(#"%#", soundFileURL);
NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatMPEG4AAC], AVFormatIDKey,
[NSNumber numberWithInt:AVAudioQualityMin], AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16], AVEncoderBitRateKey,
[NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
[NSNumber numberWithFloat:8000.0], AVSampleRateKey,
[NSNumber numberWithInt:8], AVLinearPCMBitDepthKey,
nil];
NSError *error = nil;
self.recorder = [[AVAudioRecorder alloc]
initWithURL:soundFileURL
settings:recordSettings
error:&error];
self.recorder.delegate = self;
if (error) {
NSLog(#"error: %#", [error localizedDescription]);
} else {
[self.recorder prepareToRecord];
}
Then, when the user presses the record button I do:
- (IBAction)record:(id)sender {
if (!self.isRecording) {
self.isRecording = YES;
[self.recorder record];
self.recordButton.enabled = NO;
}
}
Then to stop the recording/playback:
- (IBAction)stop:(id)sender {
if (self.isRecording) {
[self.recorder stop];
self.recordButton.enabled = YES;
self.isRecording = NO;
}
if (self.isPlaying) {
[self.player stop];
self.isPlaying = NO;
self.playButton.enabled = YES;
}
}
After, I want to be able to playback what was recorded, so I do the following:
- (IBAction)play:(id)sender {
NSError *error = nil;
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.recorder.url error:&error];
self.player.delegate = self;
if (error) {
NSLog(#"%#", error.localizedDescription);
} else {
self.isPlaying = YES;
[self.player play];
self.playButton.enabled = NO;
}
}
But when I go and play the file is get OSStatus error -43 file not found.
This is all running on the device btw, on the simulator y an error when trying to instantiate the recorder or player, and from I've seen it's a simulator issue.
EDIT 1: I solved the OSStatus error -43 part it has something to do with the encoding format, I commented out the format and it recorded and played the file properly, but I need to record in a compressed format. Does anyone know the settings for this?
EDIT 2: I managed to find settings that worked for compressed AAC audio. A 2min audio file comes out to 256KB, I updated my code to reflect the current state. Thanks to all of those who answered for your help.
I'm gonna take a wild stab at this since no-one else has answered (EDIT: now there is) (I don't have much experience with Audio in iOS) but...
Try changing
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:nil];
to
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
AVEncoderBitRateKey is not working with AAC format encoding.So try this code.
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSLog(#"%#", soundFileURL);
NSDictionary *recordSettings = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatMPEG4AAC],
AVFormatIDKey,
[NSNumber numberWithInt: AVAudioQualityMax],
AVEncoderAudioQualityKey,
[NSNumber numberWithInt: 1],
AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],
AVSampleRateKey,
nil];
NSError *error = nil;
self.recorder = [[AVAudioRecorder alloc]
initWithURL:soundFileURL
settings:recordSettings
error:&error];
self.recorder.delegate = self;
if (error) {
NSLog(#"error: %#", [error localizedDescription]);
NSLog(#"error: %#", [error description]);
} else {
[self.recorder prepareToRecord];
}
EDIT 1:
OSStatus error -43 file not found is not a simulator issue. It's an error log, which shows your recording settings are not correct and required encoding format is not supported for the settings you have selected.
When you get this error, you file will get created in the format as you given. But It will not initialize your audio recorder to start recording. If you have any doubt, then select the same settings, which you had in first question and record and try to play that. It won't record and play because of unsupported setting.
So for a compressed encoding format, you can use a settings as I given above in my code. You can have .aac format for this settings. It will take 164KB per 10 seconds to record in aac format. For rest of the formats you have to try and figure out.
You may need to set the AVAudioSession category back to playback mode:
NSError *_error = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&_error];
if (_error) {
// handle error here
}
This should also avoid the problem where the audio will not play with the mute switch toggled on.
Okay try this:
Make NSURL *soundFileURL global for your class so you can access it anywhere in your class and set in the same way as you are now (except it would be soundFileURL = [NSURL fileURLWithPath:soundFilePath]; instead of NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];.
Then change this
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.recorder.url error:&error];
to this
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];

Resources