-->

Record And Play Voice in Separate Class (Swift3)

2019-06-01 04:55发布

问题:

I used many codes that was for record an play the voice, but most of them are not in swift3 and they don't work in my app.

This code works, but I want to create a separate class from the viewcontroller that do recording an playing voices. Also the mentioned github code is complex an I'm searching for a simplified code.

Update:

After recording, when I check existence of the recorded file, the file doesn't exist, and it raises EXC_BAD_ACCESS error on appDelegate.

What's wrong?

Any suggestions would be appreciated.

回答1:

Try to record audio by wirting line

let isRec = AudioManager.shared.record(fileName: "rec")

if isRec returned true then recording is happening else not. To finish recording use : let recordedURL = AudioManager.shared.finishRecording()

To play recorded file send above url to setupUpPlayer() function in manager class

Not to forget to use extension code snippets give below the code snippet which are delegate functions of AVAudioRecorder and AVAudioPlayer

import Foundation

import AVFoundation

class AudioManager: NSObject {

static let shared = AudioManager()

var recordingSession: AVAudioSession?
var recorder: AVAudioRecorder?
var meterTimer: Timer?
var recorderApc0: Float = 0
var recorderPeak0: Float = 0
//PLayer
var player: AVAudioPlayer?
var savedFileURL: URL?

func setup() {
    recordingSession = AVAudioSession.sharedInstance()
    do {
        try recordingSession?.setCategory(AVAudioSessionCategoryPlayAndRecord, with: .defaultToSpeaker)
        try recordingSession?.setActive(true)
        recordingSession?.requestRecordPermission({ (allowed) in
            if allowed {
                print("Mic Authorised")
            } else {
                print("Mic not Authorised")
            }
        })
    } catch {
        print("Failed to set Category", error.localizedDescription)
    }
}

func record(fileName: String) -> Bool {
    setup()
    let url = getUserPath().appendingPathComponent(fileName + ".m4a")
    let audioURL = URL.init(fileURLWithPath: url.path)
    let recordSettings: [String: Any] = [AVFormatIDKey: kAudioFormatMPEG4AAC,
                                         AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue,
                                         AVNumberOfChannelsKey: 2,
                                         AVSampleRateKey: 44100.0]
    do {
        recorder = try AVAudioRecorder.init(url: audioURL, settings: recordSettings)
        recorder?.delegate = self
        recorder?.isMeteringEnabled = true
        recorder?.prepareToRecord()
        recorder?.record()
        self.meterTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { (timer: Timer) in
            //Update Recording Meter Values so we can track voice loudness
            if let recorder = self.recorder {
                recorder.updateMeters()
                self.recorderApc0 = recorder.averagePower(forChannel: 0)
                self.recorderPeak0 = recorder.peakPower(forChannel: 0)
            }
        })
        savedFileURL = url
        print("Recording")
        return true
    } catch {
        print("Error Handling", error.localizedDescription)
        return false
    }
}

func getUserPath() -> URL {
    return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
}

func finishRecording() -> String {
    recorder?.stop()
    self.meterTimer?.invalidate()
    var fileURL: String?
    if let url: URL = recorder?.url {
        fileURL = String(describing: url)
    }
    return /fileURL
}
//Player
func setupPlayer(_ url: URL) {
    do {
        try player = AVAudioPlayer.init(contentsOf: url)
    } catch {
        print("Error1", error.localizedDescription)
    }
    player?.prepareToPlay()
    player?.play()
    player?.volume = 1.0
    player?.delegate = self
}
}

    //MARK:- Audio Recorder Delegate

    extension AudioManager: AVAudioRecorderDelegate {

    func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {

        print("AudioManager Finish Recording")

    }
    func audioRecorderEncodeErrorDidOccur(_ recorder: AVAudioRecorder, error: Error?) {
        print("Encoding Error", /error?.localizedDescription)
    }

}

    //MARK:- Audio Player Delegates

    extension AudioManager: AVAudioPlayerDelegate {

       func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, 
   successfully flag: Bool) {

           player.stop()

           print("Finish Playing")

       }

       func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, 
    error: Error?) {

            print(/error?.localizedDescription)

        }

    }