Skip to content

Instantly share code, notes, and snippets.

@oded-regev
Created January 16, 2019 13:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oded-regev/a91c61e79eaeaa94c09b1ee17552756b to your computer and use it in GitHub Desktop.
Save oded-regev/a91c61e79eaeaa94c09b1ee17552756b to your computer and use it in GitHub Desktop.
Example for audio recording
//
// ViewController.m
// AudioRecordTest
//
// Created by -------- on 16/01/2019.
// Copyright © 2019 -----. All rights reserved.
//
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()
@property (nonatomic) AVAudioEngine *audioEngine;
@property (nonatomic) AVAudioFile *outputFile;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioInterruptionHandler:) name:AVAudioSessionInterruptionNotification object:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)startRecording:(id)sender {
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
if (![session setCategory:AVAudioSessionCategoryRecord error:&error]) {
NSLog(@"Failed to set session category: %@", error);
}
NSURL *outputURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0] URLByAppendingPathComponent:@"output-4.m4a"];
__block BOOL outputFileInited = NO;
self.audioEngine = [[AVAudioEngine alloc] init];
AVAudioInputNode *inputNode = self.audioEngine.inputNode;
[inputNode installTapOnBus:0 bufferSize:512 format:nil block:^(AVAudioPCMBuffer *buffer, AVAudioTime * when) {
NSError *error;
if (self.outputFile == nil && !outputFileInited) {
NSDictionary *settings = @{
AVFormatIDKey: @(kAudioFormatMPEG4AAC),
AVNumberOfChannelsKey: @(buffer.format.channelCount),
AVSampleRateKey: @(buffer.format.sampleRate)
};
self.outputFile = [[AVAudioFile alloc] initForWriting:outputURL settings:settings error:&error];
if (!self.outputFile) {
NSLog(@"output file error: %@", error);
abort();
}
outputFileInited = YES;
}
if (self.outputFile && ![self.outputFile writeFromBuffer:buffer error:&error]) {
NSLog(@"AVAudioFile write error: %@", error);
}
}];
if (![self.audioEngine startAndReturnError:&error]) {
NSLog(@"engine start error: %@", error);
}
else {
NSLog(@"Successfully start audioEngine");
}
}
- (IBAction)stopRecording:(id)sender {
// To stop recording, nil the outputFile at some point in the future.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"Finished");
self.outputFile = nil;
});
}
// https://developer.apple.com/library/archive/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/HandlingAudioInterruptions/HandlingAudioInterruptions.html
- (void)audioInterruptionHandler:(NSNotification *)notification {
NSDictionary *info = notification.userInfo;
AVAudioSessionInterruptionType type = [info[AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
switch (type) {
case AVAudioSessionInterruptionTypeBegan:
NSLog(@"Begin interruption");
break;
case AVAudioSessionInterruptionTypeEnded:
NSLog(@"End interruption");
// or ignore shouldResume if you're really keen to resume recording
AVAudioSessionInterruptionOptions endOptions = [info[AVAudioSessionInterruptionOptionKey] unsignedIntegerValue];
if (AVAudioSessionInterruptionOptionShouldResume == endOptions) {
NSError *error;
if (![self.audioEngine startAndReturnError:&error]) {
NSLog(@"Error restarting engine: %@", error);
}
else {
NSLog(@"Successfully restarting engine: %@", error);
}
}
break;
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment