Comment enregistrer de l'audio sur iPhone avec AVAudioRecorder?

148

Maintenant que l'iPhone 3.0 sdk est public, je pense que je peux poser cette question à ceux d'entre vous qui ont déjà joué avec le sdk 3.0. Je souhaite enregistrer de l'audio dans mon application, mais je souhaite utiliser AVAudioRecorder et non l'ancienne méthode d'enregistrement comme le montre l'exemple SpeakHere. Il n'y a pas d'exemples de la meilleure façon de faire cela dans le centre de développement iPhone et ne font référence qu'aux classes. Je suis un débutant dans le développement d'iPhone, donc je cherche un exemple simple pour me lancer. Merci d'avance.

Jim Zimmerman
la source

Réponses:

207

En fait, il n'y a aucun exemple. Voici mon code de travail. L'enregistrement est déclenché par l'utilisateur qui appuie sur un bouton de la barre de navigation. L'enregistrement utilise une qualité cd (44100 échantillons), stéréo (2 canaux) pcm linéaire. Attention: si vous souhaitez utiliser un format différent, en particulier un format encodé, assurez-vous de bien comprendre comment définir les paramètres de l'AVAudioRecorder (lisez attentivement la documentation des types audio), sinon vous ne pourrez jamais l'initialiser correctement. Encore une chose. Dans le code, je ne montre pas comment gérer les données de mesure, mais vous pouvez le comprendre facilement. Enfin, notez que la méthode AVAudioRecorder deleteRecording à partir de cette écriture plante votre application. C'est pourquoi je supprime le fichier enregistré via le gestionnaire de fichiers. Lorsque l'enregistrement est terminé, j'enregistre l'audio enregistré sous NSData dans l'objet actuellement édité à l'aide de 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
la source
Je pense que je suis sur le point de faire fonctionner votre code, mais j'ai du mal avec le truc des délégués. Je suis assez nouveau dans l'Objectif C et je n'ai toujours pas compris la bonne façon de faire le délégué pour quelque chose comme ça. J'ai mon délégué qui essaie d'implémenter NSObject <AVAudioRecorder>, mais je ne pense pas que je fais les choses correctement. Serait-il trop difficile de publier également le code du délégué? Merci.
Jim Zimmerman
Je viens de le faire fonctionner en ajoutant ceci à ma classe de délégué @protocol AVAudioRecorder @optional - (void) audioRecorderBeginInterruption: (AVAudioRecorder *) enregistreur; - (void) audioRecorderDidFinishRecording: (AVAudioRecorder *) enregistreur avec succès: indicateur (BOOL); - (void) audioRecorderEncodeErrorDidOccur: erreur de l'enregistreur (AVAudioRecorder *): erreur (NSError *); - (void) audioRecorderEndInterruption: enregistreur (AVAudioRecorder *); Cela semble fonctionner, mais je ne sais pas si c'est la meilleure pratique ou non. Maintenant, je dois le conserver dans un magasin de données local et le lire entre autres.
Jim Zimmerman
Ce n'est pas bien Jim. Dans l'en-tête de votre contrôleur d'enregistreur, vous feriez quelque chose comme ... #import <AVFoundation / AVFoundation.h> @interface RecorderViewController: UIViewController <AVAudioRecorderDelegate> {
dizy
8
quelques questions: éditéObjet et éditéFieldKey dans stopRecording undefined. Pouvez-vous me donner des lumières?
Raptor
1
@Olie, ils sont fonctionnellement identiques. J'ai adapté mon code d'origine dans lequel je n'utilisais pas la date actuelle, donc j'avais déjà dans mon code une déclaration comme RecordingDate = [NSDate dateWithTimeIntervalSinceNow: lastEvent]. Je viens de le changer pour celui que vous avez vu dans l'extrait de code, mais, étant paresseux, je n'ai pas réécrit la déclaration ;-)
Massimo Cafaro
85

Bien que ce soit une question avec réponse (et un peu ancienne), j'ai décidé de publier mon code de travail complet pour ceux qui avaient du mal à trouver un bon exemple de jeu et d'enregistrement fonctionnel (prêt à l'emploi) - y compris encodé, pcm, lecture via haut-parleur , écrivez dans le fichier ici c'est:

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

J'espère que cela aidera certains d'entre vous.

Shaybc
la source
Bonjour, Lorsque je construis et exécute le deuxième code fourni par ShayBC sur le simulateur d'iphone, je n'obtiens aucun résultat mais dans la console, cela montre que cela fonctionne. Le simulateur Iphone utilise-t-il le haut-parleur et le microphone de mon ordinateur portable ou est-il muet et je dois créer l'application sur l'appareil?
1
@Bataly, le simulateur d'iphone jouera vos fichiers audio (mp3 / caf ...) et peut enregistrer via le micro de votre ordinateur portable.Essayez de consulter les préférences système de leopard en cas de problème, mais la meilleure façon de tester votre application est de l'exécuter sur un vrai iDevice, et c'est une bonne idée pour tout le code que vous écrivez car il y a beaucoup d'applications rejetées de l'App-Store en raison d'un plantage puisqu'elles n'ont jamais été testées sur un vrai iDevice, il y a plus de fonctionnalités qui ne sont pas prises en charge par le simulateur (bluetooth, appareil photo, véritable multitouch, accéléromètre, IAP, GPS, il aura de meilleures performances que le plus iDevice ...)
Shaybc
[recordSettings setObject: formatObject forKey: AVFormatIDKey]; Cette ligne ne me permettra pas d'utiliser AVFormatIDKey comme clé. Ce qui donne? Si je le règle sur une autre valeur, cela fonctionne ...
jspooner
4
Dernières découvertes, pour kAudioFormatMPEG4AAC, nous ne pouvons pas définir AVEncoderBitRateKey sur 12800. Commentez hors ligne et cela fonctionnera. Je vais essayer de savoir quel devrait être le débit binaire correct pour AAC.
joe kirk
11
Je ne pense pas que vous puissiez écrire dans le paquet, alors j'écris dans des documents comme celui-ci: NSArray * chemins = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES); NSString * basePath = chemins [0]; NSURL * url = [NSURL fileURLWithPath: [NSString stringWithFormat: @ "% @ / recordTest.caf", basePath]];
marxy
14

J'ai téléchargé un exemple de projet. Vous pouvez jeter un oeil.

Enregistreur vocal

Avinash
la source
Juste au cas où vous ne trouvez pas le téléchargement: Allez dans `` Téléchargements '' dans le coin supérieur droit puis sur `` TÉLÉCHARGER LES PACKAGES ''
Phlibbo
@Phlibbo: Vous ne trouvez rien là-bas maintenant?
user523234
@ user523234: voici l'url de téléchargement - github.com/AvinashP/VoiceRecorder/downloads#download_128004
rajt
2
L'exemple de code ne se compile pas comme indiqué dans les problèmes Github il y a 6 mois.
Dewayne
J'ai corrigé le code et enregistré dans github. Cela devrait fonctionner maintenant.
Avinash
11

C'est vraiment utile. Le seul problème que j'ai eu était la taille du fichier son créé après l'enregistrement. J'avais besoin de réduire la taille du fichier, j'ai donc fait quelques changements dans les paramètres.

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

Taille du fichier réduite de 360 ​​Ko à seulement 25 Ko (enregistrement de 2 secondes).

Avinash
la source
pouvez-vous également publier le reste de votre code? parce que je pense qu'il me manque quelque chose. J'ai essayé de modifier de nombreux paramètres mais je suis incapable de réduire la taille du fichier.
Swapnil Luktuke
1
J'ai téléchargé un exemple de projet. Vous pouvez jeter un oeil. github.com/AvinashP/VoiceRecorder
Avinash
8

J'ai essayé de faire fonctionner ce code pendant les 2 dernières heures et bien qu'il n'ait montré aucune erreur sur le simulateur, il y en avait une sur l'appareil.

Il s'avère, au moins dans mon cas, que l'erreur provenait du répertoire utilisé (bundle):

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

Ce n'était pas inscriptible ou quelque chose comme ça ... Il n'y avait pas d'erreur sauf le fait que prepareToRecord a échoué ...

Je l'ai donc remplacé par:

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

Cela fonctionne maintenant comme un charme.

J'espère que cela aide les autres.

Scourtaud
la source
1
Vous n'êtes pas autorisé à écrire dans le dossier de ressources
saurabh
6

Un grand merci à @Massimo Cafaro et Shaybc, j'ai pu accomplir les tâches ci-dessous

sous iOS 8:

Enregistrer l'audio et enregistrer

Lire l'enregistrement enregistré

1.Ajoutez "AVFoundation.framework" à votre projet

dans un fichier .h

2.Ajoutez ci-dessous la déclaration d'importation 'AVFoundation / AVFoundation.h'.

3.Définissez «AVAudioRecorderDelegate»

4.Créez une mise en page avec les boutons Enregistrer, Lire et leurs méthodes d'action

5.Définissez l'enregistreur et le lecteur, etc.

Voici l'exemple de code complet qui peut vous aider.

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

Alors fais le travail

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

entrez la description de l'image ici

swiftBoy
la source
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
la source
2

Dans le lien suivant, vous trouverez des informations utiles sur l'enregistrement avec AVAudioRecording. Dans ce lien dans la première partie «Utilisation de l'audio», il y a une ancre nommée «Enregistrement avec la classe AVAudioRecorder». cela vous conduit à l'exemple.

AudioVideo Conceptuel MultimédiaPG

tico
la source
2

Ok donc la réponse que j'ai obtenue m'a aidé dans la bonne direction et je suis très reconnaissant. Cela m'a aidé à comprendre comment enregistrer réellement sur l'iPhone, mais j'ai pensé que j'inclurais également du code utile que j'ai obtenu de la bibliothèque de référence iPhone:

Technologies audio et vidéo

J'ai utilisé ce code et l'ai ajouté assez facilement à l'exemple avTouch. Avec l'exemple de code ci-dessus et l'exemple de la bibliothèque de référence, j'ai pu le faire fonctionner assez bien.

Jim Zimmerman
la source
2

pour le format wav en dessous du réglage 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];

réf: http://objective-audio.jp/2010/09/avassetreaderavassetwriter.html

Testeur Deve
la source
Merci mon frère, voici ton code 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

DÉBUT

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

ARRÊTEZ

[audioRecorder stop];
[audioRecorder release];
audioRecorder = nil;
comonitos
la source
PARAMÈTRES OPTIMAUX DE QUALITÉ SONORE QUE J'AI TROUVÉS
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];

    }
Saurabh Jain
la source
-1

Selon les réponses ci-dessus, j'ai apporté quelques modifications et j'ai obtenu la sortie correcte.

Étape 1: sous "inf.plist", ajoutez les autorisations d'utilisation du microphone ==>

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

Étape 2:

  1. Enregistrer le fichier audio enregistré dans le répertoire de documents local

  2. Lire / arrêter l'enregistrement

  3. Obtenir la durée du fichier audio enregistré

Voici le code source. Jetez-y un coup d'œil et utilisez-le.

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
la source
N'utilisez pas -[NSUserDefaults synchronize]. D'après la documentation d'Apple, "cette méthode est inutile et ne doit pas être utilisée".
Ashley Mills