AVAudioRecorder看字面意思就知道是音频录制,当我们实例化该类对象,我们可以称该实例对象为音频录制者,该对象有录制音频的能力,使用音频录制者我们能够做以下几件事情:
1:可以进行音频录制,一直到用户停止录制
2:录制具体的时间
3:暂停和恢复录制
3:暂停和恢复录制
4:我们能够使用等级测量获取音频的输入等级数据
为了合理配置AVAudioSession用于录制操作,可以参考AVAudioSession Class Reference 和AVAudioSessionDelegate Protocol Reference.
录音实现步骤:
1:导入AVFoundation框架,因为我们需要AVAudioSession、AVAudioRecorder、AVAudioPlayer等类
2:创建会话session,调用AVAudioSession的类方法+(id)sharedInstance;返回一个单例实例
3:请求用户授权进行录音,如果用户同意那么调用setCategory设置音频会话分类,本例中实现录音和播放等功能,所以会话类型选择AVAudioSessionCategoryPlayAndRecord,否则提示用户进行设置
4:实例化一个音频录制者AVAudioRecorder,指定录音保存的路径并且设置录音相关属性,注意因为录音机必须知道录音文件的格式、采样率、通道数、每个采样点的位数等信息,但是也并不是所有的信息都必须设置,通常只需要几个常用设置。
AVAudioRecorder为我们提供了settings属性字典用于设置相关信息。关于录音设置详见帮助文档中的 AV Foundation Audio Settings Constants。
5:根据需求可以设置
AVAudioRecorder的代理来监听录制情况。然后
调用音频录制者的prepareToRecord(),准备录制音频
6:最后根据按钮触发录制,停止,播放等基本功能,注意在播放部分我们将使用AVAudioPlayer获取本地存储文件进行播放操作,并且可以设置代理监听播放的情况。
下面简单的实现录音功能,包括,开始录制,停止录制,暂停录制,恢复录制,开始播放,暂停播放等。在Main.storyboard添加6个按钮分别对应功能:
class ViewController: UIViewController { //audioRecorder和audioPlayer,一个用于录音,一个用于播放 var audioRecorder:AVAudioRecorder! var audioPlayer:AVAudioPlayer! //获取音频会话单例 let audioSession = AVAudioSession.sharedInstance() var isAllowed:Bool = false //定义音频的编码参数 let recordSettings = [AVSampleRateKey : NSNumber(float: Float(44100.0)),//声音采样率 AVFormatIDKey : NSNumber(int: Int32(kAudioFormatMPEG4AAC)),//编码格式 AVNumberOfChannelsKey : NSNumber(int: 1),//采集音轨 AVEncoderAudioQualityKey : NSNumber(int: Int32(AVAudioQuality.Medium.rawValue))]//音频质量 override func viewDidLoad() { super.viewDidLoad() //首先要判断是否允许访问麦克风 audioSession.requestRecordPermission { (allowed) in if !allowed{ let alertView = UIAlertView(title: "无法访问您的麦克风" , message: "请到设置 -> 隐私 -> 麦克风 ,打开访问权限", delegate: nil, cancelButtonTitle: "取消", otherButtonTitles: "好的") alertView.show() self.isAllowed = false }else{ self.isAllowed = true } } if self.isAllowed{ do { try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord) //初始化实例 try audioRecorder = AVAudioRecorder(URL: self.directoryURL()!,settings: recordSettings) audioRecorder.delegate = self //准备录音 audioRecorder.prepareToRecord() } catch let error as NSError{ print(error) } } } func directoryURL() -> NSURL? { //定义并构建一个url来保存音频,音频文件名为ddMMyyyyHHmmss.caf,根据时间来设置存储文件名 let currentDateTime = NSDate() let formatter = NSDateFormatter() formatter.dateFormat = "ddMMyyyyHHmmss" //以下2种格式都可以 //let recordingName = formatter.stringFromDate(currentDateTime)+".caf" let recordingName = formatter.stringFromDate(currentDateTime)+".m4a" let fileManager = NSFileManager.defaultManager() let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) let documentDirectory = urls[0] as NSURL let soundURL = documentDirectory.URLByAppendingPathComponent(recordingName) return soundURL } //开始录音 @IBAction func startRecord(sender: AnyObject) { //如果正在播放,先停止播放 if let audioPlayer = audioPlayer where audioPlayer.playing { audioPlayer.stop() } //是否正在录音,如果没有,开始录音 if !audioRecorder.recording { do { try audioSession.setActive(true) audioRecorder.record() }catch let error as NSError{ print(error) } } } //停止录音 @IBAction func stopRecord(sender: AnyObject) { if audioRecorder.recording{ audioRecorder.stop() do { try audioSession.setActive(false) } catch let error as NSError{ print(error) } } } //开始播放 @IBAction func startPlaying(sender: AnyObject) { if (!audioRecorder.recording){ do { //创建音频播放器AVAudioPlayer,用于在录音完成之后播放录音 let url:NSURL? = audioRecorder.url if let url = url{ try audioPlayer = AVAudioPlayer(contentsOfURL: url) audioPlayer.delegate = self audioPlayer.play() } } catch let error as NSError{ print(error) } } } //暂停播放 @IBAction func pausePlaying(sender: AnyObject) { if let audioPlayer = audioPlayer where audioPlayer.playing{ if (!audioRecorder.recording){ audioPlayer.pause() } } } //暂停录制 @IBAction func pauseRecoder(sender: AnyObject) { if audioRecorder.recording{ audioRecorder.pause() } } //恢复录制,恢复录音只需要再次调用record,AVAudioSession会帮助你记录上次录音位置并追加录音 @IBAction func resumeRecoder(sender: AnyObject) { if (!audioRecorder.recording){ self.startRecord(sender) } } } extension ViewController:AVAudioRecorderDelegate{ func audioRecorderDidFinishRecording(recorder: AVAudioRecorder, successfully flag: Bool) { if flag{ if #available(iOS 8.0, *) { let alert = UIAlertController(title: "Recorder", message: "Finished Recording", preferredStyle: .Alert) alert.addAction(UIAlertAction(title: "OK!", style: .Default, handler: {action in print("OK was tapped") })) self.presentViewController(alert, animated:true, completion:nil) } else { // Fallback on earlier versions } } } } extension ViewController:AVAudioPlayerDelegate{ func audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) { if flag{ print("播放完成!") } } }
Audio Session会话类型:
AVAudioSessionCategoryAmbient:后台播放类型,会和其它音乐混合的音频类型。这个类别用于音频比较次要的应用,应用的音频会和其他应用的音频实现混音,关闭屏幕或者静音开关打开时音频将静音.
AVAudioSessionCategorySoloAmbient:默认类型,后台播放类型,其它音乐会停止播放,默认类别。这个类别非常像AVAudioSessionCategoryAmbient类别,除了会停止其他程序的音频回放。
AVAudioSessionCategoryPlayback:这个类别会静止其他应用的音频回放。你可以使用AVAudioPlayer的prepareToPlay和play方法,在你的应用中播放声音。主UI界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放都会继续。
AVAudioSessionCategoryRecord:录音时使用。这会停止其他应用的声音并让你的应用也不能初始化音频回放(比如AVAudioPlayer)。在这种模式下,你只能进行录音。使用这个类别,调用AVAudioPlayer的prepareToPlay会返回true,但是调用play方法将返回false。主UI界面会照常工作。这时,即使你的设备屏幕被用户锁定了,应用的录音仍会继续。而且用户必须授权允许录制。
AVAudioSessionCategoryPlayAndRecord:录音并需要播放时使用。这个类别允许你的应用中同时进行声音的播放和录制。当你的声音录制或播放开始后,其他应用的声音播放将会停止。主UI界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放和录制都会继续。用户必须授权允许录制(
Recording Requires User Permission
)
AVAudioSessionCategoryAudioProcessing:这个类别用于音频处理,比如编码解码时/不播放音频/未录音时使用。设置了这种模式,你在应用中就不能播放和录制任何声音。调用AVAPlayer的prepareToPlay和play方法都将返回false。其他应用的音频也会在此模式下停止。
AVAudioSessionCategoryMultiRoute:这个类别可以实现同时可以有多种输出,例如:usb和耳机同时输出,但并非所有输入输出方式均支持.输入方式仅包括:AVAudioSessionPortUSBAudio/AVAudioSessionPortHeadsetMic AVAudioSessionPortBuiltInMic;输出仅包括:AVAudioSessionPortUSBAudio /AVAudioSessionPortLineOut /AVAudioSessionPortHeadphones /AVAudioSessionPortHDMI AVAudioSessionPortBuiltInSpeaker