如何以 60fps 录制离屏 NSView

问题描述 投票:0回答:2

我想从 macOS 上运行的离屏 NSView 录制视频输出(编码或未编码)。我很确定没有 API 可以做到这一点,但我相信通过将其逐帧渲染到帧缓冲区中是可行的。

问题是我找不到以足够快的速度渲染视图的方法。我尝试过但没有成功的方法(在运行 Monterey 的 MacBook M1 Pro 上测试):

  • [view dataWithPDFInsideRect:]
    [view dataWithEPSInsideRect:]
    :执行大约需要 200 毫秒。
  • [view.layer renderInContext:]
    :执行大约需要350ms。
  • [view cacheDisplayInRect: toBitmapImageRep:]
    :执行大约需要100ms。

我还尝试将视图嵌入到窗口中并捕获窗口。窗口捕获功能(例如

CGWindowListCreateImage
)速度更快,但当窗口离屏时不起作用。

考虑到视图可以在窗口中以 60fps 渲染而不会出现问题,为什么这些方法要花费这么多时间?我是否错过了将 NSView 渲染到帧缓冲区的任何方法?

swift objective-c macos cocoa
2个回答
1
投票

我终于找到了一种高效的方法。通过以这种方式捕捉视图,我能够达到 60+ fps。

NSView* view = ...;
NSBitmapImageRep* bitmap = [
    [NSBitmapImageRep alloc]
    initWithBitmapDataPlanes:nil
    pixelsWide:view.bounds.size.width
    pixelsHigh:view.bounds.size.height
    bitsPerSample:8
    samplesPerPixel:4
    hasAlpha:YES
    isPlanar:NO
    colorSpaceName:NSCalibratedRGBColorSpace
    bitmapFormat:0
    bytesPerRow:(4 * view.bounds.size.width)
    bitsPerPixel:32
];

NSGraphicsContext* graphicsContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:graphicsContext];
[view displayRectIgnoringOpacity:view.bounds inContext:graphicsContext];
[NSGraphicsContext restoreGraphicsState];

// pixels are in format [R, G, B, A, R, G, B, A, ...]
unsigned char* pixels = [bitmap bitmapData];

0
投票

另一种高效的方式可能是:

```NSBitmapImageRep *bm = [view bitmapImageRepForCachingDisplayInRect:view.bounds];
    [view cacheDisplayInRect:view.bounds toBitmapImageRep:bm];
    return (CGImageRef)CFRetain( bm.CGImage );```
© www.soinside.com 2019 - 2024. All rights reserved.