VisioForge

Cross-Platform Screen Recording in C# and .NET

Build a screen recorder in C# with one API for Windows, macOS, Linux, Android and iOS: the full screen, a window or a region, with sound, the cursor and click highlights, to MP4 or a live stream. Video Capture SDK .NET and Media Blocks SDK .NET use the native capture API of each platform.

A screenshot loop is not a screen recorder

Graphics.CopyFromScreen gives you one bitmap on Windows. A recorder also needs a steady frame rate, the cursor, sound, an encoder and a file whose audio stays in sync with the video, and on every other operating system the capture API is different again: AVFoundation or ScreenCaptureKit on macOS, X11 on Linux, MediaProjection on Android, ReplayKit on iOS. In the VisioForge SDKs the screen is a video source like a webcam. ScreenSourceBlock uses the native API of the platform it runs on, and the encoder, the file and the stream are the same code everywhere.

Building a cross-platform screen recorder yourself vs. using the SDK

Typical do-it-yourself stackVisioForge Video Capture SDK .NET and Media Blocks SDK .NET
Capturing the screenA different native API on each OS, each behind your own interop: Desktop Duplication or Windows Graphics Capture on Windows, ScreenCaptureKit or AVFoundation on macOS, X11 or PipeWire on Linux, MediaProjection on Android, ReplayKit on iOSScreenSourceBlock with one settings class per platform; ScreenSourceBlock() without arguments takes the platform default
One window or a regionWindow identifiers and crop code that differ per OS: HWND on Windows, an X11 window ID on LinuxWindowHandle on Windows or XID on Linux for one window, Rectangle for a region, MonitorIndex on Windows or Monitor on macOS for the monitor
Cursor and clicksComposite the cursor and click marks onto each frame yourselfCaptureCursor on Windows, macOS and Linux; MouseHighlight draws an expanding circle at each click, taken from a global mouse hook on Windows and passed in by your code on other platforms
SoundA separate audio API per OS for the microphone, plus WASAPI loopback for system sound on Windows, synchronized with the video by your codeSystemAudioSourceBlock for a microphone on every platform, LoopbackAudioCaptureDeviceSourceSettings for system sound on Windows, on the same timeline as the video
Encoding and the fileMedia Foundation, VideoToolbox and MediaCodec wrapped one by one, or an FFmpeg build shipped with each appH264EncoderBlock picks MediaCodec, VideoToolbox, or NVENC, AMF and Quick Sync with OpenH264 as fallback; MP4, WebM, MKV, MOV, AVI or MPEG-TS output
Code to maintainFive platform implementations to write, test and keep in stepOne C# pipeline; only the source settings differ per platform

Screen capture on each platform

ScreenSourceBlock() with no arguments picks the default source for the platform. Pass a settings object to choose the API, the window or the region.

PlatformCapture APISettings classSoundNotes
WindowsWindows Graphics Capture, DXGI Desktop Duplication, DirectX 9, GDIScreenCaptureD3D11SourceSettings, ScreenCaptureDX9SourceSettings, ScreenCaptureGDISourceSettingsSystem sound (WASAPI loopback) or a microphoneMonitor, region or one window; click highlights
macOSAVFoundationScreenCaptureMacOSSourceSettingsMicrophoneNeeds the Screen Recording permission: ScreenSourceBlock.AskPermissions()
Mac Catalyst (.NET MAUI)ScreenCaptureKitScreenCaptureMacOSSourceSettingsMicrophoneThe same settings class as macOS
LinuxX11ScreenCaptureXDisplaySourceSettingsMicrophoneNeeds an X11 session; XID or XName selects one window
AndroidMediaProjectionAndroidScreenCaptureSourceSettingsMicrophoneThe user accepts the system prompt; recording runs in a foreground service
iOSReplayKitIOSScreenSourceSettings, IOSBroadcastSourceSettingsMicrophoneYour own app, or the whole device through a Broadcast Upload Extension

What the SDK does for a screen recorder

Screen and desktop recording is a video source in VideoCaptureCoreX (Video Capture SDK .NET) and a ScreenSourceBlock in Media Blocks SDK .NET. Everything after the source works as it does for a camera: preview, recording, streaming and video effects.

  • Three capture modes: the full screen of any monitor, one application window by its handle, or a rectangle of the desktop
  • Windows Graphics Capture is selected by default on Windows 10 version 1803 and later; DXGI Desktop Duplication, DirectX 9 and GDI sources are also available
  • Sound from the PC through WASAPI loopback or from a microphone; in Media Blocks SDK .NET, AudioMixerBlock mixes both into one track
  • Cursor capture and click highlights with configurable color, radius and duration, for tutorials and demos. On Windows the clicks come from a global mouse hook: when MouseHighlight is set, VideoCaptureCoreX installs it on start; in Media Blocks you call MouseHighlightSubscribe(). On other platforms your code passes each click to MouseHighlightAddClickEvent (MouseHighlight_AddClickEvent in VideoCaptureCoreX)
  • Hardware H.264: MediaCodec on Android, VideoToolbox on Apple platforms; on Windows the SDK tries NVENC, AMF and Quick Sync and falls back to OpenH264
  • Several outputs at once: record MP4 while streaming the same screen to YouTube over RTMP, SRT or NDI; pause and resume a recording or start a new file without stopping the preview
  • One API on Windows, macOS, Linux, Android and iOS, from WinForms, WPF, .NET MAUI and native macOS, Android and iOS apps; a sample for each

Use cases

Tutorial and e-learning recorders

Record a window or the whole screen with narration and click highlights, and save the lesson to MP4.

Support and session recording

Record what a user did before a problem appeared and attach the video to the support ticket.

QA and test automation

Record each automated UI test run and keep the video of the failed ones as evidence.

Presentations and live streams

Stream the screen to YouTube or an NDI receiver and keep a local MP4 copy from the same capture.

Code examples

Condensed from the Screen Capture demos of Video Capture SDK .NET and Media Blocks SDK .NET. The first two run in a WinForms form, the third in a .NET MAUI page; each has a VisioForge VideoView named videoView1 or videoView.

Record the screen and system sound to MP4

C#

Record one window with click highlights

C#

One recorder for Windows, macOS, Android and iOS (.NET MAUI)

C#

The pipeline

The window example and the .NET MAUI example use the same four blocks. ScreenSourceBlock captures the screen with the platform's API, TeeBlock splits the frames between the preview and the encoder, and MP4SinkBlock writes the file. Only the source settings change from platform to platform.

ScreenSourceBlock
TeeBlock
H264EncoderBlock
MP4SinkBlock

Frequently asked questions

How do I record the sound the PC is playing?▼
Use LoopbackAudioCaptureDeviceSourceSettings with an output device from DeviceEnumerator.Shared.AudioOutputsAsync(AudioOutputDeviceAPI.WASAPI2) and set Audio_Record to true, as in the first example. For narration, use a microphone from AudioSourcesAsync instead. To record both, mix them with AudioMixerBlock in Media Blocks SDK .NET.
Can I record a window that is covered by other windows?▼
Yes, with Windows Graphics Capture: set API to D3D11ScreenCaptureAPI.WGC and WindowHandle to the window's handle. WGC captures the window's own content, so overlapping windows do not appear in the recording. A minimized window has nothing to draw and is not captured.
Does it work on macOS and Linux?▼
Yes. On macOS the screen source uses AVFoundation and needs the Screen Recording permission: ScreenSourceBlock.AskPermissions() shows the system prompt, and macOS applies a new permission after the app restarts. On Linux, ScreenCaptureXDisplaySourceSettings captures an X11 display, so the app needs an X11 session. The encoders, files and streams are the same as on Windows; system sound loopback is Windows only, so record a microphone there.
Can I record the screen on Android and iOS?▼
Yes, with Media Blocks SDK .NET. On Android, AndroidScreenCaptureSourceSettings takes the MediaProjection your app receives after the user accepts the system prompt. On iOS, IOSScreenSourceSettings records your own app through ReplayKit, and IOSBroadcastSourceSettings records the whole device through a Broadcast Upload Extension.
Why is the recording black?▼
Protected content such as DRM video is blocked from capture by the operating system. For other black frames, try the other capture API (WGC or DXGI Desktop Duplication) or the DirectX 9 source. On a laptop with two GPUs, Desktop Duplication has to run on the adapter that drives the display; DXGIAdapter selects it.
Which SDK do I need?▼
Video Capture SDK .NET if you want a ready capture engine: set Video_Source, Audio_Source and an output, then call StartAsync. Media Blocks SDK .NET if you build the pipeline from blocks, for example to add your own processing between the screen and the encoder. Both use the same screen sources.