CGDisplayStream仅捕获单个帧

时间:2018-03-21 18:23:33

标签: swift macos screen-capture

我终于第一次开始使用Swift(和macOS开发)了。我正在尝试编写一个简单的屏幕捕获应用程序来开始。我已经看过并成功使用AVFoundation API来执行此操作(AVCaptureSessionAVCaptureScreenInput等)。但是现在我想尝试更低级别的游戏并使用更接近金属的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()

任何帮助都会受到大力赞赏!!

1 个答案:

答案 0 :(得分:0)

删除此行似乎可以解决问题:

CGDisplayStream.minimumFrameTime:    60,

文档没有提到这个“时间”字段的单位是什么,但似乎是在几秒钟内。因此,您可以将其更改为1.0/60.0以获得60fps的捕获。