程序目标:实现录音以及播放功能
开发平台:Xcode 10
语言:swift
目标平台: iOS 12
实现步骤:
1. 首先建立一个single view 的iOS应用,在storyboard上添加三个按钮,”Start”, “Stop”, “Play”,分别对应app要实现的开始录音,结束录音和播放音频的操作UI
2. 获取语音授权
首先在Info.plist中找到Information Property List,点击添加在下拉菜单中选择Privacy – Microphone Usage Description,然后在value中随意输入向用户询问许可时的文字。
下面的代码用于获取用户对麦克风的授权
func checkAuthoriztion(){ status = AVCaptureDevice.authorizationStatus(for: AVMediaType.audio) if (status == .notDetermined){ print("Not determined") } if (status == .restricted) { print("restricted") } if (status == .denied){ print("denied") } if (status == .authorized){ print("Authorized") return } // 获取麦克风权限 AVCaptureDevice.requestAccess(for: AVMediaType.audio, completionHandler: { (granted: Bool) -> Void in if(granted){ //受限制 self.status = AVAuthorizationStatus.restricted exit(0) } }) }
3. 在ViewController类中添加这三个按钮对应的响应代码:
3.1 开始录音
@IBAction func startRecord(_ sender: UIButton) { checkAuthoriztion() let session = AVAudioSession.sharedInstance() //设置session类型 do { try session.setCategory(AVAudioSession.Category.playAndRecord) } catch let err{ print("设置类型失败:\(err.localizedDescription)") } //设置session动作 do { try session.setActive(true) } catch let err { print("初始化动作失败:\(err.localizedDescription)") } //录音设置,注意,后面需要转换成NSNumber,如果不转换,你会发现,无法录制音频文件,我猜测是因为底层还是用OC写的原因 let recordSetting: [String: Any] = [AVSampleRateKey: NSNumber(value: 16000),//采样率 AVFormatIDKey: NSNumber(value: kAudioFormatLinearPCM),//音频格式 AVLinearPCMBitDepthKey: NSNumber(value: 16),//采样位数 AVNumberOfChannelsKey: NSNumber(value: 1),//通道数 AVEncoderAudioQualityKey: NSNumber(value: AVAudioQuality.min.rawValue)//录音质量 ]; //开始录音 do { let url = URL(fileURLWithPath: file_path!) recorder = try AVAudioRecorder(url: url, settings: recordSetting) recorder!.prepareToRecord() recorder!.record() print("开始录音") } catch let err { print("录音失败:\(err.localizedDescription)") } }
3.2 结束录音
@IBAction func stopRecord(_ sender: UIButton) { //结束录音 if let recorder = self.recorder { if recorder.isRecording { print("正在录音,马上结束它,文件保存到了:\(file_path!)") }else { print("没有录音,但是依然结束它") } recorder.stop() self.recorder = nil }else { print("没有初始化") } }
3.3 播放录音文件
@IBAction func play(_ sender: UIButton) { //播放 do { player = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: file_path!)) print("歌曲长度:\(player!.duration)") player!.play() } catch let err { print("播放失败:\(err.localizedDescription)") } }
4. 实时显示录音分贝
在故事板添加Label控件,设置定时器,实时显示录音时的分贝值
// 初始化一个Timer类型的定时器,并触发定时更新分贝值的函数 func startTimer() { timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateMeter), userInfo: nil, repeats: true) timer!.fire() } func stoptTimer() { if timer != nil { timer!.invalidate() //销毁timer timer = nil } } //更新分贝值的函数 @objc func updateMeter() { recorder?.updateMeters() audioLevel = (recorder?.averagePower(forChannel: 0))! level.text = String(audioLevel) }
完整代码(ViewController.swift)
import Foundation import AVFoundation import UIKit class ViewController: UIViewController { var status: AVAuthorizationStatus! var recorder: AVAudioRecorder? var player: AVAudioPlayer? let file_path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first?.appending("/record.wav") @IBOutlet weak var Start: UIButton! @IBOutlet weak var Stop: UIButton! @IBOutlet weak var Play: UIButton! @IBOutlet weak var level: UILabel! var audioLevel: Float = 0.0 var timer: Timer? func checkAuthoriztion(){ status = AVCaptureDevice.authorizationStatus(for: AVMediaType.audio) if (status == .notDetermined){ print("Not determined") } if (status == .restricted) { print("restricted") } if (status == .denied){ print("denied") } if (status == .authorized){ print("Authorized") return } // 获取麦克风权限 AVCaptureDevice.requestAccess(for: AVMediaType.audio, completionHandler: { (granted: Bool) -> Void in if(granted){ //受限制 self.status = AVAuthorizationStatus.restricted exit(0) } }) } func startTimer() { timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateMeter), userInfo: nil, repeats: true) timer!.fire() } func stoptTimer() { if timer != nil { timer!.invalidate() //销毁timer timer = nil } } @objc func updateMeter() { recorder?.updateMeters() audioLevel = (recorder?.averagePower(forChannel: 0))! level.text = String(audioLevel) } @IBAction func startRecord(_ sender: UIButton) { checkAuthoriztion() let session = AVAudioSession.sharedInstance() //设置session类型 do { try session.setCategory(AVAudioSession.Category.playAndRecord) } catch let err{ print("设置类型失败:\(err.localizedDescription)") } //设置session动作 do { try session.setActive(true) } catch let err { print("初始化动作失败:\(err.localizedDescription)") } //录音设置,注意,后面需要转换成NSNumber,如果不转换,你会发现,无法录制音频文件,我猜测是因为底层还是用OC写的原因 let recordSetting: [String: Any] = [AVSampleRateKey: NSNumber(value: 16000),//采样率 AVFormatIDKey: NSNumber(value: kAudioFormatLinearPCM),//音频格式 AVLinearPCMBitDepthKey: NSNumber(value: 16),//采样位数 AVNumberOfChannelsKey: NSNumber(value: 1),//通道数 AVEncoderAudioQualityKey: NSNumber(value: AVAudioQuality.min.rawValue)//录音质量 ]; //开始录音 do { let url = URL(fileURLWithPath: file_path!) recorder = try AVAudioRecorder(url: url, settings: recordSetting) recorder!.isMeteringEnabled = true recorder!.prepareToRecord() recorder!.record() startTimer() print("开始录音") } catch let err { print("录音失败:\(err.localizedDescription)") } } @IBAction func stopRecord(_ sender: UIButton) { //结束录音 if let recorder = self.recorder { if recorder.isRecording { print("正在录音,马上结束它,文件保存到了:\(file_path!)") }else { print("没有录音,但是依然结束它") } recorder.stop() stoptTimer() self.recorder = nil }else { print("没有初始化") } } @IBAction func play(_ sender: UIButton) { //播放 do { player = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: file_path!)) print("歌曲长度:\(player!.duration)") player!.play() } catch let err { print("播放失败:\(err.localizedDescription)") } } }
摸鱼堡版权所有丨如未注明,均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明转自:http://moyubao.net/coder/972/
转载请注明转自:http://moyubao.net/coder/972/