Repository navigation
Return state after changes; add obs-record-clip and obs-capture-window - #6
Conversation
obs-set-input-settings and obs-create-input read the input back: its settings, its size wherever it appears in the program scene, and a warning when it still renders at 0x0 after capture sources have had ~750 ms to produce a frame. An optional includeScreenshot adds a bounded 960px JPEG of the input. obs-set-scene-item-transform returns the transform OBS applied. Read-back failures are reported as warnings, never as a failed change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vjn8uBEa4mJshaQU3pFuqX
obs-record-clip runs the preflight, starts recording and waits for OBS to confirm it, adds chapters at the requested offsets, always stops, then checks the file with ffprobe (length, audio streams) and ffmpeg volumedetect when silence is expected. Clips are capped at 50 s because many clients time tool calls out at 60 s. obs-capture-window (macOS) creates or reuses a screen_capture input, selects a display before listing windows or apps (listing apps without one crashed OBS), matches the target by name or ID, mutes it and clears its audio tracks, and fits it to the canvas, then returns its size like obs-set-input-settings. The preflight fake state moves to a shared fixture, and the fake OBS takes a platform option. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vjn8uBEa4mJshaQU3pFuqX
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3495062cf3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const chapters = [...args.chapters].sort((a, b) => a.atSeconds - b.atSeconds); | ||
| for (const chapter of chapters) { | ||
| await sleep(Math.max(0, startedAt + chapter.atSeconds * 1000 - Date.now())); |
There was a problem hiding this comment.
Reject chapters scheduled after the clip ends
When a chapter's atSeconds exceeds durationSeconds, this sleep waits until the chapter time before reaching the stop logic. Since atSeconds has no upper bound, a nominally short clip can record indefinitely, outlive the MCP client's timeout, and continue consuming disk space; validate every chapter against the requested duration or stop at the duration independently of chapter scheduling.
Useful? React with 👍 / 👎.
| const { stderr } = await execFileAsync("ffmpeg", [ | ||
| "-hide_banner", "-nostats", "-i", outputPath, "-map", "0:a:0", "-af", "volumedetect", "-f", "null", "-", | ||
| ], { timeout: 60_000 }); |
There was a problem hiding this comment.
Measure every recorded audio stream
When advanced OBS recording produces multiple audio streams, mapping only 0:a:0 checks the first stream and can report a recording as silent even when a later recorded track contains audible audio. The post-recording silence verification should analyze all audio streams, or explicitly fail when any stream exceeds the threshold.
Useful? React with 👍 / 👎.
| const problems: string[] = []; | ||
| if (inspection.durationSeconds !== undefined && inspection.durationSeconds < args.durationSeconds - 2) { | ||
| problems.push(`The file is ${inspection.durationSeconds.toFixed(1)}s, shorter than the requested ${args.durationSeconds}s`); |
There was a problem hiding this comment.
Scale the short-file tolerance for short clips
For every requested duration of 2 seconds or less, durationSeconds - 2 is nonpositive, so no nonnegative probed duration can satisfy this condition. A requested 1-second recording that contains only a fraction of a second is therefore reported as verified; use a smaller proportional or bounded tolerance so the tool can detect truncated short clips.
Useful? React with 👍 / 👎.
| const type = args.window ? SCK_WINDOW_CAPTURE : SCK_APPLICATION_CAPTURE; | ||
| if (!existing) { | ||
| await client.sendRequest("CreateInput", { |
There was a problem hiding this comment.
Add reused capture inputs to the requested scene
When inputName already exists as a screen_capture but has no scene item in sceneName, this branch skips creation without adding the existing source to that scene. With the default fit: true, the later GetSceneItemId fails after the source settings and audio state have already been changed; with fit: false, the call reports success even though the requested scene contains no capture. Create a scene item for the reused source when it is absent from the target scene.
Useful? React with 👍 / 👎.
Stacked on #5.
State after changes
obs-set-input-settingsandobs-create-inputnow return the input's settings and its size in the program scene. They warn when it still renders at 0×0 after giving capture sources about 750 ms to deliver a first frame. We'd have caught the blank Chrome capture immediately.includeScreenshotadds a 960px JPEG, within the existing size limits.obs-set-scene-item-transformreturns the transform OBS actually applied.obs-record-clipexpectSilentis setobs-capture-window(macOS)screen_captureinput and selects a display before listing windows or apps. Listing apps without a display crashed OBS.Tests: 13 new unit tests, including real ffmpeg-generated silent and tone clips (skipped when ffmpeg is missing).
npm run checkpasses (92 unit, 10 e2e).Not yet verified against live OBS: both combined tools change OBS state (a new input, a recording), so their live test is waiting on approval. Two untested assumptions: that listing
display_uuiditems is safe, and that the fit transform centres the way I expect.🤖 Generated with Claude Code
https://claude.ai/code/session_01Vjn8uBEa4mJshaQU3pFuqX