【问题标题】:Direct3D11CaptureFramePool frame is null in async methodDirect3D11CaptureFramePool 帧在异步方法中为空
【发布时间】:2020-08-31 18:58:06
【问题描述】:

我正在尝试使用 Windows.Graphics.Capture 命名空间从兼容的应用程序中捕获屏幕截图。

我的代码基于此处的官方示例:MS sample screenshot code

有问题的代码如下:

  private async void btnCapture_Click(object sender, EventArgs e)
    {
        process = Process.GetProcesses().Where(p => p.ProcessName == "xxxxxxxxxxx").Single();
        hwnd = process.MainWindowHandle;

        GraphicsCaptureItem item = CaptureHelper.CreateItemForWindow(hwnd);
        device = Direct3D11Helper.CreateDevice();
        capture = new BasicCapture(device, item);
        framePool = Direct3D11CaptureFramePool.Create(device, DirectXPixelFormat.B8G8R8A8UIntNormalized, 1, item.Size);
        session = framePool.CreateCaptureSession(item);
        session.StartCapture();

        using (frame = framePool.TryGetNextFrame())
        {
            var bmp = await SoftwareBitmap.CreateCopyFromSurfaceAsync(frame.Surface);
            StorageFolder pictureFolder = KnownFolders.CameraRoll;
            StorageFile file = await pictureFolder.CreateFileAsync("test.png", CreationCollisionOption.ReplaceExisting);
            using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream);
                encoder.SetSoftwareBitmap(bmp);
                await encoder.FlushAsync();
            }
        }
    }

如果我在using (frame = framePool.TryGetNextFrame()) 行中设置断点,则会填充框架并通过以下代码正常保存文件。

如果我只是运行应用程序,则 frame 为 null 并发生错误。我不能在 framePool.TryGetNextFrame() 上使用 await

我觉得这是一个科学怪人代码,因为我正在学习新的捕获范例。任何帮助如何使此代码工作?

最终我将需要此代码与计时器一起定期截取屏幕截图。

【问题讨论】:

    标签: c# .net async-await


    【解决方案1】:

    Direct3D11CaptureFramePool 有一个FrameArrived 事件,您可以在尝试获取帧之前侦听该事件:

    var cts = new TaskCompletionSource<object>();
    framePool.FrameArrived += (s, e) => cts.SetResult(null);
    
    session.StartCapture();
    
    await cts.Task;
    
    // Frame should now be available
    using (frame = framePool.TryGetNextFrame())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-19
      相关资源
      最近更新 更多