Як записати аудіо на iPhone за допомогою AVAudioRecorder?


148

Тепер, коли iPhone 3.0 sdk є загальнодоступним, я думаю, що я можу задати це питання тим, хто вже грав з 3.0 sdk. Я хочу записати звук у своїй програмі, але я хочу використовувати AVAudioRecorder, а не старіший спосіб запису, як, наприклад, показує SpeakHere. Немає жодних прикладів, як найкраще це зробити в iPhone Dev Center, і лише посилання на класи. Я новачок в розробці iPhone, тому шукаю простий зразок, щоб почати мене. Заздалегідь спасибі.

Відповіді:


207

Власне, прикладів взагалі немає. Ось мій робочий код. Запис проводиться користувачем, натиснувши кнопку на navBar. Для запису використовується якість CD (44100 зразків), стерео (2 канали) лінійний pcm. Обережно: якщо ви хочете використовувати інший формат, особливо закодований, переконайтеся, що ви повністю розумієте, як встановити параметри AVAudioRecorder (уважно прочитайте документацію про типи аудіо), інакше ви ніколи не зможете правильно ініціалізувати її. І ще одна річ. У коді я не показую, як обробляти дані вимірювання, але ви можете це зрозуміти легко. Нарешті, зауважте, що метод видалення запису 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

}

Я думаю, що я близький до того, щоб ваш код працював, але я борюся з делегатами. Я досить новачок у Objective C і досі не переймаюся головою навколо належного способу зробити делегата для чогось подібного. Мій делегат намагається реалізувати NSObject <AVAudioRecorder>, але я не думаю, що я роблю це правильно. Чи буде занадто багато проблем також розміщувати код делегата? Дякую.
Джим Циммерман

Я щойно нарешті змусив його працювати, додавши це до свого делегатного класу @protocol AVAudioRecorder @optional - (недійсний) audioRecorderBeginInterrup: (AVAudioRecorder *) рекордер; - (недійсний) audioRecorderDidFinishRecording: (AVAudioRecorder *) рекордер успішно: (BOOL) прапор; - (недійсна) audioRecorderEncodeErrorDidOccur: помилка записувача (AVAudioRecorder *): помилка (NSError *); - (недійсний) аудіорекордерEndInterrup: (AVAudioRecorder *) рекордер; Здається, це працює, але я не знаю, це найкраща практика чи ні. Тепер мені потрібно зберегти його в локальному сховищі даних і відтворити його серед іншого.
Джим Циммерман

Це не так, Джим. У заголовку контролера диктофона ви зробите щось на кшталт ... #import <AVFoundation / AVFoundation.h> @interface RecorderViewController: UIViewController <AVAudioRecorderDelegate> {
dizy

8
деякі питання: editedObject & editedFieldKey in stopRecording undefined. Чи можете ви дати мені кілька вогнів?
Раптор

1
@Olie, вони функціонально однакові. Я адаптував свій оригінальний код, у якому я не використовував поточну дату, тому я вже мав у своєму коді вислів, як recordDate = [NSDate dateWithTimeIntervalSinceNow: lastEvent]. Я просто змінив його на той, який ви бачили в фрагменті коду, але, ледачи, я не переписав заяву ;-)
Массімо Кафаро

85

Хоча на це відповідь (і це вже старе), я вирішив опублікувати свій повний робочий код для інших, яким важко було знайти хороший робочий (поза коробкою) приклад для відтворення та запису - включаючи закодований, 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

Сподіваюсь, це допоможе комусь із вас, хлопці.


Привіт. Коли я будую і запускаю другий код, наданий ShayBC на iphone simulator, я не отримую жодних результатів, але в консолі він показує, що він працює. Чи використовує симулятор Iphone динамік та мікрофон мого ноутбука чи це звук, і я повинен будувати додаток на пристрої?

1
@Bataly імітатор iphone відтворюватиме ваші звукові файли (mp3 / caf ...) і може записувати через мікрофон свого ноутбука спробуйте вивчити системні налаштування леопарда, якщо є проблеми, але найкращий спосіб перевірити додаток - це запустити його на справжній iDevice, і його гарна ідея для всього коду, який ви пишете, оскільки існує багато додатків, які відхиляються з магазину додатків через збій, оскільки вони ніколи не перевірялися на реальному iDevice, є більше функцій, які не підтримуються симулятором (Bluetooth, камера, належний мультитач, акселерометр, IAP, GPS, він матиме кращі показники порівняно з самим iDevice ...)
Shaybc

[recordSettings setObject: formatObject forKey: AVFormatIDKey]; Цей рядок не дозволить мені використовувати AVFormatIDKey як ключ. Що дає? Якщо я встановив його іншим значенням, він працює ...
jspooner

4
Останні висновки, що для kAudioFormatMPEG4AAC ми не можемо встановити AVEncoderBitRateKey на 12800. Прокоментуйте цей рядок, і він спрацює. Спробуємо з’ясувати, якою має бути правильна швидкість передачі бітів для AAC.
Джо Кірк

11
Я не думаю, що ви можете писати в пакет, тому я пишу в такі документи: NSArray * paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES); NSString * basePath = шляхи [0]; NSURL * url = [файл NSURLURLWithPath: [NSString stringWithFormat: @ "% @ / recordTest.caf", basePath]];
marxy

14

Я завантажив зразок проекту. Можна поглянути.

Диктофон


На випадок, якщо ви не знайдете завантаження: Перейдіть до розділу "Завантаження" у верхньому правому куті, а потім - "ЗАВАНТАЖИТИ ПАКЕТИ"
Фліббо

@Phlibbo: Ви не можете знайти щось там зараз?
користувач523234

@ user523234: ось URL для завантаження - github.com/AvinashP/VoiceRecorder/downloads#download_128004
rajt

2
Зразок коду не складається, як було зазначено у випусках Github 6 місяців тому.
Девейне

Я виправив код і зареєструвався в github. Це має працювати зараз.
Авінаш

11

Це дійсно корисно. Єдиною проблемою у мене був розмір звукового файлу, створеного після запису. Мені потрібно було зменшити розмір файлу, тому я змінив налаштування.

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 секунди).


Чи можете ви також опублікувати решту коду? тому що я думаю, що я пропускаю дещо. Я спробував змінити багато налаштувань, але не можу зменшити розмір файлу ..
Swapnil Luktuke

1
Я завантажив зразок проекту. Можна поглянути. github.com/AvinashP/VoiceRecorder
Avinash

8

Я намагався змусити цей код працювати останні 2 години, і хоча він не виявив помилок на тренажері, на пристрої був такий.

Виявляється, принаймні в моєму випадку, що помилка виникла з використовуваної каталогу (пакет):

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

Це було не для запису чи щось подібне ... Не було жодної помилки, окрім того, що підготовкаToRecord не вдалася ...

Тому я замінив його на:

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

Зараз це працює як шарм.

Сподіваюся, що це допомагає іншим.


1
Ви не маєте дозволу писати у папку ресурсів
saurabh

6

Велика подяка @Massimo Cafaro та Shaybc мені вдалося досягти нижчих завдань

в iOS 8:

Запис аудіо та збереження

Відтворити збережену запис

1.Додайте "AVFoundation.framework" до свого проекту

у файлі .h

2.Додати імпорт імпорту "AVFoundation / AVFoundation.h" нижче.

3. Визначте "AVAudioRecorderDelegate"

4.Створіть макет за допомогою кнопок Record, Play та метидів їх дії

5.Define Recorder та програвач тощо.

Ось повний приклад коду, який може вам допомогти.

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

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


2
This is from Multimedia programming guide...

- (IBAction) recordOrStop: (id) sender {
if (recording) {
    [soundRecorder stop];
    recording = NO;
    self.soundRecorder = nil;
    [recordOrStopButton setTitle: @"Record" forState:
     UIControlStateNormal];
    [recordOrStopButton setTitle: @"Record" forState:
     UIControlStateHighlighted];
    [[AVAudioSession sharedInstance] setActive: NO error:nil];
} 
else {
    [[AVAudioSession sharedInstance]
     setCategory: AVAudioSessionCategoryRecord
     error: nil];
    NSDictionary *recordSettings =
    [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithFloat: 44100.0], AVSampleRateKey,
     [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
     [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
     [NSNumber numberWithInt: AVAudioQualityMax],
     AVEncoderAudioQualityKey,
     nil];
    AVAudioRecorder *newRecorder =
    [[AVAudioRecorder alloc] initWithURL: soundFileURL
                                settings: recordSettings
                                   error: nil];
    [recordSettings release];
    self.soundRecorder = newRecorder;
    [newRecorder release];
    soundRecorder.delegate = self;
    [soundRecorder prepareToRecord];
    [soundRecorder record];
    [recordOrStopButton setTitle: @"Stop" forState: UIControlStateNormal];
    [recordOrStopButton setTitle: @"Stop" forState: UIControlStateHighlighted];
    recording = YES;
}
}

2

На наступному посиланні ви можете знайти корисну інформацію про запис із AVAudioRecording. У цьому посиланні у першій частині "Використання аудіо" є якір під назвою "Запис з класом AVAudioRecorder". що приводить вас до прикладу.

AudioVideo концептуальна мультимедіаPG


2

Гаразд, відповідь, яку я отримав, допомогла мені в правильному напрямку, і я дуже вдячна. Це допомогло мені зрозуміти, як насправді робити запис на iPhone, але я подумав, що я також включу корисний код, який я отримав із Довідкової бібліотеки iPhone:

AudioandVideoTechnologies

Я використовував цей код і додав його до прикладу avTouch досить легко. З наведеним вище зразком коду та зразком з довідкової бібліотеки я зміг зробити так, щоб це працювало досить добре.


2

для формату 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


Дякую брате, це ур-код у Свіфті: 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]
Хусам,

0

СТАРТ

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;

OPTIMAL SOUND ЯКІСТЬ УСТАНОВКИ I Found
comonitos

0
-(void)viewDidLoad {
 // 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];

}    

- (IBAction)btnRecordDidClicked:(UIButton *)sender {
        if (player1.playing) {
            [player1 stop];
        }

        if (!recorder.recording) {
            AVAudioSession *session = [AVAudioSession sharedInstance];
            [session setActive:YES error:nil];

            // Start recording
            [recorder record];
            [_recordTapped setTitle:@"Pause" forState:UIControlStateNormal];

        } else {

            // Pause recording
            [recorder pause];
            [_recordTapped setTitle:@"Record" forState:UIControlStateNormal];
        }

        [_stopTapped setEnabled:YES];
        [_playTapped setEnabled:NO];

    }

    - (IBAction)btnPlayDidClicked:(UIButton *)sender {
        if (!recorder.recording){
            player1 = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
            [player1 setDelegate:self];
            [player1 play];
        }
    }

    - (IBAction)btnStopDidClicked:(UIButton *)sender {
        [recorder stop];
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setActive:NO error:nil];
    }

    - (void) audioRecorderDidFinishRecording:(AVAudioRecorder *)avrecorder successfully:(BOOL)flag{
        [_recordTapped setTitle:@"play" forState:UIControlStateNormal];

        [_stopTapped setEnabled:NO];
        [_playTapped setEnabled:YES];

    }

-1

Відповідно до вищезазначених відповідей, я вніс деякі зміни і отримав правильний результат.

Крок 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

Не використовуйте -[NSUserDefaults synchronize]. З документації Apple, "цей метод непотрібний і його не слід використовувати".
Ешлі Міллс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.