объединение AVCaptureScreenInput и AVCaptureVideoDataOutput - PullRequest
0 голосов
/ 30 апреля 2020

Я пытаюсь получить кадры записи экрана через вызов AVCaptureVideoDataOutput.

Вот как я продолжаю:

class Recorder: NSObject, NSApplicationDelegate, AVCaptureFileOutputRecordingDelegate {

    private var session = AVCaptureSession()
    private var videoOutput: AVCaptureVideoDataOutput = AVCaptureVideoDataOutput()
    private var audioOutput: AVCaptureAudioDataOutput = AVCaptureAudioDataOutput()

    fileprivate(set) lazy var isRecording = false
    fileprivate var videoWriter: AVAssetWriter!
    fileprivate var videoWriterInput: AVAssetWriterInput!
    fileprivate var audioWriterInput: AVAssetWriterInput!
    fileprivate var sessionAtSourceTime: CMTime?


    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
        print("Recording delegate WAS CALLED")
    }

    /**
     `AVCaptureSessionRuntimeErrorNotification` callback.
     */
    @objc
    fileprivate func captureSessionRuntimeError(notification: NSNotification) {
        print(notification.userInfo![AVCaptureSessionErrorKey.description])
    }


    func recorder() {
        self.session.beginConfiguration() //As per Apple docs for atomic config updates

        // Wire screen input
        let captureInput = AVCaptureScreenInput(displayID: CGMainDisplayID())
        do {
             if (!session.canAddInput(captureInput!)) {
                 assertionFailure("Failed to add input")
                 return
             }
             self.session.addInput(captureInput!)
         } catch {
             assertionFailure("Failed to add input")
         }

        //define output data queue
        let queue = DispatchQueue(label: "Spoke.data-output")

        //Define video output settings
        videoOutput.videoSettings = [
            kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA,
        ]
        videoOutput.alwaysDiscardsLateVideoFrames = true

        // Wire video output
        guard self.session.canAddOutput(self.videoOutput) else {
            assertionFailure("Failed to add video output")
            return
        }
        videoOutput.setSampleBufferDelegate(self, queue: queue)
        session.addOutput(self.videoOutput)

        // Commit configuration
        self.session.commitConfiguration()
        print("commit configuration done")

        // This should be blocking and ACTUALLY start the session as per
        // https://developer.apple.com/documentation/avfoundation/avcapturesession

        // add async error call
        NotificationCenter.default.addObserver(self, selector: #selector(captureSessionRuntimeError), name: NSNotification.Name.AVCaptureSessionRuntimeError, object: nil)
        self.session.startRunning()
    }
}

И все же я получаю много ошибок в журнале консоли после self.session.startRunning():

CMIO_Unit_Input_AS C .mm: 8558 cmio assert: "success" под залог - (err = 0) CMIO_Unit_Input_AS C .mm: 8558: SetupScreenCapture Ошибка: SetupDisplayStream () вернул false CMIO_Unit_Input_AS C .mm: 2117 cmio заявить: «успех» под залог - (err = 0) CMIO_Unit_Input_AS C .mm: 2117: _Start Ошибка: SetupScreenCapture вернул false

Вот что я получаю с AVCaptureSessionRuntimeErrorNotification обратный вызов:

Необязательно (Ошибка домена = AVFoundationErrorDomain Code = -11800 «Операция не может быть завершена» UserInfo = {NSLocalizedFailureReason = Произошла неизвестная ошибка (2003329396), NSLocalizedDescription = Операция не может быть завершено, NSUnderlyingError = 0x600000cad440 {Error Domain = NSOSStatusErrorDomain Code = 2003329396 "(null)" UserInfo = {AVErrorFourCharCode = 'what'}}})

Что я мог сделать не так в настройке?

...