feat: record at the source's size, only once capture works
Rust checks / windows-cross-check (push) Successful in 41s
Rust checks / linux (push) Failing after 5m37s

Encoders and the segment output are created when the capture source first
has a picture, at its own size (portrait monitors record portrait) unless a
resolution is configured, so nothing is written while waiting for a source.
SPEC.md records both decisions; validation docs cover how sessions should end
when the game closes.
This commit is contained in:
2026-10-08 15:34:42 +02:00
parent 96590e9c4a
commit 795118c200
9 changed files with 448 additions and 260 deletions
+22 -12
View File
@@ -149,18 +149,28 @@ Windows status:
its last frame after the stream stops, and only logs the stream state. The
engine reads that log line (stable for the pinned OBS version). A more robust
follow-up is watching the PipeWire node state directly.
- **Closed windows on Wayland.** With Hyprland's portal, closing a captured
window leaves the stream running on its last frame, with no state change or
error. Capture cannot tell this apart from a static window, so sessions must
end from game process exit (SPEC: "Stop/finalise the session when its game
exits"), which the Steam/process detection milestone provides.
- **Writing while waiting for capture.** The output starts before the source
has a picture, so a source that never arrives produces black segments. The
session timeline should show that time as missing footage, or the output
should start only once capture is usable.
- **Canvas orientation.** The output canvas is fixed by the configured
resolution, so portrait or other-aspect sources are letterboxed. Decide
whether the canvas should follow the captured source.
- **Ending a session when the game closes.** With Hyprland's portal, closing a
captured window leaves the stream running on its last frame, with no state
change or error, so capture cannot tell it from a static window. Monitor
capture never sees the game close at all. The session therefore ends from
the game's process exiting (SPEC: "Stop/finalise the session when its game
exits"); capture loss stays a failure signal, not the normal end:
- Linux: Steam runs each game under `reaper SteamLaunch AppId=<id>`, which
lives exactly as long as the game (Proton included). Watch that process
with a pidfd (`pidfd_open` + poll) rather than polling `/proc`.
- Windows: watch the game's process handle (`OpenProcess` +
`WaitForSingleObject`), found from Steam's `RunningAppID` registry value.
Game Capture reports size 0 when its game closes; the exit must be seen
first so a normal exit finalises the session instead of failing it.
- Hyprland's IPC does announce window closes, but it is compositor-specific
and cannot map a portal stream to a window, so it is not used.
- **Nothing is written before capture works.** Encoders and the segment
output are created only once the source has a picture, so waiting in the
picker or for a stalled portal writes no footage.
- **Recording size.** By default each recording is the captured window's or
monitor's own size, set when capture first has a picture (portrait monitors
record portrait). If the window is resized mid-session the size stays and
the picture is scaled to fit.
- **Audio capture failures are not detected yet.** When the PulseAudio server
was unreachable, recording continued with a silent track.
- **Linux runtime dependencies.** The Linux OBS build links the system's