简体   繁体   中英

Swift: play the audio recorded

I tried to record and I could find a good answer here: Recording audio in Swift

I could make it work. But now I would like to know how to play the recorded audio. From the recording I already have the general var audioRecorder, and defined the url path. So I tried audioRecorder.play() but it does not work.

I suppose that the problem comes form the fact that the global var audioRecorder is an instance of AVAudioRecorder and to play it should it be an instance of AVAudioPlayer?, how this two things are related?

I do not want to copy paste a peace of code I would like to understand. This is why I simplify the code here. Please explain why it does not work in this specific code and how to solve it.

(I have done a lot of tutorials related. The problem is that there is so much code I get lost. My question here is to understand how this specific part works)

import AVFoundation
var audioRecorder:AVAudioRecorder!
@IBAction func record(sender: AnyObject) {       
    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)
    println(url)

    audioRecorder = AVAudioRecorder(URL:url, settings: nil, error: nil)
    audioRecorder.record()
}

@IBAction func play(sender: AnyObject) {
   // this gives the error 'AVAudioRecorder' does not have a member named 'play'
   // audioRecorder.play() 
}

Here is the complete working code for record audio then store it to file then play it:

import UIKit
import AVFoundation

class ViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {

    @IBOutlet weak var recordButton: UIButton!
    @IBOutlet weak var stopButton: UIButton!
    @IBOutlet weak var playButton: UIButton!
    
    var audioPlayer : AVAudioPlayer?
    var audioRecorder : AVAudioRecorder?
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        playButton.enabled = false
        stopButton.enabled = false
        
        // getting URL path for audio
        let dirPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
        let docDir = dirPath[0] as! String
        let soundFilePath = docDir.stringByAppendingPathComponent("sound.caf")
        let soundFileURL = NSURL(fileURLWithPath: soundFilePath)
        println(soundFilePath)
        
        //Setting for recorder
        let recordSettings = [AVEncoderAudioQualityKey: AVAudioQuality.Min.rawValue,
            AVEncoderBitRateKey: 16,
            AVNumberOfChannelsKey : 2,
            AVSampleRateKey: 44100.0]
        var error : NSError?
        let audioSession = AVAudioSession.sharedInstance()
        audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, error: &error)
        if let err = error{
            println("audioSession error: \(err.localizedDescription)")
        }
        audioRecorder = AVAudioRecorder(URL: soundFileURL, settings: recordSettings as [NSObject : AnyObject], error: &error)
        
        if let err = error{
            println("audioSession error: \(err.localizedDescription)")
        }else{
            audioRecorder?.prepareToRecord()
        }
    }
    //record audio
    @IBAction func recordAudio(sender: AnyObject) {
        
        if audioRecorder?.recording == false{
            playButton.enabled = false
            stopButton.enabled = true
            audioRecorder?.record()
        }
    }
    //stop recording audio
    @IBAction func stopAudio(sender: AnyObject) {
        
        stopButton.enabled = false
        playButton.enabled = true
        recordButton.enabled = true
        
        if audioRecorder?.recording == true{
            audioRecorder?.stop()
        }else{
            audioPlayer?.stop()
        }
    }
    //play your recorded audio
    @IBAction func playAudio(sender: AnyObject) {
        
        if audioRecorder?.recording == false{
            stopButton.enabled = true
            recordButton.enabled = false
            
            var error : NSError?
            
            audioPlayer = AVAudioPlayer(contentsOfURL: audioRecorder?.url, error: &error)
            
            audioPlayer?.delegate = self
            
            if let err = error{
                println("audioPlayer error: \(err.localizedDescription)")
            }else{
                audioPlayer?.play()
            }
        }
    }
    
    func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) {
        recordButton.enabled = true
        stopButton.enabled = false
    }
    
    func audioPlayerDecodeErrorDidOccur(player: AVAudioPlayer!, error: NSError!) {
        println("Audio Play Decode Error")
    }
    
    func audioRecorderDidFinishRecording(recorder: AVAudioRecorder!, successfully flag: Bool) {
    }
    
    func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder!, error: NSError!) {
        println("Audio Record Encode Error")
    }
}

Check THIS sample project for more Info.

In your code audioRecorder is used for record audio and audioPlayer is used for play audio. Thats why audioRecorder doesn't have property play()

So you can not use audioRecorder.play() .

Here is the answer by @DharmeshKheni + updated for swift 4.0 Create three buttons and add outlets and methods to them.

New version

import UIKit
import AVFoundation

class ViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {

@IBOutlet weak var recordButton: UIButton!
@IBOutlet weak var stopButton: UIButton!
@IBOutlet weak var playButton: UIButton!

var audioPlayer : AVAudioPlayer?
var audioRecorder : AVAudioRecorder?


override func viewDidLoad() {
    super.viewDidLoad()
    playButton.isEnabled = false
    stopButton.isEnabled = false

    // getting URL path for audio
    let dirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
    let docDir = dirPath[0]
    let soundFilePath = (docDir as NSString).appendingPathComponent("sound.caf")
    let soundFileURL = NSURL(fileURLWithPath: soundFilePath)
    print(soundFilePath)

    //Setting for recorder
    let recordSettings = [AVEncoderAudioQualityKey: AVAudioQuality.min.rawValue,
        AVEncoderBitRateKey: 16,
        AVNumberOfChannelsKey : 2,
        AVSampleRateKey: 44100.0] as [String : Any] as [String : Any] as [String : Any] as [String : Any]
    var error : NSError?
    let audioSession = AVAudioSession.sharedInstance()
    do {
        try audioSession.setCategory(AVAudioSession.Category.playAndRecord)
        audioRecorder = try AVAudioRecorder(url: soundFileURL as URL, settings: recordSettings as [String : AnyObject])
    } catch _ {
        print("Error")
    }

    if let err = error {
        print("audioSession error: \(err.localizedDescription)")
    }else{
        audioRecorder?.prepareToRecord()
    }
}
//record audio
@IBAction func recordAudio(sender: AnyObject) {

    if audioRecorder?.isRecording == false{
        playButton.isEnabled = false
        stopButton.isEnabled = true
        audioRecorder?.record()
    }
}
//stop recording audio
@IBAction func stopAudio(sender: AnyObject) {

    stopButton.isEnabled = false
    playButton.isEnabled = true
    recordButton.isEnabled = true

    if audioRecorder?.isRecording == true{
        audioRecorder?.stop()
    }else{
        audioPlayer?.stop()
    }
}
//play your recorded audio
@IBAction func playAudio(sender: AnyObject) {

    if audioRecorder?.isRecording == false{
        stopButton.isEnabled = true
        recordButton.isEnabled = false

        var error : NSError?
        do {
            let player = try AVAudioPlayer(contentsOf: audioRecorder!.url)
             audioPlayer = player
         } catch {
             print(error)
         }

        audioPlayer?.delegate = self

        if let err = error{
            print("audioPlayer error: \(err.localizedDescription)")
        }else{
            audioPlayer?.play()
        }
    }
}

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
    recordButton.isEnabled = true
    stopButton.isEnabled = false
}

private func audioPlayerDecodeErrorDidOccur(player: AVAudioPlayer!, error: NSError!) {
    print("Audio Play Decode Error")
}

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

private func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder!, error: NSError!) {
    print("Audio Record Encode Error")
}

}

Old version

import UIKit
import AVFoundation

class PlayVC: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {

    @IBOutlet weak var recordButton: UIButton!
    @IBOutlet weak var stopButton: UIButton!
    @IBOutlet weak var playButton: UIButton!

    var audioPlayer : AVAudioPlayer?
    var audioRecorder : AVAudioRecorder?


    override func viewDidLoad() {
        super.viewDidLoad()
        playButton.isEnabled = false
        stopButton.isEnabled = false

        // getting URL path for audio
        let dirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
        let docDir = dirPath[0] as! String
        let soundFilePath = docDir.stringByAppendingPathComponent(path: "sound.caf")
        let soundFileURL = NSURL(fileURLWithPath: soundFilePath)
        print(soundFilePath)

        //Setting for recorder
        let recordSettings = [AVEncoderAudioQualityKey: AVAudioQuality.min.rawValue,
                              AVEncoderBitRateKey: 16,
                              AVNumberOfChannelsKey : 2,
                              AVSampleRateKey: 44100.0] as [String : Any]
        var error : NSError?
        let audioSession = AVAudioSession.sharedInstance()

        do {
            try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
        } catch {
            print(error)
        }
        if let err = error{
            print("audioSession error: \(err.localizedDescription)")
        }
        do {
            audioRecorder = try AVAudioRecorder(url: soundFileURL as URL, settings: recordSettings as [String : Any])
        } catch {
            print(error)
        }


        if let err = error{
            print("audioSession error: \(err.localizedDescription)")
        }else{
            audioRecorder?.prepareToRecord()
        }
    }
    //record audio
    @IBAction func recordAudio(sender: AnyObject) {

        if audioRecorder?.isRecording == false{
            playButton.isEnabled = false
            stopButton.isEnabled = true
            audioRecorder?.record()
        }
    }
    //stop recording audio
    @IBAction func stopAudio(sender: AnyObject) {

        stopButton.isEnabled = false
        playButton.isEnabled = true
        recordButton.isEnabled = true

        if audioRecorder?.isRecording == true{
            audioRecorder?.stop()
        }else{
            audioPlayer?.stop()
        }
    }
    //play your recorded audio
    @IBAction func playAudio(sender: AnyObject) {

        if audioRecorder?.isRecording == false{
            stopButton.isEnabled = true
            recordButton.isEnabled = false

            var error : NSError?

            do {

                audioPlayer = try AVAudioPlayer(contentsOf: (audioRecorder?.url)!)
            } catch {
                print(error)
            }

            audioPlayer?.delegate = self

            if let err = error{
                print("audioPlayer error: \(err.localizedDescription)")
            }else{
                audioPlayer?.play()
            }
        }
    }

    func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) {
        recordButton.isEnabled = true
        stopButton.isEnabled = false
    }

    func audioPlayerDecodeErrorDidOccur(player: AVAudioPlayer!, error: NSError!) {
        print("Audio Play Decode Error")
    }

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

    func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder!, error: NSError!) {
        print("Audio Record Encode Error")
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM