简体   繁体   中英

Swift - Sample - How to play beep sound before and after recording using AVAudioRecorder?

I want to implement similar record button like Whatsapp in iOS using Swift, where when user holds the button down, a beep sound indicates start, after which recording starts and when user releases the button, recording stops and another beep sound indicates recording finished.

I tried implementing this feature using the following code:

func startRecording(sender: UIDataButton?, callData: NSDictionary?) -> Bool {
    do {
        if (self.audioRecorder == nil) {

            AudioServicesPlayAlertSound(1110) // JBL_Begin

            self.audioSession = AVAudioSession.sharedInstance()
            try self.audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: .MixWithOthers)
            try self.audioSession.setMode(AVAudioSessionModeVoiceChat)
            try self.audioSession.setActive(true)

            if (sender != nil) {
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    sender!.setTitle("Recording...", forState: .Normal)
                })
            }

            try self.audioRecorder = AVDataAudioRecorder(URL: self.fileURL("\(CurrentTimestamp)_aud.mp4")!,
                settings: self.recordSettings)

            if (sender != nil) {
                self.audioRecorder.setRecorderSender(sender!)
            }
            if (callData != nil) {
                self.audioRecorder.setRecorderData(callData!)
            }

            self.audioRecorder.delegate = self

            if (self.audioRecorder.prepareToRecord()) {
                if (self.audioRecorder.record()) {
                    NSLog("audioRecorder started recording")
                    return true
                } else {
                    self.audioRecorder = nil
                    NSLog("audioRecorder not started")
                    return false
                }
            } else {
                NSLog("audioRecorder failed to prepare")
                return false
            }

        }
    } catch let error as NSError {
        print("Error \(error.debugDescription)")
        if (self.audioRecorder != nil) {
            self.audioRecorder.stop()
            self.audioRecorder = nil
        }
        return false
    }

    return false
}

func finishRecording(sender: UIDataButton?) -> AVDataAudioRecorder? {

    var recorder: AVDataAudioRecorder? = nil

    if self.audioRecorder != nil {

        self.audioRecorder.stop()
        NSLog("audioRecorder stopped recording")
        recorder = self.audioRecorder

        AudioServicesPlayAlertSound(1111) // JBL_End

        self.audioRecorder = nil

        do {
            try self.audioSession.setActive(false)
        } catch let error as NSError {
            print("Error - AudioSession setActive False failed -  \(error.debugDescription)")
        }


        if (sender != nil) {
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                sender!.setTitle("Push-to-Talk", forState: .Normal)
            })
        }
    }

But the problem is that the JBL_Begin alert sound never plays.

Also, when I try to playback the recorded audio after recording, the volume of the audio is very low. Here is my code:

func pressAudioControl(sender: UIButton!) {
    if audioPlayer.playing {
        audioPlayer.pause()
        self.imageView.image = UIImage(named: "MessagePlay")
    } else {
        do {
            self.audioSession = AVAudioSession.sharedInstance()
            try self.audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: .DefaultToSpeaker)
            try self.audioSession.setActive(true)
            self.audioPlayer.volume = 1.0
            audioPlayer.play()
            self.imageView.image = UIImage(named: "MessagePause")

        } catch let error as NSError {
            print("audioPlayer error \(error.debugDescription)")
        }
    }
}

Any idea why this problem occurs?

This is due to your AVAudioSession being active when you attempt to play your system sound. You need to play your system sound with completion, then set it to true and begin recording.

AudioServicesPlaySystemSoundWithCompletion(SystemSoundID(1110)) {
    //Recording method here
}

Inside the completion block is where you will run you recording method including:

try self.audioSession.setActive(true)

Then before playing your ending system sound make sure to set it back to false.

try self.audioSession.setActive(false)

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