FFMPEG录屏(13)---- WGC 捕获桌面(一) 改造官网Demo

照例先上参考资料

参考资料

New Ways to do Screen Capture
C++/WinRT
CPP ScreenCaptureForHWND

限制

WindowsGraphicsCapture APIs first shipped in the Windows 10 April 2018 Update (1803). These APIs were built for developers who depended on screen capture functionality for their modern applications without depending on restricted capabilities. These APIs enable capture of application windows, displays, and environments in a secure, easy to use way with the use of a system picker UI control.

C++/WinRT is an entirely standard modern C++17 language projection for Windows Runtime (WinRT) APIs, implemented as a header-file-based library, and designed to provide you with first-class access to the modern Windows API. With C++/WinRT, you can author and consume Windows Runtime APIs using any standards-compliant C++17 compiler. The Windows SDK includes C++/WinRT; it was introduced in version 10.0.17134.0 (Windows 10, version 1803).

综上想要基于最新的捕获技术WindowsGraphicsCapture进行图像捕获有以下限制

  • 系统版本不低于10.0.17134.0 (Windows 10, version 1803)
  • 相关接口均基于微软的新一代运行时库接口C++/WinRT,而且是最低要求 c++17

一般项目开发中不太会使用c++17,所以都会将基于WGC的图像捕获功能封装到动态库中,在判断系统支持WGC后基本都会优先使用WGC来捕获图像。

添加桌面捕获功能

已完成Demo

  • 项目中添加头文件 Win32MonitorEnumeration.h,封装了枚举显示器的功能
#pragma once
#include <dwmapi.h>

struct Monitor {
public:
  Monitor(nullptr_t) {}
  Monitor(HMONITOR hmonitor, std::wstring &className, bool isPrimary) {
    m_hmonitor = hmonitor;
    m_className = className;
    m_bIsPrimary = isPrimary;
  }

  HMONITOR Hmonitor() const noexcept { return m_hmonitor; }
  std::wstring ClassName() const noexcept { return m_className; }
  bool IsPrimary() const noexcept { return m_bIsPrimary; }

private:
  HMONITOR m_hmonitor;
  std::wstring m_className;
  bool m_bIsPrimary;
};

BOOL WINAPI EnumMonitorProc(HMONITOR hmonitor, HDC hdc, LPRECT lprc,
                            LPARAM data) {

  MONITORINFOEX info_ex;
  info_ex.cbSize = sizeof(MONITORINFOEX);

  GetMonitorInfo(hmonitor, &info_ex);

  if (info_ex.dwFlags == DISPLAY_DEVICE_MIRRORING_DRIVER)
    return true;

  auto monitors = ((std::vector<Monitor> *)data);
  std::wstring name = info_ex.szDevice;
  auto monitor =
      Monitor(hmonitor, name, info_ex.dwFlags & MONITORINFOF_PRIMARY);

  monitors->emplace_back(monitor);

  return true;
}

std::vector<Monitor> EnumerateMonitors() {
  std::vector<Monitor> monitors;

  ::EnumDisplayMonitors(NULL, NULL, EnumMonitorProc, (LPARAM)&monitors);

  return monitors;
}
  • capture.interop.h 添加根据显示器句柄创建Capture的功能
inline auto CreateCaptureItemForMonitor(HMONITOR hmonitor) {
  auto activation_factory = winrt::get_activation_factory<
      winrt::Windows::Graphics::Capture::GraphicsCaptureItem>();
  auto interop_factory = activation_factory.as<IGraphicsCaptureItemInterop>();
  winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr};
  interop_factory->CreateForMonitor(
      hmonitor,
      winrt::guid_of<ABI::Windows::Graphics::Capture::IGraphicsCaptureItem>(),
      reinterpret_cast<void **>(winrt::put_abi(item)));
  return item;
}
  • App.h 中添加开始捕获函数声明
void StartCapture(HMONITOR hmonitor);
  • App.cpp中添加开始捕获函数定义
void App::StartCapture(HMONITOR hmonitor) {
  if (m_capture) {
    m_capture->Close();
    m_capture = nullptr;
  }

  auto item = CreateCaptureItemForMonitor(hmonitor);

  m_capture = std::make_unique<SimpleCapture>(m_device, item);

  auto surface = m_capture->CreateSurface(m_compositor);
  m_brush.Surface(surface);

  m_capture->StartCapture();
}
  • main.cpp中引入头文件
#include "Win32MonitorEnumeration.h"
  • main.cpp中添加枚举显示器操作
auto g_monitors = EnumerateMonitors();
  • main.cpp中向控件Combox添加枚举到的显示器信息
for (auto &monitor : g_monitors) {
  SendMessage(comboBoxHwnd, CB_ADDSTRING, 0,
              (LPARAM)monitor.ClassName().c_str());
}
  • main.cpp中添加处理选中显示器时的操作
if (index < g_windows.size() - 1) {
  auto window = g_windows[index];
  g_app->StartCapture(window.Hwnd());
} else {
  auto monitor = g_monitors[index - g_windows.size()];
  g_app->StartCapture(monitor.Hmonitor());
}
  • 再次编译运行,会发现程序的窗口列表框里多出了你所有的显示器信息,选择它即可开始采集并实时显示捕获到的画面
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ffmpeg-web-pusher是一个基于FFmpeg的实用工具,用于实时将音频和视频内容推送到Web服务器。它可以将本地视频或音频文件编码并传输到网络服务器上,从而实现实时推流功能。 ffmpeg-web-pusher具有以下几个主要功能: 1. 编码和推送:通过FFmpeg进行音视频编码,然后使用HTTP或RTMP协议将数据推送到Web服务器。这样,可以实现通过Web浏览器或其他支持Web播放的设备来实时观看视频或听取音频。 2. 多种格式支持:ffmpeg-web-pusher支持多种音视频格式,包括常见的MP4、FLV、AVI等。无论是从本地文件还是摄像头进行推流,都可以根据需要选择合适的格式。 3. 音频和视频参数设置:通过ffmpeg-web-pusher,可以根据需求设置音频和视频的各种参数,如比特率、帧率、分辨率等。这样可以根据网络带宽和终端设备的性能来进行适当的优化。 4. 实时监控:ffmpeg-web-pusher提供实时监控功能,可以显示当前推送的音频和视频的传输状态,如帧率、码率、延迟等。这对于调试和优化音视频传输非常有帮助。 ffmpeg-web-pusher是一个功能强大而灵活的工具,可以帮助开发人员实现实时音视频推流功能,并在Web浏览器上进行播放。无论是在线直播、视频会议、视频监控还是其他实时音视频场景,都可以通过使用ffmpeg-web-pusher来实现。它在提供高质量音视频传输的同时,还可以根据具体需求进行各种参数调整,使其更好地适应不同的应用场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值