The native plugin exposes a deliberately bounded Windows-only window-capture surface. It does not forward arbitrary OBS input settings.
create_window_capture_source requires an exact scene name, source name,
process ID, window handle, and current window title. It also accepts one typed
capture method: automatic, bitblt, or windows_graphics_capture. The
caller can also set the typed capture_audio boolean to capture audio from
that exact application in normal OBS Program recordings. The
native plugin then:
- verifies that the HWND is live, visible, and owned by the requested PID;
- derives the current title, window class, executable basename, and process creation time through Win32 APIs;
- creates one libobs
window_capturesource and scene item; and - revalidates the same process object and window identity before returning a typed readback.
get_window_capture_source repeats the exact binding check without mutating
OBS. Call it immediately before recording. A missing window, PID/HWND reuse,
title drift, changed source settings, duplicate scene item, or changed process
object fails closed with a stable public error code.
list_window_capture_candidates provides a bounded, read-only recovery path
for restart-heavy RL workloads. It requires an exact executable basename and
optionally an exact title, returns at most 64 visible top-level windows, and
never returns executable paths. Each candidate includes visibility,
minimized state, client dimensions, and a derived captureReady value. A
missing or ambiguous candidate is not silently selected.
restore_window_capture_candidate accepts only one exact executable basename,
PID, HWND, and title returned by discovery. On Windows it revalidates the live
process object and window identity, submits SW_RESTORE only when the window
is minimized, and polls candidate discovery until the same physical window is
non-minimized with a positive client area. It never accepts a path, wildcard,
or arbitrary window command.
rebind_window_capture_source updates one existing source in place. The caller
must provide both the stored old PID/HWND/title identity and a fresh identity
returned by candidate discovery. The native plugin validates ownership from
private source metadata even when the old process has exited, validates the
new live window immediately before mutation, and restores the prior settings
if exact readback fails.
Metadata readback cannot prove that OBS is rendering useful pixels. Call
capture_program_frame after binding validation and before every long
recording. It returns the current program scene as a fixed 320x180 in-memory
PNG with byte length and SHA-256; it accepts no source name or filesystem path.
Inspect that frame and fail closed on black or incorrect content.
set_window_capture_method changes typed capture settings on an existing
exactly bound source. The plugin verifies the scene item, private binding
metadata, live process object, HWND, title, class, executable, cursor setting,
client-area setting, visibility, and current source kind before mutation. It
then reads the source back; a failed postcondition rolls both capture method
and application-audio state back. set_window_capture_audio provides a clear
entry point for toggling the same typed audio setting while requiring the
caller's current capture method so the update cannot silently change modes.
Window audio is part of the normal OBS source and mixer path. Private
start_scene_recordings sessions remain video-only and continue to use their
own silent AAC timing track; enabling capture_audio does not add audio to
those independent outputs.
OBS automatic mode chooses BitBlt for window classes outside its WGC allowlist.
Use explicit windows_graphics_capture when a live game window produces a
black or incorrect BitBlt frame. The public API maps the enum internally and
does not accept raw integer settings.
The source stores only the exact binding metadata needed for later readback. It returns the executable basename, never the full executable path. The API does not accept raw source kinds, raw settings, or raw vendor requests.
On macOS and Linux the native request returns OBS_UNSUPPORTED_PLATFORM.
Use other reviewed, platform-specific typed capture contracts when they are
added; UI automation remains a last-resort fallback.