commit 9602f82ca9081ca6372aa8b81b519e799dd392a0 Author: Harry Date: Thu Oct 8 12:04:39 2026 +0200 docs: add agreed recorder v1 specification diff --git a/SPEC.md b/SPEC.md new file mode 100644 index 0000000..24b88df --- /dev/null +++ b/SPEC.md @@ -0,0 +1,133 @@ +# Clipbin recorder v1 specification + +This document defines the v1 product requirements agreed on 2026-10-08. See [README.md](README.md) for the current implementation status. + +Build an open-source desktop game recorder inspired by Plays.tv, using Rust, GPUI, and libobs through libobs-rs. The core experience is automatic recording, browsing a session while it is still active, saving recent clips, and protecting bookmarked moments. + +## Platforms and distribution + +- Target Windows and Linux, covering Wayland and X11. Wayland is the user's available Linux test environment; X11 and Windows need their own validation before release. +- Initial Linux validation setup: CachyOS, Hyprland, AMD Radeon RX 9070 XT, recording at 1440p60. +- Steam is the v1 game-discovery/launcher integration. The recording core must not depend on Steam-specific data structures so other integrations can be added later. +- Use official OBS capture components only. Existing community capture plugins, including obs-vkcapture, and custom game hooks are excluded. +- Windows: upstream OBS Game Capture with original signed hook binaries; official OBS Window Capture is also available. +- Linux X11: upstream OBS Xcomposite Window Capture. +- Native Linux Wayland: upstream OBS PipeWire capture using the XDG desktop portal. Offer both window and monitor capture, selected by the user. +- Restore portal permissions/source selection where supported. If restoration fails, show a recording-needs-attention notification with a select-source action. Automatic recording is conditional on a usable, permitted capture source. +- Monitor capture includes whatever is displayed on that monitor during alt-tab. Switching from window to monitor capture requires the user's selection; do not silently broaden the capture target. +- Bundle a pinned, compatible OBS runtime and required official components. Users should not need a separate OBS installation. Graphics drivers remain system-provided. +- Pin Rust OBS bindings, OBS runtime, and plugins as a tested version set. Exact versions and platform package formats are implementation decisions. + +## Automatic recording and reliability + +- Start on login by default, with a setting to disable it. +- Detect recognised Steam games and start recording immediately, without per-game approval or routine manual start/stop. +- Keep recording when the user alt-tabs, browses footage, edits a range, or exports a clip. +- Stop/finalise the session when its game exits. +- Closing the main window leaves background recording active. Provide an explicit Quit action. +- Normal recording is silent: no routine start/stop notifications or recording overlay. +- Show honest recording state in the application: waiting for capture, starting, recording, or failed. +- Report recording only when capture is usable and footage is successfully being written. A detected process, permission grant, or accepted start command alone is insufficient. +- Source loss, permission failure, encoder failure, output failure, and insufficient physical disk space must clear the recording state and produce a persistent, actionable failure alert. +- Recover temporary failures automatically with bounded retries. Keep the unavailable/error state until recording actually resumes. +- Missing footage is represented clearly in the session timeline. Recovery must not imply that the interrupted period was captured. +- Anti-cheat risk is a primary concern. Use the original official capture foundation, preserve Windows hook signatures, and avoid changing anti-cheat/trust protections to enable capture. Successful capture alone is not evidence of a blanket anti-cheat approval. + +## Recording defaults and audio + +- Default video: 1080p at 60 FPS. +- Resolution and frame rate are configurable, including the user's intended 1440p60 configuration. +- Hardware video codec choices: H.264, HEVC, and AV1. H.264 is the default. +- Offer a codec as usable only when the runtime/device supports its hardware encoder. Failure to obtain a working encoder follows the honest-status and failure-alert rules. +- Keep system audio enabled by default. +- Microphone recording is opt-in. +- Preserve system and microphone audio on separate tracks, retaining their appropriate channel layouts. +- Export a combined system/microphone playback track by default, with an option to preserve separate tracks for editing. +- How quality presets map to individual encoder settings, and any hardware-codec fallback policy, must be chosen during implementation without hiding a recording failure. + +## Sessions, timeline, and editor + +- Keep complete recorded sessions browsable after gameplay until cleanup removes eligible footage. +- Provide a session library and a continuous timeline/VOD for each session. +- Active sessions can be browsed and clipped while their recording continues. +- The newest footage may appear two to five seconds behind recording while its segment finalises. +- Do not provide a live recording preview. Decode/play video when the user browses it. +- Editor controls: play/pause, seeking, thumbnails, bookmark navigation, draggable start/end handles, and audio controls. +- Clip selection/export uses keyframe-aligned boundaries. Frame-exact cuts are not required. +- Preserve all selected footage when extending a selection to suitable keyframe boundaries, and show the actual export range. +- Show unavailable or removed parts of a session honestly. Protect footage currently being edited or exported from cleanup. +- A clip must remain playable across retained recording segment boundaries. + +## Clip hotkey and bookmarks + +- Provide independently configurable clip and bookmark actions/hotkeys. +- The clip hotkey requests the last X time from the moment it is pressed; default X is two minutes. +- Export the requested range in the background without stopping recording. +- If the current segment must finish before export, retain the original request timestamp instead of shifting the range to when the job runs. +- For a shorter newly started session, use the available footage and show its actual duration. +- Protect source segments until export succeeds. Surface export failures; do not report successful saving before the exported file is complete. +- The separate bookmark action places a timeline marker and protects a configurable interval. +- Bookmark defaults: two minutes before and 30 seconds after the marker, independently configurable from the clip duration. +- Protection for the post-bookmark period applies as that footage is recorded, ending at the actual session end if gameplay exits sooner. +- Protected bookmarks remain available until the user releases/removes their protection. + +## Storage and exports + +- Default storage budget: 50 GB, configurable. +- The budget counts only UNPROTECTED session footage. +- Protected bookmarked footage and exported clips do not count toward the session budget. Total app storage may therefore exceed the configured budget. +- Cleanup is storage-based only; there is no age-based expiry. +- Remove the oldest eligible footage from completed sessions first, then old unprotected footage from the active session when needed. +- Retain protected bookmark, editing, and export ranges even when neighbouring footage is removed. +- Exported clips never expire automatically; users can delete them explicitly. +- Distinguish budget-counted session usage from protected/saved usage in storage information. +- Physical disk exhaustion remains a hard failure: stop/finalise safely, report that recording is unavailable, and offer corrective actions without silently deleting protected footage. +- V1 exports local files only, with quick actions to open a clip or its folder. +- Export MP4 while preserving the recorded video codec. +- Use remuxing for compatible, keyframe-aligned clips without video re-encoding. +- Keep capture running independently of export work. + +## Recording architecture and lightweight operation + +- Preferred architecture: one hardware-encoded video stream written into short, independently usable, keyframe-aligned disk segments. +- Present those segments as one session timeline. Keep timestamps, segment availability, bookmarks, and retention/protection metadata consistent. +- Keep recording independent of UI work. UI browsing, thumbnail generation, and export must not block the capture path. +- Avoid unnecessary CPU frame copies where supported by the official capture path. +- Generate/cache thumbnails in the background. Decode playback video on demand and keep work/queues bounded. +- Prioritise recording over background thumbnails and exports. +- Best-effort lightweight operation is the v1 performance goal. +- No numerical FPS/frametime overhead promise, performance-monitoring feature, or formal benchmark programme is required in v1. Recording health checks remain required to support honest status. + +## Acceptance checks for implementation + +1. A recognised Steam game starts a recording session automatically with a usable permitted source; exiting the game finalises it. +2. Alt-tab, closing the main window, playback, range selection, and export leave recording active. +3. Portal cancellation/revocation, source loss, encoder failure, and disk-write failure never leave a false recording status or a false successful-export status. +4. Recovery preserves a visible timeline gap for footage that was not captured. +5. The clip hotkey saves the default last two minutes using its request timestamp, including a range crossing segment boundaries. +6. Bookmark protection covers its configured pre/post interval and survives cleanup of adjacent footage. +7. The 50 GB default budget evicts only unprotected session footage; bookmarks and exported clips remain outside it. +8. MP4 exports preserve the chosen recorded codec and provide the agreed default/optional audio tracks. +9. The GPUI editor plays and seeks retained footage across segment boundaries, including active sessions within the agreed availability delay. +10. Packaged builds use a verified compatible OBS/bindings/plugin set on Windows, Wayland, and X11. + +## Implementation validation before building out the UI + +- Prove the pinned official OBS capture/runtime path on CachyOS/Hyprland/RX 9070 XT, including permission restoration and capture-health failure detection. +- Verify hardware encoder availability for H.264, HEVC, and AV1 on each supported platform/device combination. +- Verify short keyframe-aligned segment rollover with one continuous encoder, export across boundaries, and the two-to-five-second availability window. Do not assume the Rust convenience wrapper exposes every required OBS output option. +- Prototype GPUI playback, seeking, and the agreed audio handling for all offered codecs. +- Establish the global hotkey integration for Windows, Wayland, and X11 using supported OS/desktop mechanisms. +- Establish game/process/session identity rules, including startup discovery, launchers spawning child processes, and ambiguous simultaneous games. +- Establish recovery of session metadata/completed segments after an unexpected process exit. +- Confirm distribution/licensing requirements for the pinned components. Exact playback backend, packaging formats, default hotkey bindings, and retry intervals can be selected during implementation. + +## Primary sources checked during the interview + +- OBS Game Capture availability and modes: https://obsproject.com/kb/game-capture-source +- OBS Window Capture sources: https://obsproject.com/kb/window-capture-sources +- Official X11 source registration: https://github.com/obsproject/obs-studio/blob/master/plugins/linux-capture/linux-capture.c +- Official PipeWire/portal implementation and restoration: https://github.com/obsproject/obs-studio/blob/master/plugins/linux-pipewire/screencast-portal.c +- Portal persistence and restoration limits: https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.ScreenCast.html +- OBS signed capture-hook compatibility: https://obsproject.com/kb/capture-hook-certificate-update +- Rust OBS bindings, platform notes, API stability: https://github.com/libobs-rs/libobs-rs