【问题标题】:Swift 4 AVFoundation - Recording multiple audio sources simultaneouslySwift 4 AVFoundation - 同时录制多个音频源
【发布时间】:2017-10-15 16:14:15
【问题描述】:

我目前正在尝试同时监控 iPhone 的每个内置麦克风的音频输入。

在下面提到的代码中,我选择了我想用这行代码监控/测量的麦克风(底部、前置或后置麦克风):

try recordingSession.setInputDataSource(recordingSession.inputDataSources?[2])

不幸的是,我似乎只能为我的音频会话设置一个输入数据源。

也许有办法为每个记录通道设置一个输入数据源?

我也曾尝试探索其他解决方案,例如 AVAudioEngine,但由于有关此主题的 Swift 资源并不多,因此我很难分析走哪条路。

import UIKit
import AVFoundation

        class ViewController: UIViewController, AVAudioRecorderDelegate, AVAudioPlayerDelegate {

            @IBOutlet var recordButton: UIButton!
            var recordingSession: AVAudioSession!
            var audioPlayer: AVAudioPlayer!
            var audioRecorder: AVAudioRecorder!

            var timer: Timer!

            override func viewDidLoad() {
                recordingSession = AVAudioSession.sharedInstance()

                do {
                    try recordingSession.setCategory(AVAudioSessionCategoryMultiRoute)
                    //try recordingSession.setMode(AVAudioSessionModeMeasurement)
                    try recordingSession.setActive(true)


                    try recordingSession.setInputDataSource(recordingSession.inputDataSources?[2])
                    try recordingSession.overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)
                    recordingSession.requestRecordPermission() { [unowned self] allowed in
                        DispatchQueue.main.async {
                            if allowed {

                            } else {
                                // failed to record!
                            }
                        }
                    }
                } catch {
                    print("NOT ALLOWED")
                    // failed to record!
                }

            }

            @objc func updateMeters(){
                audioRecorder.updateMeters()


                print("CHANNEL 0 PEAK : \(audioRecorder.peakPower(forChannel: 0))")
                print("CHANNEL 1 PEAK : \(audioRecorder.peakPower(forChannel: 1))")
                print(audioRecorder.averagePower(forChannel: 0))
                print(audioRecorder.currentTime)
            }


            func startRecording() {
                let audioFilename = getDocumentsDirectory().appendingPathComponent("recording.m4a")

                let settings = [
                    AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
                    AVSampleRateKey: 12000,
                    AVNumberOfChannelsKey: 2,
                    AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
                ]

                do {

                    audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
                    audioRecorder.delegate = self
                    audioRecorder.isMeteringEnabled = true
                    audioRecorder.record()

                    recordButton.setTitle("Tap to Stop", for: .normal)

                    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateMeters), userInfo: nil, repeats: true)
                } catch {
                    finishRecording(success: false)
                }
            }

            func getDocumentsDirectory() -> URL {
                let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
                let documentsDirectory = paths[0]
                return documentsDirectory
            }

            func finishRecording(success: Bool) {
                timer.invalidate()
                audioRecorder.stop()
                audioRecorder = nil

                if success {
                    recordButton.setTitle("Tap to Re-record", for: .normal)
                } else {
                    recordButton.setTitle("Tap to Record", for: .normal)
                    // recording failed :(
                }
            }

            @IBAction func recordTapped() {
                if audioRecorder == nil {
                    startRecording()
                } else {
                    finishRecording(success: true)
                }
            }

            func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
                if !flag {
                    finishRecording(success: false)
                }
            }

            @IBAction func play(_ sender: UIButton) {
                let fileURL = getDocumentsDirectory().appendingPathComponent("recording.m4a")
                    self.audioPlayer = try! AVAudioPlayer(contentsOf: fileURL)
                    self.audioPlayer.prepareToPlay()
                    self.audioPlayer.delegate = self
                    self.audioPlayer.play()
            }
        }

【问题讨论】:

    标签: ios swift audio avfoundation audio-recording


    【解决方案1】:

    正如 smakusdodreddit thread 中提到的:

    iphone 有 3 个麦克风...根据哪个摄像头像阵列一样使用 处于活动状态,或者如果您处于免提模式等,如果苹果愿意, 他们可以将这些麦克风用于立体声录音。例如,使用 右声道底部麦克风,左声道顶部麦克风。目前 他们不允许这样做,而是只公开一个单声道。

    因为苹果只提供了一个单声道通道,这意味着 iOS 开发者不可能同时为我们访问这些内置麦克风。

    如果您认为应该可以,Apple 会为您提供机会让他们知道: https://www.apple.com/feedback/iphone.html

    【讨论】:

    • 可能硬件不支持。
    猜你喜欢
    • 1970-01-01
    • 2017-09-05
    • 2016-05-15
    • 2018-02-03
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 2017-04-14
    相关资源
    最近更新 更多