【原】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的朋友可以從這里下載:http://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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM