在AVAudioRecorder Session

时间:2017-09-19 10:05:44

标签: ios swift avaudiorecorder

用户停止拍摄后,如何停止录音? 像Siri一样。一旦你说,嗨Siri它会响应你的声音。意味着Siri app听取音频直到你停止拍摄。

我正在尝试做同样的事情。如果我说,获取天气详情一旦我停止发声。我想触发一个方法或用录制的音频调用API直到停止。

我的要求是app应该不断听取用户发现语音结束事件发送数据到服务器或只是触发方法。

代码:

import UIKit
import CoreAudio
import CoreAudioKit
import AVFoundation
import Foundation
import AVKit



class ViewController: UIViewController, AVAudioRecorderDelegate {

    private var recorder    : AVAudioRecorder? = nil
    private var isRecording : Bool = false
    private var timer       : Timer? = nil

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        permissionWasGranted { (isValied) in
            print("isValied")
            self.isRecording = false;
            self.intiateTimer()

        }
    }

    @objc func intiateTimer() {
        self.timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.updateTimer), userInfo: nil, repeats: true)

    }
    @objc func updateTimer() {

        if !isRecording {
            //recorder = nil
            self.initRecorder()
            print("Recording intiated")
        }
        else {
            print("Recording Started")
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func getDocumentsDirectory() -> URL {
        let fileManager         = FileManager.default
        let urls                = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
        let documentDirectory   = urls.first!
        return documentDirectory.appendingPathComponent("recording.m4a")
    }

    // MARK: protocol


    func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
        recorder.stop()
        recorder.deleteRecording()
        recorder.prepareToRecord()
        isRecording = false
        self.updateTimer()
    }


    func permissionWasGranted(result: @escaping (_: Bool)->()) {
        switch AVAudioSession.sharedInstance().recordPermission() {
        case AVAudioSessionRecordPermission.granted:
            //if IS_DEBUG { print("Permission granted") }
            print("Permission granted")

            result(true)
            return
        case AVAudioSessionRecordPermission.denied:
            //if IS_DEBUG { print("Pemission denied") }
                print("Pemission denied")
        case AVAudioSessionRecordPermission.undetermined:
            //if IS_DEBUG { print("Request permission here") }
            print("Request permission here")

            AVAudioSession.sharedInstance().requestRecordPermission({ (granted) in
                if granted {
                    result(true)
                    return
                }
            })

        }
        result(false)
    }

    func initRecorder() {
        let settings = [
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
            AVSampleRateKey: 12000,
            AVNumberOfChannelsKey: 1,
            AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
        ]
        do {
            let session = AVAudioSession.sharedInstance()
            try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
            try session.overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)
            try session.setActive(true)

            try recorder = AVAudioRecorder(url: getDocumentsDirectory(), settings: settings)
            recorder!.delegate = self
            recorder!.isMeteringEnabled = true

            if !recorder!.prepareToRecord() {
                print("Error: AVAudioRecorder prepareToRecord failed")
            }


            let decibels = self.getDispersyPercent()
            if decibels > -120  && decibels < -20 {
                self.timer?.invalidate()
                isRecording = true;
                self.start()
            }


        } catch {
            print("Error: AVAudioRecorder creation failed")
        }
    }

    func start() {
        recorder?.record()
        recorder?.updateMeters()
    }

    func update() {
        if let recorder = recorder {
            recorder.updateMeters()
        }
    }

    func getDispersyPercent() -> Float {
        if let recorder = recorder {
            let decibels = recorder.averagePower(forChannel: 0)
            return decibels
        }
        return 0
    }

}

2 个答案:

答案 0 :(得分:2)

这里我创建了我的功能,它实际上会检测到5秒的静音,如果条件满足,你可以停止记录那段时间

- 我使用过Recording Manager NSObject类,因此您可以从下面的函数中获取代码并设法在您的代码中使用它

代码

//StartNewRecordingIfSilenceFor5Second
    func newSessionIfSilence(){

        //get Audio file name to store
        let AudioFileName = getDocumentsDirectory().appendingPathComponent("\(getUniqueName()).wav")
        //Declare a value that will be updated when silence is detected
        var statusForDetection = Float()
        //Recorder Settings used
        let settings: [String: Any] = [
            AVFormatIDKey: Int(kAudioFormatLinearPCM),
            AVSampleRateKey: 16000,
            AVNumberOfChannelsKey: 1,
            AVLinearPCMBitDepthKey: 16,
            AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue,
            AVLinearPCMIsBigEndianKey: false,
            AVLinearPCMIsFloatKey: false,
            ]
        //Try block
        do {
            //Start Recording With Audio File name
            Manager.recorder = try AVAudioRecorder(url: AudioFileName, settings: settings)
            Manager.recorder?.delegate = self
            Manager.recorder?.isMeteringEnabled = true
            Manager.recorder?.prepareToRecord()
            Manager.recorder?.record()

            //Tracking Metering values here only
            Manager.meterTimer = Timer.scheduledTimer(withTimeInterval: 0.10, repeats: true, block: { (timer: Timer) in

                //Update Recording Meter Values so we can track voice loudness
                //Getting Recorder from another class
                //i managed my recorder from Manager class
                if let recorder = Manager.recorder
                {
                    //Start Metering Updates
                    recorder.updateMeters()

                    //Get peak values
                    Manager.recorderApc0 = recorder.averagePower(forChannel: 0)
                    Manager.recorderPeak0 = recorder.peakPower(forChannel: 0)

                    //it’s converted to a 0-1 scale, where zero is complete quiet and one is full volume.
                    let ALPHA: Double = 0.05
                    let peakPowerForChannel = pow(Double(10), (0.05 * Double(Manager.recorderPeak0)))

//                    static var lowPassResults: Double = 0.0
                    RecordingManager.lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * RecordingManager.lowPassResults

                    if(RecordingManager.lowPassResults > 0){
                        print("Mic blow detected")
                        //Do what you wanted to do here

                        //if blow is detected update silence value as zero
                        statusForDetection = 0.0
                    }
                    else
                    {

                        //Update Value for Status is blow being detected or not
                        //As timer is called at interval of 0.10 i.e 0.1 So add value each time in silence Value with 0.1
                        statusForDetection += 0.1


                        //if blow is not Detected for 5 seconds
                        if statusForDetection > 5.0 {
                            //Update value to zero
                            //When value of silence is greater than 5 Seconds
                            //Time to Stop recording
                            statusForDetection = 0.0

                            //Stop Audio recording
                            recorder.stop()

                        }
                    }
                }
            })

        } catch {
            //Finish Recording with a Error
            print("Error Handling: \(error.localizedDescription)")
            self.finishRecording(success: false)
        }

    }

答案 1 :(得分:1)

您可以向录音机添加定期聆听者(开始录音后),并检查recorder.averagePower(forChannel: 0)您是否可以处理停止录音的最低等级。