0

Apples CI Face Detector を使用してリアルタイム ビデオで顔を検出したいのですが、AVAssetWriter を使用してビデオをファイルに記録したいと考えています。

動作していると思いましたが、オーディオは気まぐれです。ビデオと一緒に正しく記録される場合もあれば、記録を開始してもミュートになる場合もあれば、ビデオと同期していない場合もあれば、まったく機能しない場合もあります。

print ステートメントを使用すると、オーディオ サンプル バッファーがあることがわかります。そのコードをコメントアウトすると、記録が正常に機能するため、顔検出と関係があるに違いありません。

これが私のコードです:

// MARK: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioOutputSampleBufferDelegate
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

    let writable = canWrite()
    if writable {
        print("Writable")
    }

    if writable,
        sessionAtSourceTime == nil {
        // Start Writing
        sessionAtSourceTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
        videoWriter.startSession(atSourceTime: sessionAtSourceTime!)
        print("session started")
    }


    // processing on the images, not audio
    if output == videoDataOutput {
        connection.videoOrientation = .portrait
        if connection.isVideoMirroringSupported {
            connection.isVideoMirrored = true
        }

        // convert current frame to CIImage
        let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
        let attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, pixelBuffer!, CMAttachmentMode(kCMAttachmentMode_ShouldPropagate)) as? [String: Any]
        let ciImage = CIImage(cvImageBuffer: pixelBuffer!, options: attachments)

        // Detects faces based on your ciimage
        let features = faceDetector?.features(in: ciImage, options: [CIDetectorSmile : true,
                                                                     CIDetectorEyeBlink : true,
                                                                     ]).compactMap({ $0 as? CIFaceFeature })

        // Retreive frame of your buffer
        let desc = CMSampleBufferGetFormatDescription(sampleBuffer)
        let bufferFrame = CMVideoFormatDescriptionGetCleanAperture(desc!, false)

        // Draw face masks
        DispatchQueue.main.async { [weak self] in
            UIView.animate(withDuration: 0.2) {
            self?.drawFaceMasksFor(features: features!, bufferFrame: bufferFrame)
            }
        }
    }

    if writable,
        output == videoDataOutput,
        (videoWriterInput.isReadyForMoreMediaData) {
        // write video buffer
        videoWriterInput.append(sampleBuffer)
        print("video buffering")
    } else if writable,
        output == audioDataOutput,
        (audioWriterInput.isReadyForMoreMediaData) {
        // write audio buffer
        audioWriterInput?.append(sampleBuffer)
        print("audio buffering")
    }

}
4

0 に答える 0