微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

播放用 AVCaptureAudioDataOutput 录制的音频

如何解决播放用 AVCaptureAudioDataOutput 录制的音频

我正在尝试录制视频和音频并通过网络发送它们,以便它们可以在其他客户端上实时播放。我已成功录制和播放视频,但仍然无法播放音频(请参阅下面代码底部的 AVAudioPlayer)。我做错了什么或缺少什么? (还有其他几个 StackOverflow 问题似乎解决了同样的问题,但即使那里的评论表明有些人能够使其工作,但没有一个给出明确的、有效的答案。)在此先感谢您任何输入。

let captureSession = AVCaptureSession()

private func startVideoFeed() {
    let sessionPreset = AVCaptureSession.Preset.low
    if captureSession.canSetSessionPreset(sessionPreset) {
        captureSession.sessionPreset = sessionPreset
    }
    switch AVCaptureDevice.authorizationStatus(for: .video) {
    case .notDetermined:
        AVCaptureDevice.requestAccess(for: .video) { success in
            self.startVideoFeed()
        }
    case .authorized:
        captureSession.beginConfiguration()
        let captureVideoDevice = AVCaptureDevice.default(.builtInWideAngleCamera,for: .video,position: .front)!
        let captureVideoInput = try! AVCaptureDeviceInput(device: captureVideoDevice)
        if captureSession.canAddInput(captureVideoInput) {
            captureSession.addInput(captureVideoInput)
        }
        let captureVideoOutput = AVCaptureVideoDataOutput()
        captureVideoOutput.setSampleBufferDelegate(self,queue: dispatchQueue.main)
        if captureSession.canAddOutput(captureVideoOutput) {
            captureSession.addOutput(captureVideoOutput)
        }
        captureSession.commitConfiguration()
        captureSession.startRunning()
    default:
        break
    }
}

private func startAudioFeed() {
    switch AVCaptureDevice.authorizationStatus(for: .audio) {
    case .notDetermined:
        AVCaptureDevice.requestAccess(for: .audio) { success in
            self.startAudioFeed()
        }
    case .authorized:
        captureSession.beginConfiguration()
        let captureAudioDevice = AVCaptureDevice.default(for: .audio)!
        let captureAudioInput = try! AVCaptureDeviceInput(device: captureAudioDevice)
        if captureSession.canAddInput(captureAudioInput) {
            captureSession.addInput(captureAudioInput)
        }
        let captureAudioOutput = AVCaptureAudioDataOutput()
        captureAudioOutput.audioSettings = [AVFormatIDKey: kAudioFormatLinearPCM,AVNumberOfChannelsKey: NSNumber(value: 1),AVSampleRateKey: NSNumber(value: 44100)]
        captureAudioOutput.setSampleBufferDelegate(self,queue: dispatchQueue.main)
        if captureSession.canAddOutput(captureAudioOutput) {
            captureSession.addOutput(captureAudioOutput)
        }
        captureSession.commitConfiguration()
    default:
        break
    }
}

func captureOutput(_ output: AVCaptureOutput,didOutput sampleBuffer: CMSampleBuffer,from connection: AVCaptureConnection) {
    if let imageBuffer = sampleBuffer.imageBuffer {
        let ciImage = CIImage(cvPixelBuffer: imageBuffer)
        let cgImage = CIContext().createCGImage(ciImage,from: ciImage.extent)!
        let data = CFDataCreateMutable(nil,0)!
        let imageDestination = CGImageDestinationCreateWithData(data,kUTTypeJPEG,1,nil)!
        CGImageDestinationAddImage(imageDestination,cgImage,[kCGImageDestinationLossyCompressionQuality: NSNumber(value: 0)] as CFDictionary)
        CGImageDestinationFinalize(imageDestination)
        play(data: data as Data)
    } else if let dataBuffer = sampleBuffer.dataBuffer {
        let data = try! dataBuffer.dataBytes()
        play(data: data)
    }
}

private func play(data: Data) {
    if let image = CGImage(jpegDataProviderSource: CGDataProvider(data: data as CFData)!,decode: nil,shouldInterpolate: false,intent: .defaultIntent) {
        // image is a valid image
    } else if let audioPlayer = try? AVAudioPlayer(data: data) {
        audioPlayer.play()
        // audioPlayer is always nil with error: Error Domain=NSOsstatusErrorDomain Code=1954115647 "(null)"
    }
}

解决方法

https://developer.apple.com/documentation/coremedia/1489629-cmsamplebuffergetdatabuffer

调用者不拥有返回的 dataBuffer,如果调用者需要维护对它的引用,则必须显式保留它。

您需要对数据执行 CFRetain 和 CFRelease。

播放器为零,因为您使用的数据对其进行了初始化。 Convert sampleBuffer to Data

NSOSStatusErrorDomain Code=1954115647

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。