AVCaptureMovieFileOutput никогда не вызывает делегата при записи экрана - PullRequest
0 голосов
/ 20 января 2020

Мне удалось собрать минимальную демонстрацию записи экрана на Swift для отладки другой вещи, но что-то структурировало меня - AVFoundation никогда не вызывает моего делегата для записи. На самом деле ни один из них.

Код довольно прост:

class ExampleRecorder: NSObject, AVCaptureFileOutputRecordingDelegate {
   private var session: AVCaptureSession?;
   private var fileOut: AVCaptureMovieFileOutput?;

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

   func record() {
       self.session = AVCaptureSession()
       self.session!.beginConfiguration() //As per Apple docs for atomic config updates

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

       // Wire output
       self.fileOut = AVCaptureMovieFileOutput()
       guard self.session!.canAddOutput(self.fileOut!) else {
           assertionFailure("Failed to add output")
           return
       }
       session!.addOutput(self.fileOut!)

       // Just check the wiring
       print(self.session!.connections)

       self.session!.commitConfiguration()

       // This should be blocking and ACTUALLY start the session as per
       // https://developer.apple.com/documentation/avfoundation/avcapturesession
       self.session!.startRunning()
       print("Is session running? \(self.session!.isRunning)")

       self.fileOut!.startRecording(to: self.getTemp(), recordingDelegate: self)
       print("Is recording running? \(self.fileOut!.isRecording)")

       //Simply stop the recording after 5 seconds
       Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(stopRecord(_:)), userInfo: nil, repeats: false)
   }

   //Nothing to see here - boilerplate to create UNIQUE temporary file
   private func getTemp() -> URL
   {
       let tempName = NSUUID().uuidString
       let tempPath = (NSTemporaryDirectory() as NSString).appendingPathComponent((tempName as NSString).appendingPathExtension("mov")!)

       print("Temp path: \(tempPath)")

       return URL(fileURLWithPath: tempPath)
   }

   @objc func stopRecord(_ timer: Timer?)
   {
       print("Is session running after 5 sec? \(self.session!.isRunning)")
       print("Is record running after 5 sec? \(self.fileOut!.isRecording)")

       fileOut?.stopRecording()
   }
}

Простой вызов ExampleRecorder().record() выполняет запись без проблем и сохраняет файл через пару секунд после записи. завершено, но «Запись делегата БЫЛА ВЫЗОВА» никогда не печатается:

2020-01-20 00:37:10.764852-0600 HEVCRecorder[29875:2886265] Metal API Validation Enabled
[<AVCaptureConnection: 0x60000026f160 [type:vide][enabled:1][active:1]>]
2020-01-20 00:37:12.061411-0600 HEVCRecorder[29875:2886265] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x6000002775e0> 30010C1C-93BF-11D8-8B5B-000A95AF9C6A
Is session running? true
Temp path: /var/folders/mv/tlzj_p0d4b9cgm854s3n73zc0000gn/T/DFCC195F-2415-4F80-AC21-25C1DB0CD181.mov
Is recording running? false
2020-01-20 00:37:12.295775-0600 HEVCRecorder[29875:2886688] GVA info: preferred scaler idx 1
2020-01-20 00:37:12.299733-0600 HEVCRecorder[29875:2886688] GVA encoder info: recomputed for fps: 15.000000, gop size in pics: 15, gop size in sec: 1.000000
GVA encoder info: recomputed for fps: 15.000000, gop size in pics: 15, gop size in sec: 1.000000 
2020-01-20 00:37:12.582543-0600 HEVCRecorder[29875:2886700] GVA info: preferred scaler idx 1
2020-01-20 00:37:12.586830-0600 HEVCRecorder[29875:2886700] GVA encoder info: recomputed for fps: 15.000000, gop size in pics: 15, gop size in sec: 1.000000
GVA encoder info: recomputed for fps: 15.000000, gop size in pics: 15, gop size in sec: 1.000000 
Is session running after 5 sec? true
Is record running after 5 sec? true

Просто чтобы убедиться, что я проверил, что используется точка останова с такими же результатами. Кто-нибудь может указать мне в любом направлении? Я перебирал документацию и не мог найти причины, по которой не было (я пытался создать отдельный объект и другие функции обратного вызова делегата) из методов делегата вызывается.

1 Ответ

0 голосов
/ 08 февраля 2020

Мне наконец удалось решить проблему. На самом деле пример, приведенный в вопросе , верен и работает .

Что будет не работать так:

let delegate = BrandNewObject()

self.fileOut!.startRecording(to: self.getTemp(), recordingDelegate: delegate)

Каким-то образом это делается делегат игнорируется. Возможно, объект очищен?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...