Repository navigation
OBS clips are cut to the highlight when finished, without the lead-in and tail OBS records (#84) - #1068
Closed
ccoventry wants to merge 8 commits into
Closed
OBS clips are cut to the highlight when finished, without the lead-in and tail OBS records (#84)#1068ccoventry wants to merge 8 commits into
ccoventry wants to merge 8 commits into
Conversation
…when finishing (#84) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…count (#84) The muxer's frame count lags the file by OBS's audio buffering, which grew from 0.37 s to over 1 s between two batches of one OBS session. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ting with the batch's last write still reads the OBS trim (#84) The first job of a finished batch read the file mid-write and copied its take untrimmed. Start delay 40 ms, from four batches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…kwards (#84) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
Closed at the user's call: OBS's ~0.9 s lead-in and ~60 ms tail are fine to leave in (users trim in their editor anyway), and Keep as captured stays an exact copy. Branch kept in case this comes back; if reopened, #1066's OBS Quality needs the trim encode at CQP 12 in the take's own pixel format so Max stays 4:4:4. |
This was referenced Oct 29, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release note: Fixed: OBS clips are now cut to the highlight when they are finished, without the second of lead-in and the tail OBS recorded around it.
Closes #84
What changes
ObsSessionnotes whenStartRecordreported the recording started, and eachSTART_RECORD/STOP_RECORDmarker is stamped as it arrives (on the reader thread, so the capture loop's 16 ms sleep doesn't add to it). A marker's place in the file is its arrival time since the start, less a measured 16 ms (plus 30 ms for a marker fromqconsole.log).native/src/obs/trim.rs.obs_trim(start_seconds,end_seconds,fps) in the take'sdodstudio_take.json. Saved format: an optional new field, no format bump. Old takes (and a take whoseSTART_RECORDwas missed) have no trim and finish untrimmed exactly as before; older builds still read the file and ignore the field. The capture-settings write after the batch keeps the trim the batch recorded.-ss <start - half a frame> -t <length>as input options (FFmpeg's accurate seek; the half frame keeps the frame nearest the start). Progress for a cut OBS take comes from the time written against its length.source_copy, the OBS default) on a take with a trim is a short re-encode, no longer a copy. The dropdown now says "Keep as captured, cut to the clip (seconds)".Why a re-encode for Keep as captured
A stream copy can only cut on a keyframe. OBS's Simple output puts one every 250 frames (4.2 s at 60 fps, measured with ffprobe), and obs-websocket can't change that in Simple mode. With a ~0.9 s head, a copy would keep the whole head. Splicing a re-encoded first GOP onto copied packets needs matching parameter sets in one MP4, which two encoders don't give, so I ruled it out as fragile. So the cut re-encodes at OBS's own quality:
h264_nvencCQP 16 (what Studio's profile records at), orlibx264CRF 14 when FFmpeg can't open NVENC. That is probed once per FFmpeg path with a one-frame encode, which haskill_on_dropand a 15 s timeout. Audio is AAC 320 kb/s. Measured on a 1440p clip: PSNR 43 dB against the original. A whole 3-clip batch (64 s of footage) finished in 17-24 s.Why not OBS's own frame count
I built it first on
GetRecordStatus'soutputDuration(frames × frame time, sampled in bursts to place OBS's frame clock to ~1 ms). It failed live. That count is what the muxer has written, and the muxer holds video until it has audio to interleave. The hold is OBS's audio buffering, which OBS raises and never lowers. In one OBS session the count ran 0.37 s behind the file in one batch. Then OBS logged "adding 661 milliseconds of audio buffering", and in the next batch it had not counted a single frame 1 s into the recording. The time sinceOUTPUT_STARTEDdoesn't move with that (measured at 298 ms and 960 ms of buffering).Test done
All on POST, Brain account through game_lock, OBS 33.0.0 at 60 fps (the user updated it from 32.2.2 that evening, so the audit's numbers were on 32.2.2), Studio built from this branch with its own settings copy. The 3 clips were m00cat's WSOD25 3k/4k/3k from the audit (
wsod25_grp5_h1_m00cat×2,wsod25_grp2_h2_m00cat), finished with Keep as captured.Across all 25 measurements (5 batches, both ends), the delay that would have been exact ranged from 6 to 30 ms (mean 16). With 16 ms, every cut lands within 14 ms of HLAE's frame, under one frame at 60 fps. Stills of each clip's first frame, OBS cut against HLAE:
local\review-images\obs-84\first_frame_*_obs_vs_hlae.png. They show the same view; only the random shell casings differ.cargo test --workspace --locked, clippy 1.98.1--workspace --all-targets -D warnings, fmt check,npm run test:unit(923), e2eapp-boot+finish-clips: all pass after merging dev.Decisions
OUTPUT_STARTED, not the frame count, for the reasons above. The 16 ms constant is measured on one PC, one game build (POST) and one encoder (NVENC). On another PC an error would show as a few ms of head or a frame short at the end, never the 0.9 s head.🤖 Generated with Claude Code