OCiOS开发:录音与音效
录音
- AVAudioRecorder是AVFoundation中的类,提供了简单的录音功能。
常用方法
- 初始化方法
- (id)initWithURL:(NSURL *)url settings:(NSDictionary *)settings error:(NSError **)outError;
- 录音操作
// 1、准备开始录音
- (BOOL)prepareToRecord; // 2、开始录音
- (BOOL)record; // 3、暂停录音
- (void)pause;// 4、停止录音
- (void)stop; // 5、删除录音文件
- (BOOL)deleteRecording;
常用属性
delegate:设置委托
currentTime:获取当前录音时长
recording:获取录音状态
settings:录音设置
AVAudioRecorderDelegate
// 1、录音结束
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag;// 2、录音错误
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError * __nullable)error;
AVAudioSession
音频预设
录音前需要对音频操作进行预设:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];[[AVAudioSession sharedInstance] setActive:YES error:nil];
Category
AVAudioSessionCategoryAmbient 或 kAudioSessionCategory_AmbientSound
用于非以语音为主的应用,使用这个category的应用会随着静音键和屏幕关闭而静音。并且不会中止其它应用播放声音,可以和其它自带应用如iPod,safari等同时播放声音。注意:该Category无法在后台播放声音AVAudioSessionCategorySoloAmbient 或 kAudioSessionCategory_SoloAmbientSound
类似于AVAudioSessionCategoryAmbient 不同之处在于它会中止其它应用播放声音。 这个category为默认category。该Category无法在后台播放声音AVAudioSessionCategoryPlayback 或 kAudioSessionCategory_MediaPlayback
用于以语音为主的应用,使用这个category的应用不会随着静音键和屏幕关闭而静音。可在后台播放声音AVAudioSessionCategoryRecord 或 kAudioSessionCategory_RecordAudio
用于需要录音的应用,设置该category后,除了来电铃声,闹钟或日历提醒之外的其它系统声音都不会被播放。该Category只提供单纯录音功能AVAudioSessionCategoryPlayAndRecord 或 kAudioSessionCategory_PlayAndRecord
用于既需要播放声音又需要录音的应用,语音聊天应用(如微信)应该使用这个category。该Category提供录音和播放功能。如果你的应用需要用到iPhone上的听筒,该category是你唯一的选择,在该Category下声音的默认出口为听筒(在没有外接设备的情况下)。
Tips
并不是一个应用只能使用一个category,程序应该根据实际需要来切换设置不同的category,举个例子,录音的时候,需要设置为AVAudioSessionCategoryRecord,当录音结束时,应根据程序需要更改category为AVAudioSessionCategoryAmbient,AVAudioSessionCategorySoloAmbient或AVAudioSessionCategoryPlayback中的一种
Audio Route的选择
当你的iPhone接有多个外接音频设备时(耳塞,蓝牙耳机等),AudioSession将遵循last-in wins的原则来选择外接设备,即声音将被导向最后接入的设备。
当没有接入任何音频设备时,一般情况下声音会默认从扬声器出来,但有一个例外的情况:在PlayAndRecord这个category下,听筒会成为默认的输出设备。如果你想要改变这个行为,可以提供MPVolumeView来让用户切换到扬声器,也可通过overrideOutputAudioPort方法来programmingly切换到扬声器,也可以修改category option为AVAudioSessionCategoryOptionDefaultToSpeaker。
PlayandRecord下切换到扬声器:
除了让用户手动选择,你也可以通过以下两种方法在程序里进行切换。
// steps 1 修改Category的默认行为:
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&error]; // steps 2 OverrideOutputAudioPort:
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
录音案例
效果展示
代码示例
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>enum {PlayBtnTag = 10,RecodeBtnTag
};@interface ViewController ()@property (nonatomic, strong) AVAudioRecorder *recoder; /**< 录音器 */
@property (nonatomic, strong) AVAudioPlayer *player; /**< 播放器 */
@property (nonatomic, strong) UIButton *playBtn; /**< 播放按钮 */
@property (nonatomic, strong) UIButton *recodeBtn; /**< 录音按钮 */- (void)initializeAudioSession; /**< 初始化音频会议 */
- (void)initializeUserInterface; /**< 初始化用户界面 */@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];[self initializeAudioSession];[self initializeUserInterface];
}#pragma mark *** Initialize methods ***
- (void)initializeAudioSession {// 配置音频处理模式AVAudioSession *audioSession = [AVAudioSession sharedInstance];NSError *error = nil;BOOL success = NO;// 音频处理模式设置为播放及录音success = [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];NSAssert(success, @"set audio session category failed with error message '%@'.", [error localizedDescription]);// 激活音频处理success = [audioSession setActive:YES error:&error];NSAssert(success, @"set audio session active failed with error message '%@'.", [error localizedDescription]);
}- (void)initializeUserInterface {self.view.backgroundColor = [UIColor whiteColor];// 加载视图[self.view addSubview:self.recodeBtn];[self.view addSubview:self.playBtn];
}#pragma mark *** Events ***
- (void)respondsToButton:(UIButton *)sender {switch (sender.tag) {// 录音case RecodeBtnTag: {if (!self.playBtn.hidden) {self.playBtn.hidden = YES;}// 设置音频存储路径NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;NSString *outputPath = [documentPath stringByAppendingString:@"/recodOutput.caf"];NSURL *outputUrl = [NSURL fileURLWithPath:outputPath];// 初始化录音器NSError *error = nil;// settings:// AVSampleRateKey:播放速度// AVNumberOfChannelsKey:录音声道self.recoder = [[AVAudioRecorder alloc] initWithURL:outputUrl settings:@{AVSampleRateKey:@(1.0)} error:&error];if (error) {NSLog(@"initialize recoder error. reason:“%@”", error.localizedDescription);}else {// 准备录音[_recoder prepareToRecord];// 录音[_recoder record];// 弹框UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"正在录音..." preferredStyle:UIAlertControllerStyleAlert];[alertController addAction:[UIAlertAction actionWithTitle:@"结束" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {// 停止录音[_recoder stop];_playBtn.hidden = NO;}]];[self presentViewController:alertController animated:YES completion:nil];}}break;// 播放case PlayBtnTag: {// 播放录制的音频文件NSError *error = nil;self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.recoder.url error:&error];if (error) {NSLog(@"%@", error.localizedDescription);}else {// 设置循环次数// -1:无限循环// 0:不循环// 1:循环1次..._player.numberOfLoops = 0;[_player prepareToPlay];[_player play];}}break;default:break;}
}#pragma mark *** Setters ***
- (void)setRecoder:(AVAudioRecorder *)recoder {if (_recoder != recoder) {// 删除录制的音频文件[_recoder deleteRecording];_recoder = nil;_recoder = recoder;}
}- (void)setPlayer:(AVAudioPlayer *)player {if (_player != player) {[_player stop];_player = nil;_player = player;}
}#pragma mark *** Getters ***
- (UIButton *)recodeBtn {if (!_recodeBtn) {_recodeBtn = [UIButton buttonWithType:UIButtonTypeSystem];_recodeBtn.bounds = CGRectMake(0, 0, 100, 30);_recodeBtn.center = self.view.center;_recodeBtn.tag = RecodeBtnTag;[_recodeBtn setTitle:@"开始录音" forState:UIControlStateNormal];[_recodeBtn addTarget:self action:@selector(respondsToButton:) forControlEvents:UIControlEventTouchUpInside];}return _recodeBtn;
}
- (UIButton *)playBtn {if (!_playBtn) {_playBtn = [UIButton buttonWithType:UIButtonTypeSystem];_playBtn.bounds = CGRectMake(0, 0, 100, 30);_playBtn.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMaxY(self.recodeBtn.frame) + CGRectGetMidY(_playBtn.bounds) + 30);_playBtn.tag = PlayBtnTag;_playBtn.hidden = YES;[_playBtn setTitle:@"播放" forState:UIControlStateNormal];[_playBtn addTarget:self action:@selector(respondsToButton:) forControlEvents:UIControlEventTouchUpInside];}return _playBtn;
}
@end
音效
- AudioToolBox.framework提供了多种音效处理功能,包括混音、音效播放等。
音效使用
1、获取音效文件的路径
NSURL *url = [[NSBundle mainBundle] URLForResource:@"music_fail" withExtension:@"mp3"];
2、加载音效文件,得到对应的音效ID
SystemSoundID soundID = 0;AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
3、播放音效
AudioServicesPlaySystemSound(soundID);
注意:音效文件只需加载1次。
音效播放常见函数
// 1、加载音效文件
AudioServicesCreateSystemSoundID(CFURLRef inFileURL, SystemSoundID *outSystemSoundID)// 2、释放音效资源
AudioServicesDisposeSystemSoundID(SystemSoundID inSystemSoundID)// 3、播放音效
AudioServicesPlaySystemSound(SystemSoundID inSystemSoundID)// 4、播放音效带点震动
AudioServicesPlayAlertSound(SystemSoundID inSystemSoundID)
音效代码示例
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>@interface ViewController () {SystemSoundID _soundID;
}- (void)initializeUserInterface; /**< 初始化用户界面 */@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];[self initializeUserInterface];
}#pragma mark *** Initialize ***
- (void)initializeUserInterface {self.view.backgroundColor = [UIColor whiteColor];// 播放音效按钮UIButton *playButton = [UIButton buttonWithType:UIButtonTypeSystem];playButton.bounds = CGRectMake(0, 0, 100, 30);playButton.center = self.view.center;[playButton setTitle:@"播放音效" forState:UIControlStateNormal];[playButton addTarget:selfaction:@selector(respondsToButton:)forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:playButton];
}#pragma mark *** Events ***
- (void)respondsToButton:(UIButton *)sender {// 1、获取音效文件全路径,music_fail.mp3为自行导入的音效素材NSURL *url = [[NSBundle mainBundle] URLForResource:@"music_fail" withExtension:@"mp3"];// 2、加载音效文件,创建音效ID(SoundID,一个ID对应一个音效文件)AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &_soundID);// 3、播放音效文件// 下面的两个函数都可以用来播放音效文件,第一个函数伴随有震动效果AudioServicesPlayAlertSound(_soundID);AudioServicesPlaySystemSound(_soundID);// 4、把需要销毁的音效文件的ID传递给它既可销毁// AudioServicesDisposeSystemSoundID(_soundID);
}@end
OCiOS开发:录音与音效相关推荐
- xcode 怎么调用midi开发录音_如何组建个人录音工作室
原文: PreSonus官网 PreSonus - How to Set Up a Home Recording Studiowww.presonus.com 译者: 玩屁小猪 (译者注: 此文为P ...
- [libgdx游戏开发教程]使用Libgdx进行游戏开发(10)-音乐音效不求人,程序员也可以DIY
本章音效文件都来自于公共许可: http://files.cnblogs.com/mignet/sounds.zip 在游戏中,播放背景音乐和音效是基本的功能. Libgdx提供了跨平台的声音播放功 ...
- 开源项目—FLutter开发录音APP
Flutter录音APP 一个录音小工具,github地址,https://github.com/ThinkerJack/flutter_record. 1.语言环境 Flutter SDK : st ...
- android 开发录音那些事(录音权限授权及判断录音权限是否拒绝处理)
在项目开发录音功能是,OnTouchListener调用时使用录音功能,接下来就总结下开发过程中遇到的问题及解决办法: (1)第一次点击时会跳出选择是否授权录音权限的对话款,操作后会发现程序崩掉,怎么 ...
- java游戏开发入门(九) -音效
java游戏开发入门(九) - 图像 前言 音频资源 编码 首先完成BGM 紧接着完成音效部分 项目目录 完整代码 总结 完整项目 前言 对于一个游戏来说,音效也是必不可少的一环,自然也不能少了. ...
- xcode 怎么调用midi开发录音_音频应用专业录音声卡:雅马哈UR242声卡教程
音频应用专业录音声卡:雅马哈UR242声卡教程 I m" L" ~" f, i8 kwww.audioapp.cn audio app不少用户在拿到雅马哈UR242这 ...
- 安卓实例开发录音应用!Android架构组件Room功能详解,面试真题解析
越来越多的人在提"移动端的下半场"."Android 开发的焦虑"之类的,也有人在喊"技术天天在变,学也学不完","昨天 Kotl ...
- iOS开发拓展篇—音效的播放
一.简单介绍 简单来说,音频可以分为2种 (1)音效 又称"短音频",通常在程序中的播放时长为1~2秒 在应用程序中起到点缀效果,提升整体用户体验 (2)音乐 比如游戏中的&quo ...
- iOS音频开发(录音+播放+剪辑+合成+压缩转码)
录音: //音频会话 AVAudioSession *session = [AVAudioSession sharedInstance]; NSError *sessionError; /* AVAu ...
最新文章
- python函数文档说明调用方式_Python 跨.py文件调用自定义函数说明
- CTFshow 信息收集 web18
- 探秘Hadoop生态12:分布式日志收集系统Flume
- 一种加速WiFi模块一键配网速度的实现
- ABAP 选择屏幕上添加按钮,按钮上添加文字和图片
- 函数模块:CTVB_COMPARE_TABLES
- Ubuntu 安装 redmine
- java例程练习(布局管理器[FlowLayout])
- 875. 爱吃香蕉的珂珂(二分)
- 全网首发:GB18030制定者站出来,$为什么要显示为¥,给大家解释一下
- 诺基亚pc远程服务器,用远程桌面把win10装进iphone —-40核256G内存的生产力工具随身带...
- 寻找最小生成树的欧拉路径,即一笔画问题
- JAVA计算机毕业设计科院垃圾分类系统部署+源码+数据库+系统+lw文档
- Cookie在前端写还是后端?
- ruok is not executed because it is not in the whitelist.
- MySQL 云数据库物理备份本地恢复方案
- Windows server 2008 关闭135端口
- 亲测无限坐席在线客服系统源码,基于ThinkPHP的一款在线客服系统源码
- html版本的网站地图只适合,网站地图-乐云SEO优化知识
- 网络通信的标准化组织和常见标准