【原】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

      2. http://stackoverflow.com/questions/18807157/how-do-i-route-audio-to-speaker-without-using-audiosessionsetproperty

本文属于原创,转载请注明,谢谢 http://www.cnblogs.com/A--G/p/4624526.html

posted on 2015-07-06 15:40  MichaelMao  阅读(11815)  评论(2编辑  收藏  举报