Frame Spaces¶
Three distinct frame spaces flow through this codebase, plus seconds from the audio side. Mixing them up is the classic bug here — everything looks right in code review and the cuts land an hour off, or shifted by exactly the padding amount.
The three spaces¶
- Timeline frames, absolute
- What Resolve's timeline items report:
ClipInfo.start/ClipInfo.endinclude the timeline start offset — usually 86400, because timelines start at 01:00:00:00 at 24 fps.session.timeline_start_frame()returns that offset. - Source frames
- Positions within a source media file.
Segment.src_in/src_out,PlannedCut.start_frame/end_frame, silence-detection output, and thestart/endyou pass toappend_segmentsare all source frames.GetLeftOffset()on a timeline item is the clip's source in-point — the bridge exposes it asleft_offset, andclip_in = left_offset,clip_out = left_offset + durationbound every per-clip computation in the pipeline. - Marker frames (timeline-relative)
AddMarkerwants frames relative to the timeline start — the one Resolve call that doesn't take absolute timeline frames. Both session classes subtracttimeline_start_frame()internally, so callers pass absolute frames and the session does the conversion. Don't subtract it yourself; that's a double-subtraction bug.
Seconds¶
librosa and Whisper produce seconds in source-file time. Convert with the timeline fps:
source_frame = int(seconds * fps)
seconds = source_frame / fps
The SRT generator works in yet another unit — seconds on the new, cut
timeline — computed as segment.timeline_offset / fps + (word.start -
segment_src_in_sec). Timeline offsets start at 0 for the new timeline;
the record position handed to Resolve is timeline_start_frame() +
timeline_offset.
Rules of thumb¶
- Crossing the session boundary into Resolve?
append_segmentstakes source frames;recordFrametakes absolute timeline frames;set_markertakes absolute timeline frames (converted for you). - Comparing anything against silence regions or transcript words: convert to
source frames or source seconds first, and clamp to
[left_offset, left_offset + duration]— the clip usually uses only part of its source file. - If an edit lands exactly one hour late, you added the timeline start offset twice; exactly one hour early, you forgot it.