我终于第一次开始使用Swift(和macOS开发)了。我正在尝试编写一个简单的屏幕捕获应用程序来开始。我已经看过并成功使用AVFoundation API来执行此操作(AVCaptureSession
,AVCaptureScreenInput
等)。但是现在我想尝试更低级别的游戏并使用更接近金属的CGDisplayStream
API。
不幸的是,我只能让它捕获一个帧。我怀疑我可能会遗漏一些主要的Runloop和我传入的DispatchQueue之间的潜在交互?不清楚这些事情是否首先相互作用。
以下是我的问题的一个小小的再现:
import Foundation
import AVFoundation
import CoreGraphics
let mainDisplay = CGMainDisplayID()
let displayBounds = CGDisplayBounds(mainDisplay)
let recordingQueue = DispatchQueue.global(qos: .background)
let displayStreamProps : [CFString : Any] = [
CGDisplayStream.preserveAspectRatio: kCFBooleanTrue,
CGDisplayStream.showCursor: kCFBooleanTrue,
CGDisplayStream.minimumFrameTime: 60,
]
let displayStream = CGDisplayStream(
dispatchQueueDisplay: mainDisplay,
outputWidth: Int(displayBounds.width),
outputHeight: Int(displayBounds.height),
pixelFormat: Int32(kCVPixelFormatType_32BGRA),
properties: displayStreamProps as CFDictionary,
queue: recordingQueue,
handler: { status, displayTime, frameSurface, updateRef in
print("is only called once")
}
)
func quit(_ : Int32) {
displayStream?.stop()
}
signal(SIGINT, quit)
displayStream?.start()
RunLoop.current.run()
任何帮助都会受到大力赞赏!!
答案 0 :(得分:0)
删除此行似乎可以解决问题:
CGDisplayStream.minimumFrameTime: 60,
文档没有提到这个“时间”字段的单位是什么,但似乎是在几秒钟内。因此,您可以将其更改为1.0/60.0
以获得60fps的捕获。