Swift - 制作一个录音机(声音的录制与播放)
(本文代码已升级至Swift4)


源码下载:
hangge_772.zip
1,技术介绍
(1)AVFoundation.framework 框架提供了 AVAudioRecorder 类。它可以实现录音功能。(2)而使用该框架的 AVAudioPlayer 类,可以实现声音的播放。
2,下面制作一个录音机样例
(1)按住录音按钮则开始录音,松开则停止录音。录音文件保存在用户文件夹下。
(2)录音过程中会实时显示声音的音量大小(这个可以用来做声音脉冲图,获得更好的展示效果)
(3)点击播放录音则可播放录制的声音文件。
3,效果图如下:

4,Info.plist配置
由于苹果安全策略更新,在使用 Xcode8 开发时,需要在 Info.plist 配置请求麦克风相的关描述字段(Privacy - Microphone Usage Description)

5,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | import UIKit import AVFoundation class ViewController : UIViewController { var recorder: AVAudioRecorder ? //录音器 var player: AVAudioPlayer ? //播放器 var recorderSeetingsDic:[ String : Any ]? //录音器设置参数数组 var volumeTimer: Timer ! //定时器线程,循环监测录音的音量大小 var aacPath: String ? //录音存储路径 @IBOutlet weak var volumLab: UILabel ! //显示录音音量 override func viewDidLoad() { super .viewDidLoad() //初始化录音器 let session: AVAudioSession = AVAudioSession .sharedInstance() //设置录音类型 try! session.setCategory( AVAudioSessionCategoryPlayAndRecord ) //设置支持后台 try! session.setActive( true ) //获取Document目录 let docDir = NSSearchPathForDirectoriesInDomains (.documentDirectory, .userDomainMask, true )[0] //组合录音文件路径 aacPath = docDir + "/play.aac" //初始化字典并添加设置参数 recorderSeetingsDic = [ AVFormatIDKey : NSNumber (value: kAudioFormatMPEG4AAC), AVNumberOfChannelsKey : 2, //录音的声道数,立体声为双声道 AVEncoderAudioQualityKey : AVAudioQuality . max .rawValue, AVEncoderBitRateKey : 320000, AVSampleRateKey : 44100.0 //录音器每秒采集的录音样本数 ] } //按下录音 @IBAction func downAction(_ sender: AnyObject ) { //初始化录音器 recorder = try! AVAudioRecorder (url: URL (string: aacPath!)!, settings: recorderSeetingsDic!) if recorder != nil { //开启仪表计数功能 recorder!.isMeteringEnabled = true //准备录音 recorder!.prepareToRecord() //开始录音 recorder!.record() //启动定时器,定时更新录音音量 volumeTimer = Timer .scheduledTimer(timeInterval: 0.1, target: self , selector: #selector( ViewController .levelTimer), userInfo: nil , repeats: true ) } } //松开按钮,结束录音 @IBAction func upAction(_ sender: AnyObject ) { //停止录音 recorder?.stop() //录音器释放 recorder = nil //暂停定时器 volumeTimer.invalidate() volumeTimer = nil volumLab.text = "录音音量:0" } //播放录制的声音 @IBAction func playAction(_ sender: AnyObject ) { //播放 player = try! AVAudioPlayer (contentsOf: URL (string: aacPath!)!) if player == nil { print ( "播放失败" ) } else { player?.play() } } //定时检测录音音量 func levelTimer(){ recorder!.updateMeters() // 刷新音量数据 let averageV: Float = recorder!.averagePower(forChannel: 0) //获取音量的平均值 let maxV: Float = recorder!.peakPower(forChannel: 0) //获取音量最大值 let lowPassResult: Double = pow( Double (10), Double (0.05*maxV)) volumLab.text = "录音音量:\(lowPassResult)" } override func didReceiveMemoryWarning() { super .didReceiveMemoryWarning() } } |

附:让声音从通过扬声器播放出来
运行上面的样例可以发现,当我们播放录音时声音是从听筒位置发出的。如果嫌音量小的话,可以将声音输出设置为下面的扬声器。
具体设置方法见下方的高亮部分。
1 2 3 4 5 6 7 8 9 10 11 12 | //播放录制的声音 @IBAction func playAction(_ sender: AnyObject ) { //播放 player = try! AVAudioPlayer (contentsOf: URL (string: aacPath!)!) if player == nil { print ( "播放失败" ) } else { //让音频通过喇叭播放 try! AVAudioSession .sharedInstance().overrideOutputAudioPort(.speaker) player?.play() } } |
我录音后播放的时候 具然是用上面那个声音播放出来的. 请问怎么样才能用下面那个大喇叭播放!
let session:AVAudioSession = AVAudioSession.sharedInstance()
//设置录音类型
try! session.setCategory(AVAudioSessionCategoryPlayAndRecord)
//设置支持后台
try! session.setActive(true)
这三个我没看到和其它代码的关联性. 所有我就没有加但也是可以录音的. 不知道这三个代码的真正作用是什么?
航哥,如何找到储存的实际路径?
源码缺少授权访问麦克风的权限描述,应该在info.plist中添加 Privacy - Microphone Usage Description
这个录音已经不能用了,是不是权限问题?
航哥真用心, 我在接受培训, 老师录的视频语法都过期了, 但是航哥这边还会更新语法~ 100000个赞!
按照这种方式编写出现了错误。setCategory 这个东西报错,有源码地址么?