¿Cómo grabo audio en iPhone con AVAudioRecorder?

148

Ahora que el iPhone 3.0 SDK es público, creo que puedo hacer esta pregunta para aquellos de ustedes que ya han estado jugando con el SDK 3.0. Quiero grabar audio en mi aplicación, pero quiero usar AVAudioRecorder y no la forma más antigua de grabar como muestra el ejemplo SpeakHere. No hay ejemplos de cómo hacer esto mejor en el Centro de desarrollo de iPhone y solo se hace referencia a las clases. Soy un novato en el desarrollo de iPhone, así que estoy buscando una muestra simple para comenzar. Gracias por adelantado.

Jim Zimmerman
fuente

Respuestas:

207

En realidad, no hay ejemplos en absoluto. Aquí está mi código de trabajo. La grabación se activa cuando el usuario presiona un botón en la barra de navegación. La grabación utiliza calidad cd (44100 muestras), estéreo (2 canales) lineal pcm. Tenga cuidado: si desea usar un formato diferente, especialmente uno codificado, asegúrese de comprender completamente cómo configurar los ajustes de AVAudioRecorder (lea cuidadosamente la documentación de los tipos de audio), de lo contrario, nunca podrá inicializarlo correctamente. Una cosa más. En el código, no estoy mostrando cómo manejar los datos de medición, pero puedes resolverlo fácilmente. Finalmente, tenga en cuenta que el método AVAudioRecorder deleteRecording a partir de este escrito bloquea su aplicación. Es por eso que estoy eliminando el archivo grabado a través del Administrador de archivos. Cuando finalizo la grabación, guardo el audio grabado como NSData en el objeto actualmente editado usando 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

}
Massimo Cafaro
fuente
Creo que estoy cerca de hacer que su código funcione, pero estoy luchando con las cosas del delegado. Soy bastante nuevo en el Objetivo C y todavía no he entendido la forma correcta de hacer el delegado para algo como esto. Tengo a mi delegado tratando de implementar NSObject <AVAudioRecorder>, pero no creo que lo esté haciendo bien. ¿Sería demasiado problema publicar el código de delegado también? Gracias.
Jim Zimmerman
Finalmente lo puse a trabajar agregando esto a mi clase de delegado @protocol AVAudioRecorder @optional - (void) audioRecorderBeginInterruption: (AVAudioRecorder *) grabadora; - (vacío) audioRecorderDidFinishRecording: (AVAudioRecorder *) grabadora con éxito: (BOOL) bandera; - (nulo) audioRecorderEncodeErrorDidOccur: (AVAudioRecorder *) error de grabadora: (NSError *) error; - (nulo) audioRecorderEndInterruption: (AVAudioRecorder *) grabadora; Parece funcionar, pero no sé si esta es la mejor práctica o no. Ahora necesito persistirlo en un almacén de datos local y reproducirlo, entre otras cosas.
Jim Zimmerman
Eso no está bien, Jim. En el encabezado del controlador de la grabadora, haría algo como ... #import <AVFoundation / AVFoundation.h> @interface RecorderViewController: UIViewController <AVAudioRecorderDelegate> {
dizy
8
algunas preguntas: editedObject & editedFieldKey en stopRecording undefined. ¿Me puedes dar algunas luces?
Raptor
1
@Olie, son funcionalmente iguales. Adapté mi código original en el que no estaba usando la fecha actual, por lo que ya tenía en mi código una declaración como grabaciónDate = [NSDate dateWithTimeIntervalSinceNow: lastEvent]. Simplemente lo cambié por el que viste en el fragmento de código, pero, como soy vago, no reescribí la declaración ;-)
Massimo Cafaro
85

Aunque esta es una pregunta respondida (y un poco antigua), he decidido publicar mi código de trabajo completo para otros que encontraron difícil encontrar un buen trabajo (listo para usar) en el ejemplo de reproducción y grabación, incluido codificado, pcm, reproducción por altavoz , escriba al archivo aquí es:

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

Espero que esto ayude a algunos de ustedes.

Shaybc
fuente
Hola, cuando construyo y ejecuto el segundo código proporcionado por ShayBC en el simulador de iPhone, no obtengo ningún resultado, pero en la consola muestra que está funcionando. ¿El simulador de Iphone utiliza el altavoz y el micrófono de mi computadora portátil o está silenciado y tengo que construir la aplicación en el dispositivo?
1
@Bataly, el simulador de iPhone reproducirá sus archivos de sonido (mp3 / caf ...) y puede grabar a través del micrófono de su computadora portátil, intente buscar las Preferencias del sistema leopard si hay problemas, pero la mejor manera de probar su aplicación es ejecutarla en un iDevice real, y es una buena idea para todo el código que escriba, ya que hay muchas aplicaciones rechazadas de la tienda de aplicaciones debido a un bloqueo, ya que nunca se probaron en un iDevice real, hay más funciones que no son compatibles con el simulador (Bluetooth, cámara, multitáctil adecuado, acelerómetro, IAP, GPS, tendrá un mejor rendimiento que la mayoría de iDevice ...)
Shaybc
[recordSettings setObject: formatObject forKey: AVFormatIDKey]; Esta línea no me permite usar AVFormatIDKey como clave. ¿Lo que da? Si lo configuro con otro valor, funciona ...
jspooner
44
Últimos hallazgos, para kAudioFormatMPEG4AAC, no podemos establecer AVEncoderBitRateKey en 12800. Comente fuera de línea y funcionará. Intentaremos averiguar cuál debería ser la velocidad de bits correcta para AAC.
Joe Kirk
11
No creo que pueda escribir en el paquete, así que escribo en Documentos como este: NSArray * caminos = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES); NSString * basePath = caminos [0]; NSURL * url = [NSURL fileURLWithPath: [NSString stringWithFormat: @ "% @ / recordTest.caf", basePath]];
marxy 01 de
14

He subido un proyecto de muestra. Puedes echar un vistazo.

Grabadora de voz

Avinash
fuente
En caso de que no encuentre la descarga: vaya a 'Descargas' en la esquina superior derecha y luego a 'DESCARGAR PAQUETES'
Phlibbo
@ Phlibbo: ¿No puedes encontrar nada allí ahora?
usuario523234
@ user523234: aquí está la url de descarga - github.com/AvinashP/VoiceRecorder/downloads#download_128004
rajt
2
El código de muestra no se compila como se señaló en los problemas de Github hace 6 meses.
Dewayne
He arreglado el código y me he registrado en github. Debería funcionar ahora.
Avinash
11

Es realmente útil. El único problema que tuve fue el tamaño del archivo de sonido creado después de la grabación. Necesitaba reducir el tamaño del archivo, así que hice algunos cambios en la configuración.

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

El tamaño del archivo se redujo de 360 ​​kb a solo 25 kb (grabación de 2 segundos).

Avinash
fuente
¿puedes publicar el resto de tu código también? porque creo que me falta algo Traté de cambiar muchas configuraciones pero no puedo reducir el tamaño del archivo ...
Swapnil Luktuke
1
He subido un proyecto de muestra. Puedes echar un vistazo. github.com/AvinashP/VoiceRecorder
Avinash
8

He estado tratando de hacer que este código funcione durante las últimas 2 horas y, aunque no mostró ningún error en el simulador, hubo uno en el dispositivo.

Resulta que, al menos en mi caso, el error provino del directorio utilizado (paquete):

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

No fue editable o algo así ... No hubo ningún error, excepto el hecho de que prepareToRecord falló ...

Por lo tanto, lo reemplacé por:

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

Ahora funciona como un encanto.

Espero que esto ayude a otros.

scourtaud
fuente
1
No tiene permiso para escribir en la carpeta de recursos
saurabh
6

Muchas gracias a @Massimo Cafaro y Shaybc pude lograr las siguientes tareas

en iOS 8:

Grabar audio y guardar

Reproducir grabación guardada

1.Agregue "AVFoundation.framework" a su proyecto

en archivo .h

2.Agregue a continuación la declaración de importación 'AVFoundation / AVFoundation.h'.

3. Definir "AVAudioRecorderDelegate"

4.Cree un diseño con los botones Grabar, Reproducir y sus métodos de acción

5.Definir grabador y reproductor, etc.

Aquí está el código de ejemplo completo que puede ayudarlo.

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

Entonces haz el trabajo en

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

ingrese la descripción de la imagen aquí

swiftBoy
fuente
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;
}
}
Govind
fuente
2

En el siguiente enlace puede encontrar información útil sobre la grabación con AVAudioRecording. En este enlace en la primera parte "Uso del audio" hay un ancla llamada "Grabación con la clase AVAudioRecorder". eso te lleva al ejemplo.

AudioVideo Conceptual MultimediaPG

tico
fuente
2

Ok, la respuesta que recibí me ayudó en la dirección correcta y estoy muy agradecido. Me ayudó a descubrir cómo grabar realmente en el iPhone, pero pensé que también incluiría un código útil que obtuve de la Biblioteca de referencia del iPhone:

Tecnologías de audio y video

Usé este código y lo agregué al ejemplo de avTouch con bastante facilidad. Con el ejemplo de código anterior y el ejemplo de la biblioteca de referencia, pude hacer que esto funcionara bastante bien.

Jim Zimmerman
fuente
2

para formato wav debajo de la configuración de audio

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

ref: http://objective-audio.jp/2010/09/avassetreaderavassetwriter.html

Deve Tester
fuente
Gracias hermano, este es tu código en 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]
Husam
0

COMIENZO

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

DETENER

[audioRecorder stop];
[audioRecorder release];
audioRecorder = nil;
comonitos
fuente
CONFIGURACIÓN DE CALIDAD DE SONIDO ÓPTIMA
ENCONTRÉ
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];

    }
Saurabh Jain
fuente
-1

Según las respuestas anteriores, hice algunos cambios y obtuve el resultado correcto.

Paso 1: en "inf.plist", agregue los permisos de uso del micrófono ==>

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

Paso 2:

  1. Guarde el archivo de audio de grabación en el directorio de documentos locales

  2. Reproducir / detener grabación

  3. Obtener la duración del archivo de audio guardado

Aquí está el código fuente. Eche un vistazo de una vez y úselo.

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
Mannam Brahmam
fuente
No utilice -[NSUserDefaults synchronize]. De la documentación de Apple "este método es innecesario y no debe usarse".
Ashley Mills