ios 录制音频文件并保存在 iPhone 本地

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12135687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:53:42  来源:igfitidea点击:

Record audio file and save locally on iPhone

iphoneobjective-ciosxcode

提问by moshikafya

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.

我一直在到处寻找这个问题的答案,但找不到我需要的东西。基本上在我的应用程序中,我将语音录制到音频文件(如 iOS 语音备忘录应用程序),然后想将其保存到本地文档目录。由于某种原因,我在下次启动应用程序时获得的带有录制文件的 URL 会过期。此外,即使没有,如果我记录两次,第二个文件的 URL 与第一个文件的 URL 相同,所以我丢失了第一个文件。

Recording this way:

记录方式如下:

    [audioRecorder record];

Where: AVAudioRecorder *audioRecorder;

其中: AVAudioRecorder *audioRecorder;

Playing is ok:

播放没问题:

        [audioPlayer play];

Where: AVAudioPlayer *audioPlayer;

其中: AVAudioPlayer *audioPlayer;

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

在 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.

数据是我的 AVAudioPlayer NSData 属性的数据,但 BOOL 为 0,不知道为什么。

回答by Hardeep Singh

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

返回我们用作声音文件名的当前日期和时间。

Objective-c

目标-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

斯威夫特 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

目标-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

斯威夫特 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

目标-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

斯威夫特 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

目标-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

斯威夫特 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

目标-c

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

Swift 4

斯威夫特 4

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

continueRecording

继续录音

Objective-c

目标-c

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

}

Swift 4

斯威夫特 4

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

pauseRecording

暂停录音

Objective-c

目标-c

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

 }

Swift 4

斯威夫特 4

func pauseRecording() {
 recorder?.pause()
}