【原】AVAudio录制,播放 (解决真机播放音量太小)
原文链接:http://www.cnblogs.com/A--G/p/4624526.html
最近学习AVFoundation里的audio操作,最基本的录制和播放,参考了一个Code4pp的 一个 demo后,发现写的不错,但是里面有一些问题,1,由于没有添加控制输入输出流的AVAudioSession,真机播放无法录音;2.真机播放的音量很小;
下面是源代码:
1 // 2 // ViewController.h 3 // AudioRecorder 4 // 5 // Created by MZN on 15-7-1. 6 // Copyright (c) 2015年 MZN. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 #import <AudioToolbox/AudioToolbox.h> 11 #import <AVFoundation/AVFoundation.h> 12 13 @interface ViewController : UIViewController<AVAudioRecorderDelegate> 14 { 15 AVAudioRecorder *recorder; 16 NSTimer *timer; 17 NSURL *urlPlay; 18 19 } 20 @property (retain, nonatomic) IBOutlet UIButton *btn; 21 @property (retain, nonatomic) IBOutlet UIImageView *imageView; 22 @property (retain, nonatomic) IBOutlet UIButton *playBtn; 23 @property (retain, nonatomic) AVAudioPlayer *avPlay; 24 25 @end
1 // 2 // ViewController.m 3 // AudioRecorder 4 // 5 // Created by MZN on 15-7-1. 6 // Copyright (c) 2014年 MZN. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 11 @interface ViewController () 12 13 @end 14 15 @implementation ViewController 16 @synthesize btn; 17 @synthesize imageView = _imageView; 18 @synthesize playBtn = _playBtn; 19 @synthesize avPlay = _avPlay; 20 21 - (void)viewDidLoad 22 { 23 [super viewDidLoad]; 24 // Do any additional setup after loading the view, typically from a nib. 25 [self audio]; 26 [self.btn addTarget:self action:@selector(btnDown:) forControlEvents:UIControlEventTouchDown]; 27 [self.btn addTarget:self action:@selector(btnUp:) forControlEvents:UIControlEventTouchUpInside]; 28 [self.btn addTarget:self action:@selector(btnDragUp:) forControlEvents:UIControlEventTouchDragExit]; 29 [self.playBtn addTarget:self action:@selector(playRecordSound:) forControlEvents:UIControlEventTouchDown]; 30 31 } 32 33 - (IBAction)playRecordSound:(id)sender 34 { 35 if (self.avPlay.playing) { 36 [self.avPlay stop]; 37 return; 38 } 39 AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:urlPlay error:nil]; 40 self.avPlay = player; 41 [player release]; 42 [self.avPlay play]; 43 } 44 45 - (IBAction)btnDown:(id)sender 46 { 47 48 //创建录音文件,准备录音 49 if ([recorder prepareToRecord]) { 50 //开始 51 [recorder record]; 52 } 53 54 //设置定时检测 55 timer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(detectionVoice) userInfo:nil repeats:YES]; 56 } 57 58 - (IBAction)btnUp:(id)sender 59 { 60 double cTime = recorder.currentTime; 61 if (cTime > 2) {//如果录制时间<2 不发送 62 NSLog(@"发出去"); 63 }else { 64 //删除记录的文件 65 [recorder deleteRecording]; 66 //删除存储的 67 } 68 [recorder stop]; 69 [timer invalidate]; 70 } 71 72 - (IBAction)btnDragUp:(id)sender 73 { 74 //删除录制文件 75 [recorder deleteRecording]; 76 [recorder stop]; 77 [timer invalidate]; 78 79 NSLog(@"取消发送"); 80 } 81 82 - (void)audio 83 { 84 //录音设置 85 NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init]; 86 //设置录音格式 AVFormatIDKey==kAudioFormatLinearPCM 87 [recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey]; 88 //设置录音采样率(Hz) 如:AVSampleRateKey==8000/44100/96000(影响音频的质量) 89 [recordSetting setValue:[NSNumber numberWithFloat:44100] forKey:AVSampleRateKey]; 90 //录音通道数 1 或 2 91 [recordSetting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey]; 92 //线性采样位数 8、16、24、32 93 [recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey]; 94 //录音的质量 95 [recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey]; 96 //是否使用浮点数采样 97 [recordSetting setValue:@(YES) forKey:AVLinearPCMIsFloatKey]; 98 99 NSString *strUrl = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 100 NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/lll.aac", strUrl]]; 101 urlPlay = url; 102 103 NSError *error; 104 //初始化 105 recorder = [[AVAudioRecorder alloc]initWithURL:url settings:recordSetting error:&error]; 106 //开启音量检测 107 recorder.meteringEnabled = YES; 108 recorder.delegate = self; 109 } 110 111 - (void)detectionVoice 112 { 113 [recorder updateMeters];//刷新音量数据 114 //获取音量的平均值 [recorder averagePowerForChannel:0]; 115 //音量的最大值 [recorder peakPowerForChannel:0]; 116 117 double lowPassResults = pow(10, (0.05 * [recorder peakPowerForChannel:0])); 118 NSLog(@"%lf",lowPassResults); 119 //最大50 0 120 //图片 小-》大 121 if (0<lowPassResults<=0.06) { 122 [self.imageView setImage:[UIImage imageNamed:@"record_animate_01.png"]]; 123 }else if (0.06<lowPassResults<=0.13) { 124 [self.imageView setImage:[UIImage imageNamed:@"record_animate_02.png"]]; 125 }else if (0.13<lowPassResults<=0.20) { 126 [self.imageView setImage:[UIImage imageNamed:@"record_animate_03.png"]]; 127 }else if (0.20<lowPassResults<=0.27) { 128 [self.imageView setImage:[UIImage imageNamed:@"record_animate_04.png"]]; 129 }else if (0.27<lowPassResults<=0.34) { 130 [self.imageView setImage:[UIImage imageNamed:@"record_animate_05.png"]]; 131 }else if (0.34<lowPassResults<=0.41) { 132 [self.imageView setImage:[UIImage imageNamed:@"record_animate_06.png"]]; 133 }else if (0.41<lowPassResults<=0.48) { 134 [self.imageView setImage:[UIImage imageNamed:@"record_animate_07.png"]]; 135 }else if (0.48<lowPassResults<=0.55) { 136 [self.imageView setImage:[UIImage imageNamed:@"record_animate_08.png"]]; 137 }else if (0.55<lowPassResults<=0.62) { 138 [self.imageView setImage:[UIImage imageNamed:@"record_animate_09.png"]]; 139 }else if (0.62<lowPassResults<=0.69) { 140 [self.imageView setImage:[UIImage imageNamed:@"record_animate_10.png"]]; 141 }else if (0.69<lowPassResults<=0.76) { 142 [self.imageView setImage:[UIImage imageNamed:@"record_animate_11.png"]]; 143 }else if (0.76<lowPassResults<=0.83) { 144 [self.imageView setImage:[UIImage imageNamed:@"record_animate_12.png"]]; 145 }else if (0.83<lowPassResults<=0.9) { 146 [self.imageView setImage:[UIImage imageNamed:@"record_animate_13.png"]]; 147 }else { 148 [self.imageView setImage:[UIImage imageNamed:@"record_animate_14.png"]]; 149 } 150 } 151 152 - (void) updateImage 153 { 154 [self.imageView setImage:[UIImage imageNamed:@"record_animate_01.png"]]; 155 } 156 157 - (void)didReceiveMemoryWarning 158 { 159 [super didReceiveMemoryWarning]; 160 // Dispose of any resources that can be recreated. 161 } 162 163 @end
一、问题1:添加AVAudioSession, 这里由于录制和play都需要,所以设置Category为AVAudioSessionCategoryPlayAndRecord:
1 NSError *categoryError = nil; 2 AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 3 [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&categoryError]; 4 [audioSession setActive:YES error:&categoryError];
二、问题2:真机播放音量太小,有人说设置AudioSession属性里把sizeof设成1可行:
1 // UInt32 doChangeDefault = 1; 2 // AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefault), &doChangeDefault);
使用后的确可以,但是ios7.0之后,AudioSessionSetProperty已经被弃用了,于是乎
~keep looking for~~~
____________ 15分钟之后_______________
在stackoverflow上,一位朋友说audioSession的属性基本迁移到AVFoundation里了,建议我们多使用AVFoundation里的API。
1 NSError *audioError = nil; 2 BOOL success = [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&audioError]; 3 if(!success) 4 { 5 NSLog(@"error doing outputaudioportoverride - %@", [audioError localizedDescription]); 6 }
初步实现了录制和播放功能,进一步的研究正在进行ing~~~~
需要修改过demo的朋友可以从这里下载:https://files.cnblogs.com/files/A--G/AudioRecorder%E6%94%B9%E8%BF%9B%E6%92%AD%E6%94%BE%E9%9F%B3%E9%87%8F.zip
参考链接: 1,http://code4app.com/ios/%E5%BD%95%E9%9F%B3%E5%92%8C%E6%92%AD%E6%94%BE/51ba821b6803fa6901000000
本文属于原创,转载请注明,谢谢 http://www.cnblogs.com/A--G/p/4624526.html