AVCaptureMovieFileOutput 从不在屏幕录制上调用委托
AVCaptureMovieFileOutput never calls delegate on screen recording
我能够 assemble 一个最小的 Swift 屏幕录制演示,用于调试另一件事,但有些东西构造了我 - AVFoundation
从不调用我的代理进行录制。 None 事实上。
代码非常简单:
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()
即可毫无问题地执行录制,并在录制完成后几秒钟后保存文件,但 "Recording delegate WAS CALLED" 永远不会打印:
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
为了确保我使用断点验证了相同的结果。谁能指出我的任何方向?我在文档中来回浏览,但找不到任何原因 none (我也尝试了一个单独的对象和其他委托回调) 委托方法被调用。
我终于设法解决了这个问题。事实上,问题 中发布的示例是正确的并且有效 。
不能的是:
let delegate = BrandNewObject()
self.fileOut!.startRecording(to: self.getTemp(), recordingDelegate: delegate)
不知何故,委托被忽略了。也许该对象已被清除?
我能够 assemble 一个最小的 Swift 屏幕录制演示,用于调试另一件事,但有些东西构造了我 - AVFoundation
从不调用我的代理进行录制。 None 事实上。
代码非常简单:
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()
即可毫无问题地执行录制,并在录制完成后几秒钟后保存文件,但 "Recording delegate WAS CALLED" 永远不会打印:
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
为了确保我使用断点验证了相同的结果。谁能指出我的任何方向?我在文档中来回浏览,但找不到任何原因 none (我也尝试了一个单独的对象和其他委托回调) 委托方法被调用。
我终于设法解决了这个问题。事实上,问题 中发布的示例是正确的并且有效 。
不能的是:
let delegate = BrandNewObject()
self.fileOut!.startRecording(to: self.getTemp(), recordingDelegate: delegate)
不知何故,委托被忽略了。也许该对象已被清除?