Recording Audio And Video at same Time in ios - ios

I have to start recorder first which will record the audio during that i need to record video from camera as well.
Code for audio Recording
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:AVAudioSessionCategoryPlayback 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:nil];
recorder.delegate = self;
recorder.meteringEnabled = YES;
[recorder prepareToRecord];
[recorder record];
code for video recording
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
[picker dismissViewControllerAnimated:YES completion:^
{
if(_isVideo)
{
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
_imageData = [NSData dataWithContentsOfURL:videoURL];
[picker dismissViewControllerAnimated:YES completion:nil];
[ self saveVideo];
}
}];
}
-(void)saveVideo
{
if(_isVideo)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSDateFormatter *formatter;
NSString *dateString;
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"dd-MM-yyyy HH:mm:ss"];
dateString = [formatter stringFromDate:[NSDate date]];
NSString *path = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"/%#/%#/%#.mp4",_folderName,#"Videos",dateString]];
NSError * error = nil;
NSString *pathVideoThumb = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"/%#/%#/%#",_folderName,#"VideoThumb",dateString]];
[_imageData writeToFile:path options:NSDataWritingAtomic error:&error];
if (error != nil)
{
NSLog(#"Error: %#", error);
return;
}
[self generateThumbImage:pathVideoThumb dataPath:path];
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
_isVideo=NO;
videoCount++;
[videoLabel setText:[NSString stringWithFormat:#"%d %#",videoCount,#"VIDEOS"]];
[videoView setBackgroundColor:[UIColor clearColor]];
});
});
}
}
But when i play the recorded Video it does not contain any sound. The recorded audio is working fine ,I understand that the problem is with the audio session ,Please guide me how should i use audio session to handle this.
Thanks

Related

Recording voice is not working

In my app, I want to record voice and send via email. I am recording voice and once I click the attach button, it throws me the following error. It seems voice is not recorded.
Here is my code snippet
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemo.m4a",
nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
NSLog(#"%#",outputFileURL);
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];
}
- (IBAction)microButton:(id)sender {
if(counter%2==0)
{
if (!recorder.recording) {
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
// Start recording
[recorder record];
}
counter=counter+1;
}
else{
[recorder stop];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setActive:NO error:nil];
counter=counter+1;
}
}
- (void) audioRecorderDidFinishRecording:(AVAudioRecorder *)avrecorder successfully:(BOOL)flag{
NSLog(#"audioPlayerDidFinishPlaying");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: #"Done" message: #"Voice recorded successfully!"delegate: nil cancelButtonTitle:#"OK"otherButtonTitles:nil];
[alert show];
}
- (IBAction)attachBtn:(id)sender {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *URL = [documentsDirectory stringByAppendingPathComponent:#"MyAudioMemo.m4a"];
NSString* someText = #"Voice";
NSURL *urlToShare = [NSURL fileURLWithPath:URL isDirectory:NO];
NSArray* dataToShare = #[someText, urlToShare];
UIActivityViewController* activityViewController =
[[UIActivityViewController alloc] initWithActivityItems:dataToShare
applicationActivities:nil];
activityViewController.excludedActivityTypes = #[UIActivityTypePrint,UIActivityTypeCopyToPasteboard,UIActivityTypeAssignToContact];
activityViewController.popoverPresentationController.barButtonItem = (UIBarButtonItem *)sender;
activityViewController.completionHandler = ^(NSString *activityType, BOOL completed) {
//if (completed) {
[self dismissViewControllerAnimated:YES completion:nil];
//}
};
[self presentViewController:activityViewController animated:YES completion:nil];
}
Assuming this is on an iPad, when you present the UIActivityViewController, it will be shown in a popover. You need to do what the message states, set either the sourceView or the barButtonItem.
activityViewController.popoverPresentationController.barButtonItem = sender;
That assumes sender is a UIBarButtonItem. If it's a UIButton or other view, use:
activityViewController.popoverPresentationController.sourceView = sender;

iPhone - Problems Saving Audio After Recording

I a button that records audio when isNotRecording is false and plays audio when isNotRecording is true. Here is my code in the viewDidLoad function:
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];
Here is my code to play the sound or record:
if (isNotRecording==NO){
if (player.playing) {
[player stop];
}
if (!recorder.recording) {
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
// Start recording
[recorder record];
}
}
else{
if (!recorder.recording){
player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
[player setDelegate:self];
[player play];
}
}
And here is my code to stop the playing/recording:
[recorder stop];
[player stop];
Now, everything works almost perfectly (i.e. I can record and play sounds fine). However, there are two issues. The major one is that after I close out the app and try to play the sound, it does not have a sound to play. I want it to play the previous recording. That is my main issue, but it would also be great if I could reduce the lag from when I press the button and the sound plays. Sometimes, if I press the button and release it very fast, no sound plays at all. Any suggestions are greatly appreciated. However, again, the main issue I need fixed is that the recording doesn't save after I close out the app.
I think what's happening is that when you initialize your AVAudioRecorder when the view loads then that will delete any existing file at the target location, irrespective of whether you start recording at that stage. So I think that's how the file is going missing.
Simplest may be just not to call [recorder prepareToRecord]; when you do, as I suspect that's when your recording is getting deleted.
Or you might want to use a temporary file while recording and move it to the final location when you're notified that the recording is finished, in order to avoid that issue. Code is something like:
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemoTemp.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];
if (isNotRecording==NO){
if (player.playing) {
[player stop];
}
if (!recorder.recording) {
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
// Start recording
[recorder record];
}
}
else{
if (!recorder.recording){
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemo.m4a",
nil];
NSURL *inputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:inputFileURL error:nil];
[player setDelegate:self];
[player play];
}
}
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder
                            successfully:(BOOL)flag
{
if (successfully) {
// Copy temp file used during recording to replace that used when playing
//
pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemo.m4a",
nil];
NSURL *targetFileURL = [NSURL fileURLWithPathComponents:pathComponents];
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtURL:targetFileURL error:&error];
error = nil;
[[NSFileManager defaultManager] copyItemAtURL:recorder.url toURL:targetFileURL error:&error];
}
}

Audio processing in iOS to get volume and pitch

I'm attempting to create a realtime audio analyzer on iOS7. What I'm looking to get is volume and pitch from the native microphone on an iPod Touch Gen 5, and write to a CSV along with a timestamp. I'd like to break it up into 7 channels, and sample at 8Hz. I've looked at a bunch of documentation and code samples, but can't get anything to work.
I'm trying to start something simple now from scratch, but it seems to me that there is nothing outlining how I can achieve what I mentioned above.
Most recently I've tried AVAudioSessionCategoryAudioProcessing hoping to be able to use it for signal processing, but the Audio Session docs suggest that only automated signal processing can be done...and only in voice or video chat modes.
- (void)analyzeAudio
{
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
audioUnit = (AudioUnit*)malloc(sizeof(AudioUnit));
NSError *activationError = nil;
BOOL success = [[AVAudioSession sharedInstance] setActive: YES error: &activationError];
if (!success)
{
NSLog(#"AudioSession could not init");
}
[audioSession setCategory:AVAudioSessionCategoryAudioProcessing error:nil];
[audioSession setActive:YES error:nil];
}
Is there a simple way with Audio Session to get what I'm looking for?
Found out that I can use the AVAudioRecorder method updateMeters on a timer to get the peakPowerForChannel: value at some interval.
- (void)recordAudio
{
_audioSession = [AVAudioSession sharedInstance];
NSError *error;
[_audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
[_audioSession setActive:YES error:&error];
NSMutableDictionary *settings = [NSMutableDictionary dictionary];
[settings setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[settings setValue:[NSNumber numberWithFloat:8000.0] forKey:AVSampleRateKey];
[settings setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
[settings setValue:[NSNumber numberWithFloat:16000] forKey:AVEncoderBitRateKey];
[settings setValue:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityForVBRKey];
NSArray *dirPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [dirPath objectAtIndex:0];
long currentTime = [[NSDate date] timeIntervalSince1970];
NSString *filePath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:#"audio_%ld.aac", currentTime]];
NSURL *audioFileURL = [NSURL fileURLWithPath:filePath];
_audioRecorder = [[AVAudioRecorder alloc] initWithURL:audioFileURL settings:settings error:&error];
if (error)
{
NSLog(#"audio record error: %#", [error localizedDescription]);
} else {
[_audioRecorder prepareToRecord];
_audioRecorder.meteringEnabled = YES;
[_audioRecorder record];
[self addTextToLog:#"Recording Audio"];
self.audioTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:#selector(updateAudioMeters) userInfo:nil repeats:YES];
}
}
- (void)updateAudioMeters
{
[_audioRecorder updateMeters];
NSLog(#"pkPwr: %f", [_audioRecorder peakPowerForChannel:0]);
}

iOS: Audio recording setup fails in simulator, but not on my device?

I am recording audio in my app.
The app runs in my iPhone 5C with iOS 7 just fine, but it fails in the simulator (iPhone Retina 3,5-inch / 4-inch/ 4-inch 64 bit)
Here is the code to setup audio:
-(void)setupAudio{
_audioMessageLabel.text = #"...Bereit für Aufnahme...";
[_stopButton setEnabled:NO];
[_playButton setEnabled:NO];
// Set the audio file
NSString *guid = [[NSUUID new] UUIDString];
_dateiName = [NSString stringWithFormat:#"audio-notiz-%#.m4a", guid];
NSLog(#"dateiName: %#", _dateiName);
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
_dateiName,
nil];
_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
NSError *error = nil;
recorder = [[AVAudioRecorder alloc] initWithURL:_outputFileURL settings:recordSetting error:&error];
if (error)
{
NSLog(#"error: %#", [error localizedDescription]);
} else {
recorder.delegate = self;
recorder.meteringEnabled = YES;
[recorder prepareToRecord];
}
}
It fails in the last line [recorder prepareToRecord] with (lldb) in the console
I think the issue could be, that the ios simulator doesn't support microphone:
Is it possible to record actual sound on the simulator using mic
https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/iOS_Simulator_Guide/TestingontheiOSSimulator/TestingontheiOSSimulator.html#//apple_ref/doc/uid/TP40012848-CH4-SW1

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

Resources