Search code examples
iosswiftaudioavaudioplayeravaudiorecorder

AVAudioPlayer not playing audio correctly the first time


I am working on a project that has to play audio that the user recorded themselves. When the app is launched for the first time and the user records a bit of audio, when trying to play it back, the AVAudioPlayer seems to play but is immediately stopped. If the user try to record another bit of audio, the AVAudioPlayer works fine.

Code for playing and stopping audio:

@objc func playAudio() {
    if audioPlayer == nil {
        do{
            if FileManager.default.fileExists(atPath: filename.path) {
                print("File Exists")
            }
            else {
                print("File Doesnt Exists")
            }

            try audioPlayer = AVAudioPlayer(contentsOf: filename)
            audioPlayer.delegate = self
            audioPlayer.prepareToPlay()
            audioPlayer.play()
            print(audioPlayer.isPlaying)
            print("Playing Audio")
            playStopButton.setImage(#imageLiteral(resourceName: "Stop Button"), for: .normal)
        }catch {
            //displayAlert(title: "Oops!", message: "There was an error. Try Recording Again")
            print(error)
        }
    }
    else {
        playStopButton.setImage(#imageLiteral(resourceName: "Play Button"), for: .normal)
        audioPlayer.stop()
        audioPlayer = nil
    }
}

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
    if flag {
        print("Stopping Cuase Comlete")
        playStopButton.setImage(#imageLiteral(resourceName: "Play Button"), for: .normal)
        audioPlayer.stop()
        audioPlayer = nil
    }
}

Code For Recording Audio

@objc func record() {

    if audioRecorder == nil{

        let settings = [AVFormatIDKey: Int(kAudioFormatMPEG4AAC), AVSampleRateKey: 12000, AVNumberOfChannelsKey:1, AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue]

        do{
            audioRecorder = try AVAudioRecorder(url: filename, settings: settings)
            audioRecorder.delegate = self
            audioRecorder.record()
            //view.backgroundColor = UIColor.red
            //recordButton.setTitle("Stop Recording", for: .normal)
            setupTimer()
            timerDisplay.isHidden = false
            shapeLayer.fillColor = UIColor.black.cgColor

        }catch{
            displayAlert(title: "Oops!", message: "Recording Failed")
        }
    }
    else{
        audioRecorder.stop()
        timer?.invalidate()
        timer = nil
        shapeLayer.strokeEnd = 0
        audioRecorder=nil;

        timerDisplay.isHidden = true
        shapeLayer.fillColor = UIColor.red.cgColor
        let selected = arr[picker.selectedRow(inComponent: 0)]
        UserDefaults.standard.set(selected, forKey: "SelectedTopic")

        present(UINavigationController(rootViewController: PlaybackController()), animated: true, completion: nil)
    }
}

Solution

  • getting same issue with audiorecorder.I fixed by making a method to setup a player. like this:

    func setupView() {
            recordingSession = AVAudioSession.sharedInstance()
    
            do {
                try recordingSession.setCategory(.playAndRecord, mode: .default)
                try recordingSession.setActive(true)
                recordingSession.requestRecordPermission() { [unowned self] allowed in
                    DispatchQueue.main.async {
                        if allowed {
                            self.loadRecordingUI()
                        } else {
                            // failed to record
                        }
                    }
                }
            } catch {
                // failed to record
            }
        }
    

    and then calling it in my viewDidLoad.as:

    self.setupView()