iOS 音声録音(AVAudioRecorder)

プロフェッショナルプログラマーと同じ内容です。

iOS, Mac でのオーディオ録音のためのObjective-C インタフェースを提供するAVAudioRecorderの使い方(Mac OS Xでも同じです)

※AVAudioRecorderはMac OS Xの場合, 録音に利用するデバイスの選択はできません。(デフォルトになる)デバイスを選択する場合は, Audio Queue Service を利用します。iOSはマイク入力は1つです今のところ。

AVAudioRecorderでできること

  • 録音
  • 長さ(duration)を決めて録音
  • PauseとResume
  • レベルで与えられた入力のオーディオレベルを取得する
  • ファイルとして保存する

ちょっとがんばったけどできなかったこと

  • 録音の入力(マイクの入力)音量の変更(iOS)

※ちなみにMac OS Xならできます

サンプル

※ちなみに, サンプルはSimulator でも動作します。私はMac Book Pro を使っていますが, マイクついています。さらに仕事で, Mac を使っていますが, こちらもマイクがついています。マイクが付いていれば録音のテストをSimulator 上でもできます。

RecordViewController.h

#import "ViewController.h"
#import <AudioToolbox/AudioToolbox.h>

@interface RecordViewController : ViewController

@property (nonatomic)AVAudioRecorder *recorder;
@property (nonatomic)AVAudioSession *session;
@property (nonatomic)AVAudioPlayer *player;


@property (weak, nonatomic) IBOutlet UIButton *recordButton;
- (IBAction)recordClick:(id)sender;

@property (weak, nonatomic) IBOutlet UIButton *playButton;
- (IBAction)playClick:(id)sender;

@end

RecordViewController.m

#import "RecordViewController.h"

@interface RecordViewController ()

@end

- RecordViewController.m
@implementation RecordViewController

@synthesize session;
@synthesize recorder;
@synthesize player;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

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

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Helpers
-(NSMutableDictionary *)setAudioRecorder
{
    NSMutableDictionary *settings = [[NSMutableDictionary alloc] init];
    [settings setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
    [settings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
    [settings setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
    [settings setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [settings setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
    [settings setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
    
    return settings;
}

-(void)recordFile
{
    // Prepare recording(Audio session)
    NSError *error = nil;
    self.session = [AVAudioSession sharedInstance];
    
    if ( session.inputAvailable )   // for iOS6 [session inputIsAvailable]  iOS5
    {
        [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
    }
    
    if ( error != nil )
    {
        NSLog(@"Error when preparing audio session :%@", [error localizedDescription]);
        return;
    }
    [session setActive:YES error:&error];
    if ( error != nil )
    {
        NSLog(@"Error when enabling audio session :%@", [error localizedDescription]);
        return;
    }
    
    // File Path
    NSString *dir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    NSString *filePath = [dir stringByAppendingPathComponent:@"test.caf"];
    NSURL *url = [NSURL fileURLWithPath:filePath];
    
   // recorder = [[AVAudioRecorder alloc] initWithURL:url settings:nil error:&error];
   recorder = [[AVAudioRecorder alloc] initWithURL:url settings:[self setAudioRecorder] error:&error];
   
    //recorder.meteringEnabled = YES;
    if ( error != nil )
    {
        NSLog(@"Error when preparing audio recorder :%@", [error localizedDescription]);
        return;
    }
    [recorder record];
}

-(void)stopRecord
{
    if ( self.recorder != nil && self.recorder.isRecording )
    {
        [recorder stop];
        self.recorder = nil;
    }
}

-(void)playRecord
{
    NSError *error = nil;
    
    // File Path
    NSString *dir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    NSString *filePath = [dir stringByAppendingPathComponent:@"test.caf"];
    NSURL *url = [NSURL fileURLWithPath:filePath];
    
    if ( [[NSFileManager defaultManager] fileExistsAtPath:[url path]] )
    {
        self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
        
        if ( error != nil )
        {
            NSLog(@"Error %@", [error localizedDescription]);
        }
        [self.player prepareToPlay];
        [self.player play];
    }
}

- (IBAction)recordClick:(id)sender
{
    if ( self.recorder != nil && self.recorder.isRecording )
    {
        [self stopRecord];
        [self.recordButton setTitle:@"Record" forState:UIControlStateNormal];
    }
    else
    {
        [self recordFile];
        [self.recordButton setTitle:@"..." forState:UIControlStateNormal];
    }
}
- (IBAction)playClick:(id)sender
{
    [self playRecord];
}
@end

簡易的な説明

-(NSMutableDictionary *)setAudioRecorder
では, 保存形式を入れています。 settingsの部分で入れていますが, nilにするとdefault の設定になります。 辞書式に設定を入れていきます。ここで保存形式などを細かく指定できます。

-(void)recordFile
で, 実際の処理をしています。処理手順はこんな感じです。

      AudioSession をつくる
      マイク入力が可能かどうかの確認
      ファイルパスの設定
      AVAudioRecorder の作成
      record 開始