CoreAudio实现录音播音和扬声器听筒模式的切换
本例子使用Core Audio实现类似于微信的音频对讲功能,可以录音和播放并且实现了听筒模式和扬声器模式的切换。录音主要使用AVAudioRecorder类来实现录音功能,播放则使用AVAudioPlayer类来实现播放音频功能,扬声器和听筒模式的切换是通过设置AVAudioSession类的属性值来实现切换效果。
- (void)viewDidLoad
{
[super viewDidLoad];
//创建录音按钮
UIButton* recorderB = [[[UIButton alloc]initWithFrame:CGRectMake(20, 220, 60, 40)]autorelease];
[recorderB setTitle:@"record" forState:UIControlStateNormal];
[recorderB setBackgroundColor:[UIColor grayColor]];
[recorderB addTarget:self action:@selector(prerecord:) forControlEvents:UIControlEventTouchDown];
[recorderB addTarget:self action:@selector(startrecord:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:recorderB];
//创建播放按钮
UIButton* play = [[[UIButton alloc]initWithFrame:CGRectMake(230, 220, 60, 40)]autorelease];
[play setTitle:@"play" forState:UIControlStateNormal];
[play setBackgroundColor:[UIColor grayColor]];
[play addTarget:self action:@selector(play:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:play];
//创建听筒模式和扬声器模式切换按钮
change = [[[UISwitch alloc]initWithFrame:CGRectMake(120, 225, 40, 40)]autorelease];
//默认设置为没有打开,则用听筒模式
[change setOn:NO];
[change addTarget:self action:@selector(change:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:change];
}
//切换按钮事件
-(void)change:(UISwitch*)sender{
NSLog(@"%@",NSStringFromSelector(_cmd));
//录音的时候因为设置的音频会话是录音模式,所以录音完成后要把音频会话设置回听筒模式或者扬声器模式,根据切换器的值判断,kAudioSessionOverrideAudioRoute_None为听筒模式,kAudioSessionOverrideAudioRoute_Speaker为扬声器模式
UInt32 audioRouteOverride = ![sender isOn] ?kAudioSessionOverrideAudioRoute_None:kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setActive:YES error:nil];
}
//录音事件
-(void)record:(id)sender{
//获取当前应用的AudioSession,每个应用都有自己唯一的声频会话
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
NSError* error1;
//设置当前应用的声频会话为录音模式
/*
Use this category for background sounds such as rain, car engine noise, etc.
Mixes with other music.
AVF_EXPORT NSString *const AVAudioSessionCategoryAmbient;
Use this category for background sounds. Other music will stop playing. AVF_EXPORT NSString *const AVAudioSessionCategorySoloAmbient;
Use this category for music tracks.
AVF_EXPORT NSString *const AVAudioSessionCategoryPlayback;
Use this category when recording audio.
AVF_EXPORT NSString *const AVAudioSessionCategoryRecord;
Use this category when recording and playing back audio.
AVF_EXPORT NSString *const AVAudioSessionCategoryPlayAndRecord;
Use this category when using a hardware codec or signal processor while
not playing or recording audio.
AVF_EXPORT NSString *const AVAudioSessionCategoryAudioProcessing;
*/
[audioSession setCategory:AVAudioSessionCategoryRecord error: &error1];
//激活音频会话
[audioSession setActive:YES error: &error1];
NSLog(@"record...");
//创建录音的文件保存位置
NSString* filepath = [DOCUMENT_PATH stringByAppendingPathComponent:@"test.caf"];
url = [[NSURL fileURLWithPath:filepath]retain];
NSLog(@"path:%@",filepath);
//设置录音的相关属性
NSMutableDictionary *settings = [[NSMutableDictionary alloc] init];
//设置音频格式
[settings
setValue:[NSNumber numberWithInteger:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
//设置采用率
[settings
setValue:[NSNumber numberWithFloat:44100.0f] forKey:AVSampleRateKey];
//设置频道
[settings
setValue:[NSNumber numberWithInteger:2] forKey:AVNumberOfChannelsKey];
//设置录音质量
[settings
setValue:[NSNumber numberWithInteger:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
NSError* error;
recorder = [[AVAudioRecorder alloc]initWithURL:url settings:settings error:&error];
recorder.delegate = self;
//录音准备,会为建立录音文件做好需要的准备
BOOL isrecord = [recorder prepareToRecord];
NSLog(@"isrecord:%d",isrecord);
//正式开始录音
[recorder record];
NSLog(@"record begin...");
}
//手指离开点击录音按钮的事件
-(void)startrecord:(id)sender{
NSLog(@"%@",NSStringFromSelector(_cmd));
NSTimeInterval now = [[NSDate date]timeIntervalSince1970];
//获取长按录音按钮的时间
NSTimeInterval offset = now - starttime;
NSLog(@"offset:%f",offset);
//如果长按的时间少于1秒,则不录音
if (offset<=1) {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(record:) object:self];
}else{
//超过一秒,则完成录音,停止继续录音
[self stoprecorder:recorder];
}
}
//手指点击录音按钮时间
-(void)prerecord:(id)sender{
NSLog(@"%@",NSStringFromSelector(_cmd));
//获取点击的时间
starttime = [[NSDate date]timeIntervalSince1970];
NSLog(@"starttime:%f",starttime);
//点击超过一秒后才正式录音
[self performSelector:@selector(record:) withObject:self afterDelay:1];
}
//停止录音的事件
-(void)stoprecorder:(AVAudioRecorder*)sender{
NSLog(@"%@",NSStringFromSelector(_cmd));
//判断是否还在录音,如果是就停止
if ([recorder isRecording]) {
[recorder stop];
}
}
//播放事件
-(void)play:(id)sender{
NSLog(@"%@",NSStringFromSelector(_cmd));
NSError* error;
NSLog(@"url:%@",url);
//通过AVAudioPlayer打开刚才录音的文件
AVAudioPlayer* player = [[AVAudioPlayer alloc]initWithData:[NSData dataWithContentsOfURL:url] error:&error];
//AVAudioPlayer预处理,为需要播放做好准备
BOOL isplay = [player prepareToPlay];
NSLog(@"isplay:%d",isplay);
// player.volume = 1;
player.delegate = self;
//正式播放
[player play];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//录音完成后的回调事件
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
NSLog(@"%@",NSStringFromSelector(_cmd));
//录音完成后关闭释放资源
if ([recorder isRecording]) {
[recorder stop];
}
[recorder release];
//录音的时候因为设置的音频会话是录音模式,所以录音完成后要把音频会话设置回听筒模式或者扬声器模式,根据切换器的值判断,kAudioSessionOverrideAudioRoute_None为听筒模式,kAudioSessionOverrideAudioRoute_Speaker为扬声器模式
UInt32 audioRouteOverride = ![change isOn] ?kAudioSessionOverrideAudioRoute_None:kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
//类别要AVAudioSessionCategoryPlayAndRecord,才有效
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession setActive:YES error:nil];
}
//录音编码出错的回调
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error{
NSLog(@"%@",NSStringFromSelector(_cmd));
[recorder release];
}
//播放音频完成后的回调
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
NSLog(@"%@",NSStringFromSelector(_cmd));
//成功播放完音频后释放资源
if ([player isPlaying]) {
[player stop];
}
[player release];
}
//音频播放解码出错的回调
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{
NSLog(@"%@",NSStringFromSelector(_cmd));
[player release];
}
CoreAudio实现录音播音和扬声器听筒模式的切换的更多相关文章
- Android5.0版本之后切换听筒模式
5.0以前Android听筒模式和扬声器模式这样就管用 扬声器://关闭麦克风 mAudioManager.setMicrophoneMute(false); // 打开扬声器 mAudioMa ...
- CentOS下命令行和桌面模式的切换方法(转载)
桌面模式和命令行模式的切换方法 用编辑器打开 /etc/inittab 文件(这里用的是vi,你可以选择你喜欢的): #vi /etc/inittab 打开效果图如下: 桌面模式 : 把光标所在 ...
- RENIX板卡V2-100G系列工作模式速率切换——网络测试仪实操
本文主要介绍了RENIX板卡V2-100G系列工作模式速率切换相关操作.全文分为五部分内容.文章开头对V2-100G系列板卡进行了概述,之后分别详细介绍了100G工作模式.40G工作模式.25G工作模 ...
- virtaulbox视图模式常用切换
virtaulbox发现菜单不见,如何切换视图模式呢? 很简单,通过快捷键主机(host)键 Host+F 换到全屏模 ...
- DGbroker三种保护模式的切换
1.三种保护模式 – Maximum protection 在Maximum protection下, 可以保证从库和主库数据完全一样,做到zero data loss.事务同时在主从两边提交完成,才 ...
- IIS32位,64位模式下切换
一.32位模式 1.cscript %systemdrive%\inetpub\adminscripts\adsutil.vbs set w3svc/appPools/enable32bitappon ...
- Oracle数据库归档模式的切换及其相关操作详解
SQL> shutdown immediate; Database closed. Database dismounted. ORACLE instance shut down. SQL> ...
- Linux中图形界面和文本模式相互切换
1.默认开机进入文本模式 如果想让开机自动进纯文本模式, 修改/etc/inittab 找到其中的 id:5:initdefault: 这行指示启动时的运行级是5,也就是图形模式 改成3就是文本模式了 ...
- 使用exchange普通表模式被切换到分区表
随着数据库的不断增长的数据量.有些表需要转换的普通堆表分区表模式. 有几种不同的方式来执行此操作,如出口数据表,区表再导入数据到分区表:使用EXCHANGE PARTITION方式来转换为分区表以及使 ...
随机推荐
- jenkins远程连接linux配置测试
由于配置原因造成一下错误错误: jenkins.plugins.publish_over.BapPublisherException: Failed to connect session for co ...
- python 与 matlab 混编
用于 Python 的 MATLAB 引擎 API 快速入门 安装用于 Python 的 MATLAB 引擎 API Matlab的官方文档中介绍了 Matlab 与其余编程语言之间的引擎接口,其中包 ...
- [leetcode greedy]455. Assign Cookies
Assume you are an awesome parent and want to give your children some cookies. But, you should give e ...
- django数据库操作-增删改查-多对多关系以及一对多(外键)关系
一.一对多(外键) 例子:一个作者对应多本书,一本书只有一个作者 model代码: class Person(models.Model); name = models.CharField('作者姓名' ...
- uboot的使用
嵌入式软件的层次: bootloader +boot_parameter+kernel+ boot filesystem <uboot的编译> 1)将uboot压缩文件拷贝到 linux系 ...
- android studio 添加有趣的注释模板 佛祖保佑无bug等
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 汉化包 百度云盘 下载地址:https://pan.baidu.com/s/1pLjwy ...
- php curl 发送get和post请求示例
<?php final class HttpClient { const TIME_OUT = 10; static function get($url) { $ch = curl_init() ...
- opencv第一课 打开一个图片
#include<stdio.h>#include<stdlib.h>#include<opencv2\opencv.hpp>#include<iostrea ...
- ROS知识(10)----smach_viewer的Graph view不能显示状态图
1.问题 在运行ROS by Example 2--Indigo版本中,运行 smach_viewer,再运行巡逻,命令如下: $ rosrun smach_viewer smach_viewer.p ...
- Oracle连接步骤
JDBC实现数据所有的操作: 数据库连接需要的步骤 1.数据库的驱动程序:oracle.jdbc.driver.OracleDriver; 2.连接地址:jdbc:oracle:thin:@主机地址: ...