原生音視頻編碼 https://github.com/loyinglin/LearnVideoToolBox/tree/mastergit
基於 AVFoundation 進行音頻錄製github
@interface ViewController ()<AVAudioRecorderDelegate> { AVAudioRecorder *recorder; AVAudioPlayer *player; } @property (weak, nonatomic) IBOutlet UILabel *label; @end - (IBAction)record:(id)sender { if (recorder == nil) { // 路徑拼接 NSString *filePath = [NSString stringWithFormat:@"%@/rec_audio.caf", [self documentsDirectory]]; // 構建URL NSURL *fileUrl = [NSURL fileURLWithPath:filePath]; NSError *error = nil; // AVAudioSession類提供了Audio Session服務,Audio Session是指定應用於音頻系統如何交互。AVAudioSession經過指定一個音頻類別實現的,音頻類別描述了應用使用音頻的方式 // 下面是設置音頻回話類別 // AVAudioSessionCategoryRecord表明只能輸入音頻,即錄製音頻,其效果是中止其餘音頻播放,開始錄製音頻, AVAudioSessionCategoryPlayback表明只能輸出音頻,即進行音頻播放。 [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:&error]; // 設置是否「活躍」,這會把系統的任何聲音關閉 [[AVAudioSession sharedInstance] setActive:YES error:&error]; // 設置settings參數 NSMutableDictionary *settings = [NSMutableDictionary dictionary]; // AVFormatIDKey鍵是設置錄製音頻編碼格式,kAudioFormatLinearPCM表明線性PCM編碼格式,PCM(pulse code modulation)線性脈衝編碼調製,它是一種非壓縮格式。 // 注意:編碼格式與文件格式不一樣,例如WAV是音頻文件格式,它採用線性PCM音頻編碼 [settings setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey]; // AVSampleRateKey鍵是設置音頻採樣頻率,44100.0是音頻CD,VCD,SVCD和MP3所用的採樣頻率。 [settings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey]; // AVNumberOfChannelsKey設置聲道數量,值爲1或者2 [settings setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey]; // AVLinearPCMBitDepthKey這是採樣位數,取值爲8,16,24,32,16是默認值 [settings setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey]; // AVLinearPCMIsBigEndianKey設置音頻解碼是大字節序仍是小字節序,大字節序,YES,不然爲NO [settings setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey]; // AVLinearPCMIsFloatKey設置音頻解碼是否爲浮點數,若是是則設置爲YES,不然爲NO [settings setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey]; // 實例化recorder對象 recorder = [[AVAudioRecorder alloc] initWithURL:fileUrl settings:settings error:&error]; // 設置代理 recorder.delegate = self; } // 若是正在錄製,return if(recorder.isRecording) { return; } //若是正在播放,中止 if(player && player.isPlaying) { [player stop]; } // 開始錄製 [recorder record]; self.label.text = @"錄製中..."; } - (IBAction)stop:(id)sender { self.label.text = @"中止..."; // 是否正在錄製 if(recorder.isRecording) { [recorder stop];//中止 recorder.delegate = nil; recorder = nil; } if(player.isPlaying) { [player stop]; } } - (IBAction)play:(id)sender { if(recorder.isRecording) { [recorder stop]; recorder.delegate = nil; recorder = nil; } if(player.isPlaying) { [player stop]; } NSString *filePath = [NSString stringWithFormat:@"%@/rec_audio.caf", [self documentsDirectory]]; NSURL *fileUrl = [NSURL fileURLWithPath:filePath]; NSError *error = nil; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error]; [[AVAudioSession sharedInstance] setActive:YES error:&error]; player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:&error]; if(error) { NSLog(@"%@",[error description]); } else { [player play]; self.label.text = @"播放..."; } } -(NSString *)documentsDirectory{ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); return [paths objectAtIndex:0]; } #pragma mark--實現AVAudioRecorderDelegate協議方法 - (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
NSLog(@"錄製完成。"); } - (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error{ NSLog(@"錄製錯誤發生: %@", [error localizedDescription]); } - (void)audioRecorderBeginInterruption:(AVAudioRecorder *)recorder{ NSLog(@"播放中斷。"); } - (void)audioRecorderEndInterruption:(AVAudioRecorder *)recorder withOptions:(NSUInteger)flags{ NSLog(@"中斷返回。"); }