その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

iOS4でバックグラウンド音声録音する方法

音の録音機能の実装はやったことなかったんですが、それ系のアプリのソースや参考書のサンプルもあるし、ネットにも情報たくさんあるだろうから30分ぐらいでさっくりいけると思っていました。


が、もろもろすんなり行かなかったので書き残しておきます。

AudioUnit、AudioQueueはなんだか難しそう

まず、ローカルフォルダにこの本のサンプルを発見。
(Recorderというプロジェクト)


iPhone SDK アプリケーション開発ガイド
Jonathan Zdziarski
オライリージャパン
売り上げランキング: 40,841


ソースみてみたら、録音周りがほぼCで書かれてて面食らいました。。
自分がものすごく特殊なことをしようとしているならまだしも、単に録音したいだけなのに。。


iPhoneのオモチャ箱 iPhone SDKプログラミング
徳井 直生 岡村 浩志 笠谷 真也 深津 貴之 青木 太臣 大宮 聡之 瀬尾 浩二郎 バスケ 宮川 義之
ワークスコーポレーション
売り上げランキング: 261,060


こちらの本の『CameraFilter』という録音機能を持つサンプルでは、AudioUnitを使用した部分はAudioIOというクラスにラップされてていい感じそう。


と思ってたら録音しつつ再生っていう仕様ががっつり組み込まれてて分離するにはそのクラスに手を入れなきゃいけない・・・



とりあえずやってみるならAVAudioRecord

iOS SDKならもっと簡単なやり方を用意してくれてるはず!
と、その後いろいろ調べた結果、AVAudioRecordに行き着きました。


こんな感じにObjective-Cだけでシンプルに書けます。

初期化
// 録音ファイルパス
NSArray *filePaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                         NSUserDomainMask,YES);
NSString *documentDir = [filePaths objectAtIndex:0];    
NSString *path = [documentDir stringByAppendingPathComponent:@"recording.caf"];
NSURL *recordingURL = [NSURL fileURLWithPath:path];

// 録音設定
NSDictionary *settings;
settings = [NSDictionary dictionaryWithObjectsAndKeys:
            [NSNumber numberWithUnsignedInt:kAudioFormatLinearPCM], AVFormatIDKey,
            [NSNumber numberWithInt:1], AVNumberOfChannelsKey,
            nil];

// インスタンス生成
NSError *error = nil;
myRecorder = [[AVAudioRecorder alloc]initWithURL:recordingURL
                                                       settings:settings 
                                                          error:&error];
if(error){
    NSLog(@"error = %@",error);
    return;
}
myRecorder.delegate = self;
録音開始
[myRecorder record];
録音停止
[myRecorder stop];
録音結果を再生する
NSURL *recordingURL = myRecorder.url;
AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:recordingURL 
                                                              error:nil];
player.delegate = self;
[player play];

バックグラウンドで録音するなら赤い録音中表示は出さざるを得ない

長時間タスクを宣言すればその時間内は何でもやってOKなんだと思ってたのですが、実際にやってみたら、バックグラウンドに行くタイミングでばっちり録音が停止してしまいました。


なので、Info.plistにrequired backgroud modesを追加する方法でいくことにしました。



App plays audioとありますが、この指定でバックグラウンド録音もうまくいきました。


ただ、今回はアプリの特性上、赤いバーなしで録音したかったので、required backgroud modes指定なしでできなかったのは残念。
つまり赤いバーを出さずバックグラウンドで録音することはできないようです。
(いやできたよ、そういうアプリあるよ、という方、教えていただければ幸いです)