IOS15 Swift5 实现录音App

IOS15 Swift5 实现录音App

IOS15 Swift5 实现录音App

//
//  ViewController.swift
//  AudioRecoardDemo
//
//  Created by lujun on 2022/1/25.
//

import UIKit
import AudioToolbox
import AVFoundation
class ViewController: UIViewController, AVAudioPlayerDelegate {
    /// 播放音频
    var player: AVAudioPlayer!
    /// 录音
    var recorder: AVAudioRecorder!
    /// 用户输入的文件名
    var recordFileName = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
        myLabel.text = "录音测试"
        debugPrint(NSHomeDirectory())
    }
    // push到下一级页面的时候结束
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if player != nil {
            player.stop()
            player = nil
        }
        startButton.isEnabled = true
    }
    @IBOutlet weak var startButton: UIButton!
    @IBOutlet weak var myLabel: UILabel!
   

    @IBAction func addSound(_ sender: UIButton) {
        sender.isSelected = !sender.isSelected
        if sender.isSelected {
            sender.setTitle("结束并保存", for: .selected)
            let alertController = UIAlertController(title: "文件名", message: "请输入录音文件名", preferredStyle: .alert)
            let ensureAction = UIAlertAction(title: "确定", style: .default) { (action) in
                let textField = alertController.textFields![0] as UITextField
                self.recordFileName =  textField.text!
                // 开始录音
                self.createRecord()
            }
            let cancelAction = UIAlertAction(title: "取消", style: .default, handler: nil)
            alertController.addAction(ensureAction)
            alertController.addAction(cancelAction)
            alertController.addTextField { (textField) in
                textField.placeholder = "请输入录音文件名"
            }
            present(alertController, animated: true, completion: nil)
        }
        else {
            saveRecord()
        }
    }
    @IBAction func startTest(_ sender: UIButton) {
        sender.isEnabled = false
        avPlaySound()
    }
    
}


// MARK: - AudioServices 播放模式
extension ViewController {
    func playSound() {
        // 0,手机的静音开关打开后,听不到声音
        let audioFilePath = Bundle.main.path(forResource: fileName(), ofType: nil)
        let url = URL(fileURLWithPath: audioFilePath!)
        // 1.获取系统声音ID
        var soundID: SystemSoundID = 0
        AudioServicesCreateSystemSoundID(url as CFURL, &soundID)
        // 2.播放音频
        AudioServicesPlaySystemSound(soundID)
        AudioServicesPlaySystemSoundWithCompletion(soundID) {
            print("AudioServices - 播放结束---")
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5, execute: {
                print("AudioServices - 播放开始---")
                self.playSound()
            })
        }
    }
}

// MARK: - AVFoundation 播放模式
extension ViewController {
    func avPlaySound()  {
        let audioFilePath = Bundle.main.path(forResource: fileName(), ofType: nil)
        let url = URL(fileURLWithPath: audioFilePath!)
        player = try? AVAudioPlayer(contentsOf: url)
        guard let p = player else {
            return
        }
        p.delegate = self
        p.play()
    }
    
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        print("AVAudioPlayer - 播放结束---")
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5) {
            print("AVAudioPlayer - 播放开始---")
            guard self.player != nil  else{
                return
            }
            self.avPlaySound()
        }
    }
}
// MARK: - 获取文件的名字
extension ViewController {
    
    func fileName() -> String {
        let number = arc4random_uniform(60)
        var fileName = ""
        switch number {
        case 0...9:
            fileName = "diSound.wav"
        case 10...19:
            fileName = "diSound.wav"
        case 20...29:
            fileName = "diSound.wav"
        case 30...39:
            fileName = "diSound.wav"
        case 40...49:
            fileName = "diSound.wav"
        case 50...59:
            fileName = "diSound.wav"
        default:
            fileName = "diSound.wav"
        }
        return fileName
    }
    
}
extension ViewController {
    fileprivate func createRecord() {
        var files =  LRSoundSourceManger.obtainFileName()
        // 第一次取得时候应该是空的
        if files == nil {
            print("新建文件")
            files = [String]()
        }
        let document = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last! as NSString;
        let fileName = recordFileName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
        let path = document.appendingPathComponent("\(fileName!).caf")
        let url = URL(string: path)
        
        // 录音格式
        var recordSettings = [String : Any]()
        // 编码格式
        recordSettings[AVFormatIDKey] = kAudioFormatLinearPCM
        // 采样率
        recordSettings[AVSampleRateKey] = 8000.0
        // 通道数
        recordSettings[AVNumberOfChannelsKey] = 1
        // 采样的位数
        recordSettings[AVLinearPCMBitDepthKey] = 16
        // 音频质量,采样质量
        // 这个设置完成后就会:prepareToRecord:准备失败;record:开始录音失败
        recorder = try! AVAudioRecorder(url: url!, settings: recordSettings)
        recorder.isMeteringEnabled = true
        // 这个设置不加的话,record方法返回false
        try! AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.record)
        if recorder.prepareToRecord() {
            print("准备录音。。。")
            if self.recorder.record() {
                print("开始录音。。。")
            }
        }
    }
    // 保存录音文件
    fileprivate func saveRecord() {
        print("录音结束。。。")
        LRSoundSourceManger.saveFileName(recordFileName)
        self.recorder.stop()
    }
}
上一篇:iOS15屏幕适配


下一篇:iOS15的状态栏高度获取