Как записать звук на iPhone с помощью AVAudioRecorder?

Теперь, когда iPhone 3.0 SDK стал общедоступным, я думаю, что могу задать этот вопрос тем из вас, кто уже играл с 3.0 SDK. Я хочу записывать звук в своем приложении, но хочу использовать AVAudioRecorder, а не более старый способ записи, как в примере SpeakHere. В Центре разработки для iPhone нет примеров того, как это лучше всего сделать, и есть ссылки только на классы. Я новичок в разработке iPhone, поэтому мне нужен простой образец, который поможет мне начать работу.


person Jim Zimmerman    schedule 18.06.2009    source источник


Ответы (11)


Собственно, примеров вообще нет. Вот мой рабочий код. Запись запускается при нажатии пользователем кнопки на панели навигации. При записи используется качество cd (44100 сэмплов), стерео (2 канала), линейный pcm. Будьте осторожны: если вы хотите использовать другой формат, особенно закодированный, убедитесь, что вы полностью понимаете, как установить настройки AVAudioRecorder (внимательно прочтите документацию по типам аудио), иначе вы никогда не сможете правильно его инициализировать. Еще кое-что. В коде я не показываю, как обрабатывать данные измерений, но вы можете легко это понять. Наконец, обратите внимание, что метод deleteRecording в AVAudioRecorder на момент написания этой статьи приводит к сбою вашего приложения. Вот почему я удаляю записанный файл через файловый менеджер. Когда запись закончена, я сохраняю записанный звук как NSData в редактируемом в данный момент объекте, используя KVC.

#define DOCUMENTS_FOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]


- (void) startRecording{

UIBarButtonItem *stopButton = [[UIBarButtonItem alloc] initWithTitle:@"Stop" style:UIBarButtonItemStyleBordered  target:self action:@selector(stopRecording)];
self.navigationItem.rightBarButtonItem = stopButton;
[stopButton release];

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err){
    NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
    return;
}
[audioSession setActive:YES error:&err];
err = nil;
if(err){
    NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
    return;
}

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



// Create a new dated file
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];
NSString *caldate = [now description];
recorderFilePath = [[NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, caldate] retain];

NSURL *url = [NSURL fileURLWithPath:recorderFilePath];
err = nil;
recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];
if(!recorder){
    NSLog(@"recorder: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
    UIAlertView *alert =
    [[UIAlertView alloc] initWithTitle: @"Warning"
                               message: [err localizedDescription]
                              delegate: nil
                     cancelButtonTitle:@"OK"
                     otherButtonTitles:nil];
    [alert show];
    [alert release];
    return;
}

//prepare to record
[recorder setDelegate:self];
[recorder prepareToRecord];
recorder.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;
}

// start recording
[recorder recordForDuration:(NSTimeInterval) 10];

}

- (void) stopRecording{

[recorder stop];

NSURL *url = [NSURL fileURLWithPath: recorderFilePath];
NSError *err = nil;
NSData *audioData = [NSData dataWithContentsOfFile:[url path] options: 0 error:&err];
if(!audioData)
    NSLog(@"audio data: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
[editedObject setValue:[NSData dataWithContentsOfURL:url] forKey:editedFieldKey];   

//[recorder deleteRecording];


NSFileManager *fm = [NSFileManager defaultManager];

err = nil;
[fm removeItemAtPath:[url path] error:&err];
if(err)
    NSLog(@"File Manager: %@ %d %@", [err domain], [err code], [[err userInfo] description]);



UIBarButtonItem *startButton = [[UIBarButtonItem alloc] initWithTitle:@"Record" style:UIBarButtonItemStyleBordered  target:self action:@selector(startRecording)];
self.navigationItem.rightBarButtonItem = startButton;
[startButton release];

}

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully:(BOOL)flag
{

NSLog (@"audioRecorderDidFinishRecording:successfully:");
// your actions here

}
person Massimo Cafaro    schedule 18.06.2009
comment
Я думаю, что близок к тому, чтобы ваш код заработал, но я борюсь с делегированием. Я новичок в Objective C и до сих пор не придумал, как правильно выполнять делегирование для чего-то вроде этого. Мой представитель пытается реализовать NSObject ‹AVAudioRecorder›, но я не думаю, что делаю это правильно. Было бы слишком сложно также опубликовать код делегата? Спасибо. - person Jim Zimmerman; 19.06.2009
comment
Я наконец-то заставил его работать, добавив это в свой класс делегата @protocol AVAudioRecorder @optional - (void) audioRecorderBeginInterruption: (AVAudioRecorder *) рекордер; - (void) audioRecorderDidFinishRecording: (AVAudioRecorder *) рекордер успешно: (BOOL) флаг; - (void) audioRecorderEncodeErrorDidOccur: (AVAudioRecorder *) ошибка записывающего устройства: (NSError *) ошибка; - (void) audioRecorderEndInterruption: (AVAudioRecorder *) рекордер; Кажется, это работает, но я не знаю, является ли это лучшей практикой или нет. Теперь мне нужно сохранить его в локальном хранилище данных и, среди прочего, воспроизвести. - person Jim Zimmerman; 19.06.2009
comment
Это не так, Джим. В заголовке контроллера записывающего устройства вы должны сделать что-то вроде ... #import ‹AVFoundation / AVFoundation.h› @interface RecorderViewController: UIViewController ‹AVAudioRecorderDelegate› { - person dizy; 19.06.2009
comment
Спасибо. Вероятно, это единственный хороший фрагмент кода в Интернете для записи. Однако использование этого кода дает мне монофоническое воспроизведение при воспроизведении записанного файла. Я указал количество каналов как 2 в настройках записи, но не получаю стерео воспроизведение. Любые идеи? - person lostInTransit; 13.10.2009
comment
некоторые вопросы: editedObject и editedFieldKey в stopRecording undefined. Вы можете дать мне немного света? - person Raptor; 21.09.2010
comment
@unforgiven у меня есть идея, как сохранить воспроизводимый звук в AVAudioPlayer? не окружающий || Звук микрофона. - person AJPatel; 10.03.2012
comment
с помощью этого кода, как я могу записать файл в формате .amr, скажите, пожалуйста - person Abhishek; 23.04.2012
comment
@Massimo Cafaro, можем ли мы записать текущий воспроизводимый файл на iphone. - person Warewolf; 25.02.2013
comment
Мне любопытно, почему вы используете now = [NSDate dateWithTimeIntervalSinceNow:0], а не просто now = [NSDate date]. Разве они не одинаковы в функциональном отношении? - person Olie; 16.07.2013
comment
@Olie, функционально они такие же. Я адаптировал свой исходный код, в котором я не использовал текущую дату, поэтому в моем коде уже был такой оператор, как recordDate = [NSDate dateWithTimeIntervalSinceNow: lastEvent]. Я просто поменял его на тот, который вы видели в фрагменте кода, но, будучи ленивым, я не стал переписывать оператор ;-) - person Massimo Cafaro; 16.07.2013
comment
@Raptor editedObject - это NSMutableDictionary, а editedFieldKey - это ключ для этого словаря. Учитывайте NSMutableDictionary = [editedObject setValue: [NSData dataWithContentsOfURL: url] forKey: @editedFieldKey]; Надеюсь, что это поможет вам. - person Vaibhav Limbani; 29.03.2014
comment
@MassimoCafaro, как я записываю звук, когда приложение работает в фоновом режиме ?. Я проверил ваш код, он не работает в фоновом режиме. - person Yogendra Girase; 29.06.2017

Несмотря на то, что это вопрос с ответом (и отчасти старый), я решил опубликовать свой полный рабочий код для других, которым было трудно найти хороший рабочий (из коробки) пример воспроизведения и записи, включая кодирование, pcm, воспроизведение через динамик , напишите в файл вот он:

AudioPlayerViewController.h:

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface AudioPlayerViewController : UIViewController {
AVAudioPlayer *audioPlayer;
AVAudioRecorder *audioRecorder;
int recordEncoding;
enum
{
    ENC_AAC = 1,
    ENC_ALAC = 2,
    ENC_IMA4 = 3,
    ENC_ILBC = 4,
    ENC_ULAW = 5,
    ENC_PCM = 6,
} encodingTypes;
}

-(IBAction) startRecording;
-(IBAction) stopRecording;
-(IBAction) playRecording;
-(IBAction) stopPlaying;

@end

AudioPlayerViewController.m:

#import "AudioPlayerViewController.h"

@implementation AudioPlayerViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    recordEncoding = ENC_AAC;
}

-(IBAction) startRecording
{
NSLog(@"startRecording");
[audioRecorder release];
audioRecorder = nil;

// Init audio with record capability
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];

NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] initWithCapacity:10];
if(recordEncoding == ENC_PCM)
{
    [recordSettings setObject:[NSNumber numberWithInt: kAudioFormatLinearPCM] forKey: AVFormatIDKey];
    [recordSettings setObject:[NSNumber numberWithFloat:44100.0] forKey: AVSampleRateKey];
    [recordSettings setObject:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
    [recordSettings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [recordSettings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
    [recordSettings setObject:[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];
    }

    [recordSettings setObject:formatObject forKey: AVFormatIDKey];
    [recordSettings setObject:[NSNumber numberWithFloat:44100.0] forKey: AVSampleRateKey];
    [recordSettings setObject:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
    [recordSettings setObject:[NSNumber numberWithInt:12800] forKey:AVEncoderBitRateKey];
    [recordSettings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [recordSettings setObject:[NSNumber numberWithInt: AVAudioQualityHigh] forKey: AVEncoderAudioQualityKey];
}

NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", [[NSBundle mainBundle] resourcePath]]];


NSError *error = nil;
audioRecorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSettings error:&error];

if ([audioRecorder prepareToRecord] == YES){
    [audioRecorder record];
}else {
    int errorCode = CFSwapInt32HostToBig ([error code]); 
    NSLog(@"Error: %@ [%4.4s])" , [error localizedDescription], (char*)&errorCode); 

}
NSLog(@"recording");
}

-(IBAction) stopRecording
{
NSLog(@"stopRecording");
[audioRecorder stop];
NSLog(@"stopped");
}

-(IBAction) playRecording
{
NSLog(@"playRecording");
// Init audio with playback capability
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];

NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
[audioPlayer play];
NSLog(@"playing");
}

-(IBAction) stopPlaying
{
NSLog(@"stopPlaying");
[audioPlayer stop];
NSLog(@"stopped");
}

- (void)dealloc
{
[audioPlayer release];
[audioRecorder release];
[super dealloc];
}

@end

Надеюсь, это поможет некоторым из вас, ребята.

person Shaybc    schedule 05.12.2010
comment
Здравствуйте! Когда я создаю и запускаю второй код, предоставленный ShayBC, на симуляторе iphone, я не получаю никаких результатов, но в консоли он показывает, что он работает. Использует ли симулятор Iphone динамик и микрофон моего ноутбука или он отключен, и мне нужно создать приложение на устройстве? - person ; 19.01.2011
comment
@Bataly, симулятор iphone будет воспроизводить ваши звуковые файлы (mp3 / caf ...) и может записывать через микрофон вашего ноутбука, попробуйте заглянуть в системные настройки leopard, если есть проблемы, но лучший способ проверить ваше приложение - запустить его на реальный iDevice, и это хорошая идея для всего кода, который вы пишете, поскольку есть ряд приложений, которые отклоняются из магазина приложений из-за сбоя, поскольку они никогда не тестировались на реальном iDevice, есть больше функций, которые не поддерживаются симулятором (bluetooth, камера, правильный мультитач, акселерометр, IAP, GPS, у него будет лучшая производительность, чем у большинства iDevice ...) - person Shaybc; 19.02.2011
comment
[recordSettings setObject: formatObject forKey: AVFormatIDKey]; Эта строка не позволяет мне использовать AVFormatIDKey в качестве ключа. Что дает? Если я установлю другое значение, он будет работать ... - person jspooner; 20.04.2011
comment
@Shaybc: не работает для меня .. я использую тот же код, только измененный, чтобы включить первые 10 секунд в случае записи .... какие-либо предложения? - person Ahsan; 30.05.2011
comment
Я обнаружил, что recordEncoding = ENC_AAC; в методе viewDidLoad является причиной вашей проблемы. Попробуйте другой формат, у меня работают другие форматы, но не kAudioFormatMPEG4AAC. Хотя не знаю почему. - person joe kirk; 04.10.2011
comment
По последним данным, для kAudioFormatMPEG4AAC мы не можем установить AVEncoderBitRateKey на 12800. Прокомментируйте вне строки, и это будет работать. Постараюсь выяснить, какой должен быть правильный битрейт для AAC. - person joe kirk; 04.10.2011
comment
Игнорируйте этот комментарий, я добавляю ваш ответ в закладки. Отлично работает в iOS 5 с небольшими изменениями - person William Entriken; 31.03.2012
comment
Хм. Нет ли утечки памяти в NSMutableDictionary * recordSettings = [[NSMutableDictionary alloc] initWithCapacity: 10] ;? recordSettings вроде нигде не выпускается? - person Olof; 30.08.2012
comment
Я не думаю, что вы можете писать в пакет, поэтому я пишу в Документы следующим образом: NSArray * paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES); NSString * basePath = пути [0]; NSURL * url = [NSURL fileURLWithPath: [NSString stringWithFormat: @% @ / recordTest.caf, basePath]]; - person marxy; 01.06.2013
comment
В этом примере кода есть основная ошибка записи аудиофайла в URL-адрес ресурса пакета. Проверьте исправление, предоставленное @marxy - person CodeBrew; 02.03.2018

Я загрузил образец проекта. Вы можете посмотреть.

VoiceRecorder

person Avinash    schedule 09.09.2011
comment
На случай, если вы не найдете загрузку: перейдите в «Загрузки» в правом верхнем углу, а затем в «СКАЧАТЬ ПАКЕТЫ». - person Phlibbo; 02.10.2011
comment
@Phlibbo: Не можете там сейчас ничего найти? - person user523234; 23.10.2011
comment
Образец кода не компилируется, как отмечалось в выпусках Github 6 месяцев назад. - person Dewayne; 17.11.2012
comment
Я исправил код и зарегистрировался в github. Теперь он должен работать. - person Avinash; 19.11.2012

Это действительно полезно. Единственная проблема, с которой я столкнулся, - это размер звукового файла, созданного после записи. Мне нужно было уменьшить размер файла, поэтому я внес некоторые изменения в настройки.

NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:16000.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];

Размер файла уменьшен с 360 КБ до 25 КБ (2 секунды записи).

person Avinash    schedule 06.10.2010
comment
Можете ли вы опубликовать и остальную часть вашего кода? Потому что я думаю, что мне что-то не хватает. Я пытался изменить многие настройки, но не могу уменьшить размер файла. - person Swapnil Luktuke; 21.05.2011
comment
Я загрузил образец проекта. Вы можете посмотреть. github.com/AvinashP/VoiceRecorder - person Avinash; 09.09.2011

Я пытался заставить этот код работать в течение последних 2 часов, и, хотя он не показал ошибок на симуляторе, на устройстве была одна.

Оказывается, по крайней мере, в моем случае ошибка возникла из используемого каталога (пакета):

NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", [[NSBundle mainBundle] resourcePath]]];

Он не был доступен для записи или что-то в этом роде ... Не было никаких ошибок, кроме того факта, что prepareToRecord не удался ...

Поэтому я заменил его на:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *recDir = [paths objectAtIndex:0];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", recDir]]

Теперь это работает как шарм.

Надеюсь, это поможет другим.

person scourtaud    schedule 03.02.2011
comment
У вас нет разрешения на запись в папку ресурсов - person saurabh; 01.06.2011

Большое спасибо @Massimo Cafaro и Shaybc, мне удалось выполнить следующие задачи

в iOS 8:

Записать аудио и сохранить

Воспроизвести сохраненную запись

1. Добавьте AVFoundation.framework в свой проект.

в файле .h

2. Добавьте ниже оператор импорта «AVFoundation / AVFoundation.h».

3. Определите AVAudioRecorderDelegate

4.Создайте макет с кнопками "Запись", "Воспроизведение" и методами их действия.

5. Определите рекордер и плеер и т. Д.

Вот полный пример кода, который может вам помочь.

ViewController.h

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ViewController : UIViewController <AVAudioRecorderDelegate>

@property(nonatomic,strong) AVAudioRecorder *recorder;
@property(nonatomic,strong) NSMutableDictionary *recorderSettings;
@property(nonatomic,strong) NSString *recorderFilePath;
@property(nonatomic,strong) AVAudioPlayer *audioPlayer;
@property(nonatomic,strong) NSString *audioFileName;

- (IBAction)startRecording:(id)sender;
- (IBAction)stopRecording:(id)sender;

- (IBAction)startPlaying:(id)sender;
- (IBAction)stopPlaying:(id)sender;

@end

Тогда сделай работу в

ViewController.m

#import "ViewController.h"

#define DOCUMENTS_FOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]

@interface ViewController ()
@end

@implementation ViewController

@synthesize recorder,recorderSettings,recorderFilePath;
@synthesize audioPlayer,audioFileName;


#pragma mark - View Controller Life cycle methods
- (void)viewDidLoad
{
    [super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}


#pragma mark - Audio Recording
- (IBAction)startRecording:(id)sender
{
    AVAudioSession *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];
    err = nil;
    if(err)
    {
        NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
        return;
    }
    
    recorderSettings = [[NSMutableDictionary alloc] init];
    [recorderSettings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
    [recorderSettings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
    [recorderSettings setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
    [recorderSettings setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
    [recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
    
    // Create a new audio file
    audioFileName = @"recordingTestFile";
    recorderFilePath = [NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, audioFileName] ;
    
    NSURL *url = [NSURL fileURLWithPath:recorderFilePath];
    err = nil;
    recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recorderSettings error:&err];
    if(!recorder){
        NSLog(@"recorder: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
        UIAlertView *alert =
        [[UIAlertView alloc] initWithTitle: @"Warning" message: [err localizedDescription] delegate: nil
                         cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
        return;
    }
    
    //prepare to record
    [recorder setDelegate:self];
    [recorder prepareToRecord];
    recorder.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];
        return;
    }
    
    // start recording
    [recorder recordForDuration:(NSTimeInterval) 60];//Maximum recording time : 60 seconds default
    NSLog(@"Recroding Started");
}

- (IBAction)stopRecording:(id)sender
{
    [recorder stop];
    NSLog(@"Recording Stopped");
}

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully:(BOOL)flag
{
    NSLog (@"audioRecorderDidFinishRecording:successfully:");
}


#pragma mark - Audio Playing
- (IBAction)startPlaying:(id)sender
{
    NSLog(@"playRecording");
    
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
    
     NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, audioFileName]];
    NSError *error;
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    audioPlayer.numberOfLoops = 0;
    [audioPlayer play];
    NSLog(@"playing");
}
- (IBAction)stopPlaying:(id)sender
{
    [audioPlayer stop];
    NSLog(@"stopped");
}

@end

введите описание изображения здесь

person swiftBoy    schedule 02.02.2015

По следующей ссылке вы можете найти полезную информацию о записи с помощью AVAudioRecording. В этой ссылке в первой части «Использование звука» есть привязка «Запись с использованием класса AVAudioRecorder». это подводит вас к примеру.

AudioVideo Conceptual MultimediaPG

person tico    schedule 24.09.2010

Хорошо, поэтому ответ, который я получил, помог мне в правильном направлении, и я очень благодарен. Это помогло мне понять, как на самом деле записывать на iPhone, но я подумал, что также включу некоторый полезный код, который я получил из справочной библиотеки iPhone:

Аудио- и видеотехнологии

Я использовал этот код и довольно легко добавил его в пример avTouch. С помощью приведенного выше примера кода и образца из справочной библиотеки я смог заставить это работать очень хорошо.

person Jim Zimmerman    schedule 29.06.2009

для формата wav ниже настройки звука

NSDictionary *audioSetting = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithFloat:44100.0],AVSampleRateKey,
                              [NSNumber numberWithInt:2],AVNumberOfChannelsKey,
                              [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
                              [NSNumber numberWithInt:kAudioFormatLinearPCM],AVFormatIDKey,
                              [NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey, 
                              [NSNumber numberWithBool:0], AVLinearPCMIsBigEndianKey,
                              [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
                              [NSData data], AVChannelLayoutKey, nil];

ссылка: http://objective-audio.jp/2010/09/avassetreaderavassetwriter.html

person Deve Tester    schedule 29.08.2013
comment
Спасибо, брат, это твой код на Swift: let recordSettings:[String:AnyObject] = [ AVFormatIDKey:Int(kAudioFormatLinearPCM), AVLinearPCMIsFloatKey:false, AVLinearPCMIsBigEndianKey:0, AVLinearPCMIsNonInterleaved:false, AVSampleRateKey:44100.0, AVNumberOfChannelsKey:2, AVEncoderBitRateKey:12800, AVLinearPCMBitDepthKey:16, AVEncoderAudioQualityKey:AVAudioQuality.Max.rawValue] - person Husam; 12.10.2015

НАЧАЛО

NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);

NSError *error = nil;
NSString *filename = [NSString stringWithFormat:@"%@.caf",FILENAME];
NSString *path = [[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:filename];
NSURL *soundFileURL = [NSURL fileURLWithPath:path];


NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
                                [NSNumber numberWithInt:AVAudioQualityMedium],AVEncoderAudioQualityKey,
                                [NSNumber numberWithInt:AVAudioQualityMedium], AVSampleRateConverterAudioQualityKey,
                                [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
                                [NSNumber numberWithFloat:22050.0],AVSampleRateKey,
                                nil];

AVAudioRecorder *audioRecorder = [[AVAudioRecorder alloc]
                 initWithURL:soundFileURL
                 settings:recordSettings
                 error:&error];


if (!error && [audioRecorder prepareToRecord])
{
    [audioRecorder record];
}

СТОП

[audioRecorder stop];
[audioRecorder release];
audioRecorder = nil;
person Tim Kozak    schedule 19.02.2013
comment
НАШЕЛ НАСТРОЙКИ ОПТИМАЛЬНОГО КАЧЕСТВА ЗВУКА - person Tim Kozak; 19.02.2013

В соответствии с приведенными выше ответами я внес некоторые изменения и получил правильный результат.

Шаг 1. В разделе "inf.plist" добавьте разрешения на использование микрофона ==>

  <key>NSMicrophoneUsageDescription</key>
  <string>${PRODUCT_NAME} Microphone Usage</string>

Шаг 2:

  1. Сохранить аудиофайл записи в локальный каталог документов

  2. Воспроизвести / остановить запись

  3. Получить продолжительность сохраненного аудиофайла

Вот исходный код. Пожалуйста, посмотрите сразу и воспользуйтесь им.

ViewController.h

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ViewController : UIViewController{
AVAudioPlayer *audioPlayer;
AVAudioRecorder *audioRecorder;
}

-(IBAction) startRecording;
-(IBAction) stopRecording;
-(IBAction) playRecording;
-(IBAction) stopPlaying;

@end

ViewController.m

#import "ViewController.h"
@interface ViewController () <AVAudioRecorderDelegate, AVAudioPlayerDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

-(IBAction) startRecording{
// Setup audio session
AVAudioSession *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];
err = nil;
if(err)
{
    NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
    return;
}
AVAudioSessionRecordPermission permissionStatus = [audioSession recordPermission];
switch (permissionStatus) {
    case AVAudioSessionRecordPermissionUndetermined:{
        [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
            // CALL YOUR METHOD HERE - as this assumes being called only once from user interacting with permission alert!
            if (granted) {
                // Microphone enabled code
                NSLog(@"Mic permission granted.  Call method for granted stuff.");
                [self startRecordingAudioSound];
            }
            else {
                // Microphone disabled code
                NSLog(@"Mic permission indeterminate. Call method for indeterminate stuff.");
                //        UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
            }
        }];
        break;
    }
    case AVAudioSessionRecordPermissionDenied:
        // direct to settings...
        NSLog(@"Mic permission denied. Call method for denied stuff.");

        break;
    case AVAudioSessionRecordPermissionGranted:
        // mic access ok...
        NSLog(@"Mic permission granted.  Call method for granted stuff.");
        [self startRecordingAudioSound];
        break;
    default:
        // this should not happen.. maybe throw an exception.
        break;
}
}

#pragma mark - Audio Recording
- (BOOL)startRecordingAudioSound{
NSError *error = nil;
NSMutableDictionary *recorderSettings = [[NSMutableDictionary alloc] init];
[recorderSettings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[recorderSettings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recorderSettings setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
[recorderSettings setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];

// Create a new audio file
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath_ = [searchPaths objectAtIndex: 0];
NSString *pathToSave = [documentPath_ stringByAppendingPathComponent:[self dateString]];
NSLog(@"the path is %@",pathToSave);

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

//Save recording path to preferences
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setURL:url forKey:@"Test1"];
[prefs synchronize];

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

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

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

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

#pragma mark - AVAudioRecorderDelegate
- (void) audioRecorderDidFinishRecording:(AVAudioRecorder *)avrecorder successfully:(BOOL)flag{
NSLog (@"audioRecorderDidFinishRecording:successfully:");
}

#pragma mark - AVAudioPlayerDelegate
- (void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
NSLog (@"audioPlayerDidFinishPlaying:successfully:");
}

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

-(IBAction) stopRecording{
NSLog(@"stopRecording");
[audioRecorder stop];
NSLog(@"stopped");
}

-(IBAction) playRecording{
//Load recording path from preferences
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSURL *temporaryRecFile = [prefs URLForKey:@"Test1"];

//Get Duration of Audio File
AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:temporaryRecFile options:nil];
CMTime audioDuration = audioAsset.duration;
float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
NSLog(@"Duration Of Audio: %f", audioDurationSeconds);

audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:temporaryRecFile error:nil];
audioPlayer.delegate = self;
[audioPlayer setNumberOfLoops:0];
audioPlayer.volume = 1;
[audioPlayer prepareToPlay];
[audioPlayer play];
NSLog(@"playing");
}

-(IBAction) stopPlaying{
NSLog(@"stopPlaying");
[audioPlayer stop];
NSLog(@"stopped");
 }

 @end
person Mannam Brahmam    schedule 19.06.2018
comment
Не используйте -[NSUserDefaults synchronize]. Из документации Apple этот метод не нужен и не должны использоваться. - person Ashley Mills; 11.10.2018
comment
Спасибо чувак! Этот ответ должен быть выше, поскольку последние версии iOS требуют, чтобы информация о конфиденциальности была в файле info.plist. Кроме того, к сведению любых других новичков iOS, которые сталкиваются с этим: вы можете открыть Info.plist, а затем просто щелкнуть правой кнопкой мыши фон в нижней части файла, нажать Добавить строку и вставить NSMicrophoneUsageDescription - person Debug Arnaut; 29.12.2020