Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Record audio file and save locally on iPhone

I have been looking all over the place for an answer to this but cant find exactly what I need. Basically in my app I am recording voice to an audio file (like the iOS Voice Memo app) and then would like to save it to the local document dir. From some reason the URL that I am being given with the recorded file expires next time I launch the app. Besides, even if it did not, if I record twice, the second file URL gets the same URL as the first one, so I am losing the first file.

Recording this way:

    [audioRecorder record];

Where: AVAudioRecorder *audioRecorder;

Playing is ok:

        [audioPlayer play];

Where: AVAudioPlayer *audioPlayer;

What is the best way to record voice memo and save it to the local disk on the iPhone?

Thanks.

Update:

I tried to use this code:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
BOOL status = [data writeToFile:filePath atomically:YES];

With the data being the data of my AVAudioPlayer NSData property, but BOOL gets 0, and no idea why.

like image 611
moshikafya Avatar asked Aug 27 '12 02:08

moshikafya


People also ask

How do I save an audio file on my iPhone?

To keep a single audio message, tap "Keep" underneath an audio message to prevent it from being automatically removed. If your device is using a version previous to iOS12, you also have the option to save audio messages to the Voice Memos app. To do this, tap and hold an audio message, then choose "Save".

Where do sound recordings save on iPhone?

If you have an iOS version earlier than iOS 12, your saved audio files will be in the Voice Memos app. To access them: Open 'Messages. '

What file type does iPhone record audio?

The MPEG-4 codec used to record and play back audio files in the iPhone's Voice Memo app is compressed using the Advanced Audio Coding (AAC) codec or the Apple Lossless Audio Codec (ALAC). Because the Voice Memo app only records audio data, the ". M4A" file extension is used, rather than the ". MP4" file extension.


1 Answers

Return current date and time which we are use as sound file name.

Objective-c

- (NSString *) dateString
{
// return a formatted string for a file name
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"ddMMMYY_hhmmssa";
return [[formatter stringFromDate:[NSDate date]] stringByAppendingString:@".aif"];
}

Swift 4

func dateString() -> String {
  let formatter = DateFormatter()
  formatter.dateFormat = "ddMMMYY_hhmmssa"
  let fileName = formatter.string(from: Date())
  return "\(fileName).aif"
}

Setup Audio Session

Objective-c

- (BOOL) startAudioSession
{
// Prepare the audio session
NSError *error;
AVAudioSession *session = [AVAudioSession sharedInstance];

if (![session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error])
{
    NSLog(@"Error setting session category: %@", error.localizedFailureReason);
    return NO;
}


if (![session setActive:YES error:&error])
{
    NSLog(@"Error activating audio session: %@", error.localizedFailureReason);
    return NO;
}

return session.inputIsAvailable;
}

Swift 4

func startAudioSession() -> Bool {

 let session = AVAudioSession()
 do {
  try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
 } catch(let error) {
  print("--> \(error.localizedDescription)")
}
 do {
   try session.setActive(true)
 } catch (let error) {
   print("--> \(error.localizedDescription)")
 }
   return session.isInputAvailable;
}

Record Sound..

Objective-c

- (BOOL) record
{
NSError *error;

// Recording settings
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:[self dateString]];

// File URL
NSURL *url = [NSURL fileURLWithPath:pathToSave];//FILEPATH];

// Create recorder
recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
if (!recorder)
{
    NSLog(@"Error establishing recorder: %@", error.localizedFailureReason);
    return NO;
}

// Initialize degate, metering, etc.
recorder.delegate = self;
recorder.meteringEnabled = YES;
//self.title = @"0:00";

if (![recorder prepareToRecord])
{
    NSLog(@"Error: Prepare to record failed");
    //[self say:@"Error while preparing recording"];
    return NO;
}

if (![recorder record])
{
    NSLog(@"Error: Record failed");
//  [self say:@"Error while attempting to record audio"];
    return NO;
}

// Set a timer to monitor levels, current time
timer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(updateMeters) userInfo:nil repeats:YES];

return YES;
}

Swift 4

func record() -> Bool {

    var settings: [String: Any]  = [String: String]()
    settings[AVFormatIDKey] = kAudioFormatLinearPCM
    settings[AVSampleRateKey] = 8000.0
    settings[AVNumberOfChannelsKey] = 1
    settings[AVLinearPCMBitDepthKey] = 16
    settings[AVLinearPCMIsBigEndianKey] = false
    settings[AVLinearPCMIsFloatKey] = false
    settings[AVAudioQualityMax] = AVEncoderAudioQualityKey

    let searchPaths: [String] = NSSearchPathForDirectoriesInDomains(.documentDirectory, .allDomainsMask, true)
    let documentPath_ = searchPaths.first
    let pathToSave = "\(documentPath_)/\(dateString)"
    let url: URL = URL(pathToSave)

    recorder = try? AVAudioRecorder(url: url, settings: settings)

    // Initialize degate, metering, etc.
    recorder.delegate = self;
    recorder.meteringEnabled = true;
    recorder?.prepareToRecord()
    if let recordIs = recorder {
        return recordIs.record()
    }
    return false
    }

Play sound...Retrieve From document directiory

Objective-c

-(void)play
{

 NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath_ = [searchPaths objectAtIndex: 0];

 NSFileManager *fileManager = [NSFileManager defaultManager];

if ([fileManager fileExistsAtPath:[self recordingFolder]]) 
    { 

    arrayListOfRecordSound=[[NSMutableArray alloc]initWithArray:[fileManager  contentsOfDirectoryAtPath:documentPath_ error:nil]];

    NSLog(@"====%@",arrayListOfRecordSound);

}

   NSString  *selectedSound =  [documentPath_ stringByAppendingPathComponent:[arrayListOfRecordSound objectAtIndex:0]];

    NSURL   *url =[NSURL fileURLWithPath:selectedSound];

     //Start playback
   player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];

   if (!player)
   {
     NSLog(@"Error establishing player for %@: %@", recorder.url, error.localizedFailureReason);
     return;
    }

    player.delegate = self;

    // Change audio session for playback
    if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error])
    {
        NSLog(@"Error updating audio session: %@", error.localizedFailureReason);
        return;
    }

    self.title = @"Playing back recording...";

    [player prepareToPlay];
    [player play];


}

Swift 4

func play() {
        let searchPaths: [String] = NSSearchPathForDirectoriesInDomains(.documentDirectory, .allDomainsMask, true)
    let documentPath_ = searchPaths.first
      let fileManager = FileManager.default
        let arrayListOfRecordSound: [String]
        if fileManager.fileExists(atPath: recordingFolder()) {
    let arrayListOfRecordSound = try? fileManager.contentsOfDirectory(atPath: documentPath_)
    }

let selectedSound = "\(documentPath_)/\(arrayListOfRecordSound.first)"
let url = URL.init(fileURLWithPath: selectedSound)
let player = try? AVAudioPlayer(contentsOf: url)
player?.delegate = self;
try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
player?.prepareToPlay()
player?.play()
}

stopRecording

Objective-c

- (void) stopRecording
{
// This causes the didFinishRecording delegate method to fire
  [recorder stop];
}

Swift 4

func stopRecording() {
 recorder?.stop()
}

continueRecording

Objective-c

- (void) continueRecording
{
// resume from a paused recording
[recorder record];

}

Swift 4

func continueRecording() {
 recorder?.record()
}

pauseRecording

Objective-c

 - (void) pauseRecording
 {  // pause an ongoing recording
[recorder pause];

 }

Swift 4

func pauseRecording() {
 recorder?.pause()
}
like image 149
Hardeep Singh Avatar answered Oct 22 '22 00:10

Hardeep Singh