簡體   English   中英

在AVAudioRecorder Session中找到沉默

[英]Find silence in AVAudioRecorder Session

一旦用戶停止播放,我該如何停止錄音? 像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
    }

}

在這里我創建了我的功能,它實際上會檢測到靜音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)
        }

    }

您可以向錄像機添加定期監聽器(開始錄像后),並檢查recorder.averagePower(forChannel: 0)您可以處理停止錄像的最低級別。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM