Recording audio in Swift

后端 未结 8 1787
别那么骄傲
别那么骄傲 2020-12-04 06:12

Does anyone know where I can find info on how to record audio in a Swift application? I\'ve been looking at some of the audio playback examples but I can\'t seem to be able

相关标签:
8条回答
  • 2020-12-04 06:49

    In Swift 3

    • Add framework AVFoundation
    • **In info.plist add key value

    Key = Privacy - Microphone Usage Description and Value = For using microphone

    (the apps will crash if you don't provide the value - description why you are asking for the permission)**

    • Import AVFoundation & AVAudioRecorderDelegate, AVAudioPlayerDelegate

      import AVFoundation
      
       class RecordVC: UIViewController , AVAudioRecorderDelegate, AVAudioPlayerDelegate
      
    • Create button for record audio & play audio , and label for display recording timing & give outlets and action as start_recording , play_recording & declare some variables which we will use later

      @IBOutlet var recordingTimeLabel: UILabel!
      @IBOutlet var record_btn_ref: UIButton!
      @IBOutlet var play_btn_ref: UIButton!
      
      var audioRecorder: AVAudioRecorder!
      var audioPlayer : AVAudioPlayer!
      var meterTimer:Timer!
      var isAudioRecordingGranted: Bool!
      var isRecording = false
      var isPlaying = false
      
    • In viewDidLoad check record permission

      override func viewDidLoad() {
          super.viewDidLoad()
          check_record_permission()
      }
      
      func check_record_permission()
      {
          switch AVAudioSession.sharedInstance().recordPermission() {
          case AVAudioSessionRecordPermission.granted:
              isAudioRecordingGranted = true
              break
          case AVAudioSessionRecordPermission.denied:
              isAudioRecordingGranted = false
              break
          case AVAudioSessionRecordPermission.undetermined:
              AVAudioSession.sharedInstance().requestRecordPermission({ (allowed) in
                      if allowed {
                          self.isAudioRecordingGranted = true
                      } else {
                          self.isAudioRecordingGranted = false
                      }
              })
              break
          default:
              break
          }
      }
      
    • generate path where you want to save that recording as myRecording.m4a

      func getDocumentsDirectory() -> URL
      {
          let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
          let documentsDirectory = paths[0]
          return documentsDirectory
      }
      
      func getFileUrl() -> URL
      {
          let filename = "myRecording.m4a"
          let filePath = getDocumentsDirectory().appendingPathComponent(filename)
      return filePath
      }
      
    • Setup the recorder

      func setup_recorder()
      {
          if isAudioRecordingGranted
          {
              let session = AVAudioSession.sharedInstance()
              do
              {
                  try session.setCategory(AVAudioSessionCategoryPlayAndRecord, with: .defaultToSpeaker)
                  try session.setActive(true)
                  let settings = [
                      AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
                      AVSampleRateKey: 44100,
                      AVNumberOfChannelsKey: 2,
                      AVEncoderAudioQualityKey:AVAudioQuality.high.rawValue
                  ]
                  audioRecorder = try AVAudioRecorder(url: getFileUrl(), settings: settings)
                  audioRecorder.delegate = self
                  audioRecorder.isMeteringEnabled = true
                  audioRecorder.prepareToRecord()
              }
              catch let error {
                  display_alert(msg_title: "Error", msg_desc: error.localizedDescription, action_title: "OK")
              }
          }
          else
          {
              display_alert(msg_title: "Error", msg_desc: "Don't have access to use your microphone.", action_title: "OK")
          }
      }
      
    • Start recording when button start_recording press & display seconds using updateAudioMeter, & if recording is start then finish the recording

      @IBAction func start_recording(_ sender: UIButton)
      {
          if(isRecording)
          {
              finishAudioRecording(success: true)
              record_btn_ref.setTitle("Record", for: .normal)
              play_btn_ref.isEnabled = true
              isRecording = false
          }
          else
          {
              setup_recorder()
      
              audioRecorder.record()
              meterTimer = Timer.scheduledTimer(timeInterval: 0.1, target:self, selector:#selector(self.updateAudioMeter(timer:)), userInfo:nil, repeats:true)
              record_btn_ref.setTitle("Stop", for: .normal)
              play_btn_ref.isEnabled = false
              isRecording = true
          }
      }
      
      func updateAudioMeter(timer: Timer)
      {
          if audioRecorder.isRecording
          {
              let hr = Int((audioRecorder.currentTime / 60) / 60)
              let min = Int(audioRecorder.currentTime / 60)
              let sec = Int(audioRecorder.currentTime.truncatingRemainder(dividingBy: 60))
              let totalTimeString = String(format: "%02d:%02d:%02d", hr, min, sec)
              recordingTimeLabel.text = totalTimeString
              audioRecorder.updateMeters()
          }
      }
      
      func finishAudioRecording(success: Bool)
      {
          if success
          {
              audioRecorder.stop()
              audioRecorder = nil
              meterTimer.invalidate()
              print("recorded successfully.")
          }
          else
          {
              display_alert(msg_title: "Error", msg_desc: "Recording failed.", action_title: "OK")
          }
      }
      
    • Play the recording

      func prepare_play()
      {
          do
          {
              audioPlayer = try AVAudioPlayer(contentsOf: getFileUrl())
              audioPlayer.delegate = self
              audioPlayer.prepareToPlay()
          }
          catch{
              print("Error")
          }
      }
      
      @IBAction func play_recording(_ sender: Any)
      {
          if(isPlaying)
          {
              audioPlayer.stop()
              record_btn_ref.isEnabled = true
              play_btn_ref.setTitle("Play", for: .normal)
              isPlaying = false
          }
          else
          {
              if FileManager.default.fileExists(atPath: getFileUrl().path)
              {
                  record_btn_ref.isEnabled = false
                  play_btn_ref.setTitle("pause", for: .normal)
                  prepare_play()
                  audioPlayer.play()
                  isPlaying = true
              }
              else
              {
                  display_alert(msg_title: "Error", msg_desc: "Audio file is missing.", action_title: "OK")
              }
          }
      }
      
    • When recording is finish enable the play button & when play is finish enable the record button

      func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool)
      {
          if !flag
          {
              finishAudioRecording(success: false)
          }
          play_btn_ref.isEnabled = true
      }
      
      func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool)
      {
          record_btn_ref.isEnabled = true
      }
      
    • Generalize function for display alert

      func display_alert(msg_title : String , msg_desc : String ,action_title : String)
      {
          let ac = UIAlertController(title: msg_title, message: msg_desc, preferredStyle: .alert)
          ac.addAction(UIAlertAction(title: action_title, style: .default)
          {
              (result : UIAlertAction) -> Void in
          _ = self.navigationController?.popViewController(animated: true)
          })
          present(ac, animated: true)
      }
      
    0 讨论(0)
  • 2020-12-04 06:49

    Swift 3 Code Version: Complete Solution for Audio Recording!

    import UIKit
    import AVFoundation
    
    class ViewController: UIViewController, AVAudioRecorderDelegate {
    
        //Outlets
        @IBOutlet weak var recordingTimeLabel: UILabel!
    
        //Variables
        var audioRecorder: AVAudioRecorder!
        var meterTimer:Timer!
        var isAudioRecordingGranted: Bool!
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            switch AVAudioSession.sharedInstance().recordPermission() {
            case AVAudioSessionRecordPermission.granted:
                isAudioRecordingGranted = true
                break
            case AVAudioSessionRecordPermission.denied:
                isAudioRecordingGranted = false
                break
            case AVAudioSessionRecordPermission.undetermined:
                AVAudioSession.sharedInstance().requestRecordPermission() { [unowned self] allowed in
                    DispatchQueue.main.async {
                        if allowed {
                            self.isAudioRecordingGranted = true
                        } else {
                            self.isAudioRecordingGranted = false
                        }
                    }
                }
                break
            default:
                break
            }
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
    
            audioRecorder = nil
        }
    
        //MARK:- Audio recorder buttons action.
        @IBAction func audioRecorderAction(_ sender: UIButton) {
    
            if isAudioRecordingGranted {
    
                //Create the session.
                let session = AVAudioSession.sharedInstance()
    
                do {
                    //Configure the session for recording and playback.
                    try session.setCategory(AVAudioSessionCategoryPlayAndRecord, with: .defaultToSpeaker)
                    try session.setActive(true)
                    //Set up a high-quality recording session.
                    let settings = [
                        AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
                        AVSampleRateKey: 44100,
                        AVNumberOfChannelsKey: 2,
                        AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
                    ]
                    //Create audio file name URL
                    let audioFilename = getDocumentsDirectory().appendingPathComponent("audioRecording.m4a")
                    //Create the audio recording, and assign ourselves as the delegate
                    audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
                    audioRecorder.delegate = self
                    audioRecorder.isMeteringEnabled = true
                    audioRecorder.record()
                    meterTimer = Timer.scheduledTimer(timeInterval: 0.1, target:self, selector:#selector(self.updateAudioMeter(timer:)), userInfo:nil, repeats:true)
                }
                catch let error {
                    print("Error for start audio recording: \(error.localizedDescription)")
                }
            }
        }
    
        @IBAction func stopAudioRecordingAction(_ sender: UIButton) {
    
            finishAudioRecording(success: true)
    
        }
    
        func finishAudioRecording(success: Bool) {
    
            audioRecorder.stop()
            audioRecorder = nil
            meterTimer.invalidate()
    
            if success {
                print("Recording finished successfully.")
            } else {
                print("Recording failed :(")
            }
        }
    
        func updateAudioMeter(timer: Timer) {
    
            if audioRecorder.isRecording {
                let hr = Int((audioRecorder.currentTime / 60) / 60)
                let min = Int(audioRecorder.currentTime / 60)
                let sec = Int(audioRecorder.currentTime.truncatingRemainder(dividingBy: 60))
                let totalTimeString = String(format: "%02d:%02d:%02d", hr, min, sec)
                recordingTimeLabel.text = totalTimeString
                audioRecorder.updateMeters()
            }
        }
    
        func getDocumentsDirectory() -> URL {
    
            let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
            let documentsDirectory = paths[0]
            return documentsDirectory
        }
    
        //MARK:- Audio recoder delegate methods
        func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
    
            if !flag {
                finishAudioRecording(success: false)
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-04 06:52

    Code in Class file Using Swift 4

    Class is AGAudioRecorder

    Code is

    class AudioRecordViewController: UIViewController {
    
        @IBOutlet weak var recodeBtn: UIButton!
        @IBOutlet weak var playBtn: UIButton!
    
        var state: AGAudioRecorderState = .Ready
    
        var recorder: AGAudioRecorder = AGAudioRecorder(withFileName: "TempFile")
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            recodeBtn.setTitle("Recode", for: .normal)
            playBtn.setTitle("Play", for: .normal)
            recorder.delegate = self
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    
        @IBAction func recode(_ sender: UIButton) {
            recorder.doRecord()
        }
    
        @IBAction func play(_ sender: UIButton) {
            recorder.doPlay()
        }
    }
    
    extension AudioRecordViewController: AGAudioRecorderDelegate {
        func agAudioRecorder(_ recorder: AGAudioRecorder, withStates state: AGAudioRecorderState) {
            switch state {
            case .error(let e): debugPrint(e)
            case .Failed(let s): debugPrint(s)
    
            case .Finish:
                recodeBtn.setTitle("Recode", for: .normal)
    
            case .Recording:
                recodeBtn.setTitle("Recoding Finished", for: .normal)
    
            case .Pause:
                playBtn.setTitle("Pause", for: .normal)
    
            case .Play:
                playBtn.setTitle("Play", for: .normal)
    
            case .Ready:
                recodeBtn.setTitle("Recode", for: .normal)
                playBtn.setTitle("Play", for: .normal)
                refreshBtn.setTitle("Refresh", for: .normal)
            }
            debugPrint(state)
        }
    
        func agAudioRecorder(_ recorder: AGAudioRecorder, currentTime timeInterval: TimeInterval, formattedString: String) {
            debugPrint(formattedString)
        }
    }
    
    0 讨论(0)
  • 2020-12-04 06:55

    Swift2 version of @codester's answer.

    func record() {
        //init
        let audioSession:AVAudioSession = AVAudioSession.sharedInstance()
    
        //ask for permission
        if (audioSession.respondsToSelector("requestRecordPermission:")) {
            AVAudioSession.sharedInstance().requestRecordPermission({(granted: Bool)-> Void in
                if granted {
                    print("granted")
    
                    //set category and activate recorder session
                    try! audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
                    try! audioSession.setActive(true)
    
    
                    //get documnets directory
                    let documentsDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
                    let fullPath = documentsDirectory.stringByAppendingPathComponent("voiceRecording.caf")
                    let url = NSURL.fileURLWithPath(fullPath)
    
                    //create AnyObject of settings
                    let settings: [String : AnyObject] = [
                        AVFormatIDKey:Int(kAudioFormatAppleIMA4), //Int required in Swift2
                        AVSampleRateKey:44100.0,
                        AVNumberOfChannelsKey:2,
                        AVEncoderBitRateKey:12800,
                        AVLinearPCMBitDepthKey:16,
                        AVEncoderAudioQualityKey:AVAudioQuality.Max.rawValue
                    ]
    
                    //record
                    try! self.audioRecorder = AVAudioRecorder(URL: url, settings: settings)
    
                } else{
                    print("not granted")
                }
            })
        }
    
    }
    
    0 讨论(0)
  • 2020-12-04 06:58

    Here is code.You can record easily.Write this code on IBAction.It will save the recording in Documents by name recordTest.caf

    //declare instance variable 
    var audioRecorder:AVAudioRecorder!
    func record(){        
        var audioSession:AVAudioSession = AVAudioSession.sharedInstance()
        audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, error: nil)
        audioSession.setActive(true, error: nil)
    
        var documents: AnyObject = NSSearchPathForDirectoriesInDomains( NSSearchPathDirectory.DocumentDirectory,  NSSearchPathDomainMask.UserDomainMask, true)[0]
        var str =  documents.stringByAppendingPathComponent("recordTest.caf")
        var url = NSURL.fileURLWithPath(str as String)
    
        var recordSettings = [AVFormatIDKey:kAudioFormatAppleIMA4,
            AVSampleRateKey:44100.0,
            AVNumberOfChannelsKey:2,AVEncoderBitRateKey:12800,
            AVLinearPCMBitDepthKey:16,
            AVEncoderAudioQualityKey:AVAudioQuality.Max.rawValue]
    
        println("url : \(url)")
        var error: NSError?
    
        audioRecorder = AVAudioRecorder(URL:url, settings: recordSettings, error: &error)
        if let e = error {
            println(e.localizedDescription)
        } else {
            audioRecorder.record()
        }        
    }
    
    0 讨论(0)
  • 2020-12-04 06:59

    For Swift 5,

     func setup_recorder()
    {
        if isAudioRecordingGranted
        {
            let session = AVAudioSession.sharedInstance()
            do
            {
                try session.setCategory(.playAndRecord, mode: .default)
                try session.setActive(true)
                let settings = [
                    AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
                    AVSampleRateKey: 44100,
                    AVNumberOfChannelsKey: 2,
                    AVEncoderAudioQualityKey:AVAudioQuality.high.rawValue
                ]
                audioRecorder = try AVAudioRecorder(url: getFileUrl(), settings: settings)
                audioRecorder.delegate = self
                audioRecorder.isMeteringEnabled = true
                audioRecorder.prepareToRecord()
            }
            catch let error {
                display_alert(msg_title: "Error", msg_desc: error.localizedDescription, action_title: "OK")
            }
        }
        else
        {
            display_alert(msg_title: "Error", msg_desc: "Don't have access to use your microphone.", action_title: "OK")
        }
    
    0 讨论(0)
提交回复
热议问题