Recording audio in Swift

后端 未结 8 1816
别那么骄傲
别那么骄傲 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)
      }
      

提交回复
热议问题