AVCaptureSession音频预览

3

对于这个“愚蠢”的问题,我提前道歉,但我觉得我已经耗尽了所有的资源。虽然我几乎没有使用Swift和编码方面的经验,但我基于以往的经验和使用基于对象的编程,如MAX MSP,已经理解了很多。

我正在尝试为macOS QuickTime Player录制功能开发一个相机/麦克风捕获iOS应用程序(回答我自己对原始相机接入的需求,因为我真的找不到合适的东西!)。

成功实现AVCaptureSession视频输出后,我尝试了许多将音频发送到Quicktime的方法(包括AVAudioSessionPortUSBAudio),但都没有成功。这是在我意识到QuickTime自动捕获iOS系统音频输出之前。

所以我的假设是,在AVCapture Session下应该能够轻松预览音频;但事实并非如此!似乎在Swift4中,AVCaptureAudioPreviewOutput是“不可用的”,或者我只是错过了一些基础知识。我看到了关于停止音频处理的堆栈文章,所以我希望可以轻松地预览/监视它。

你们中的任何一个人能够指引我预览AVCaptureSession中的音频的方法吗?我仍然有一个已实例化的AVAudioSession(我的原始尝试),并且还成功(我希望)将麦克风连接到了AVCaptureSession。但是,我不确定还需要使用什么!我的目标:只是听到系统音频输出上的Mic输入:Quicktime连接应该(希望如此)处理从USB端口捕获(在选择iOS设备作为麦克风时,在手机上播放的音乐会通过USB传输)。

    let audioDevice = AVCaptureDevice.default(for: AVMediaType.audio)
    do {
        let audioInput = try AVCaptureDeviceInput(device: audioDevice!)
        self.captureSession.addInput(audioInput)
    } catch {
        print("Unable to add Audio Device")
    }

我还尝试了其他一些事情,但现在有些茫然不知所措。

    captureSession.automaticallyConfiguresApplicationAudioSession = true

    func showAudioPreview() -> Bool { return true }

也许可以在音频采集的同时使用 AVAudioSession 吗?然而,我的基础知识表明,同时运行采集和音频会话存在问题。如有帮助将不胜感激,我相信你们中的许多人会翻白眼并轻松指出我的错误!
谢谢,
Iwan
1个回答

1

AVCaptureAudioPreviewOutput 仅适用于 Mac,但您可以使用 AVSampleBufferAudioRenderer 替代。您需要手动将音频 CMSampleBuffer 排队到其中,这是由 AVCaptureAudioDataOutput 提供的:

import UIKit
import AVFoundation

class ViewController: UIViewController, AVCaptureAudioDataOutputSampleBufferDelegate {
    let session = AVCaptureSession()
    let bufferRenderSyncer = AVSampleBufferRenderSynchronizer()
    let bufferRenderer = AVSampleBufferAudioRenderer()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        bufferRenderSyncer.addRenderer(bufferRenderer)
        
        let audioDevice = AVCaptureDevice.default(for: .audio)!
        
        let captureInput = try! AVCaptureDeviceInput(device: audioDevice)
        
        let audioOutput = AVCaptureAudioDataOutput()
        audioOutput.setSampleBufferDelegate(self, queue: DispatchQueue.main) // or some other dispatch queue
        
        session.addInput(captureInput)
        session.addOutput(audioOutput)
        
        session.startRunning()
    }

    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        bufferRenderer.enqueue(sampleBuffer)
        
        if bufferRenderSyncer.rate == 0 {
            bufferRenderSyncer.setRate(1, time: sampleBuffer.presentationTimeStamp)
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接