pub struct EditProject {
pub schema_version: u32,
pub source: ClipRef,
pub segments: Vec<TimelineSegment>,
pub zooms: Vec<ZoomSegment>,
pub background: BackgroundConfig,
pub cursor: CursorConfig,
pub crop: Option<CropRect>,
pub aspect: AspectRatio,
pub project_fps: u32,
pub next_zoom_id: u32,
pub cursor_track: Option<Vec<CursorSample>>,
pub clicks: Option<Vec<ClickEvent>>,
}Expand description
The serialized source of truth for one editing session.
The edited video is the ordered concatenation of segments; the
cinematic framing comes from background / cursor / crop /
aspect; cinematic punch-ins come from zooms. Nothing here is
a GPU or media handle — the renderer and encoder re-derive every
frame from this model at preview + export time.
Fields§
§schema_version: u32On-disk schema version (see SCHEMA_VERSION).
source: ClipRefThe source recording this project edits.
segments: Vec<TimelineSegment>Ordered timeline slices (trim / split / speed).
zooms: Vec<ZoomSegment>Cinematic zoom regions.
background: BackgroundConfigBackground framing (wallpaper / padding / radius / shadow).
cursor: CursorConfigCursor styling + auto-zoom detection settings.
crop: Option<CropRect>Optional crop / reframe of the source. None = full frame.
aspect: AspectRatioOutput aspect ratio.
project_fps: u32Timeline frame rate (the editor’s time authority).
next_zoom_id: u32Monotonic counter for allocating fresh crate::ZoomIds
(managed by edit operations in ED.2).
cursor_track: Option<Vec<CursorSample>>Per-frame cursor track captured at record time (ED.17). None for
projects recorded before cursor capture, or when the macOS
input-monitoring permission was denied. Drives the cursor overlay
(ED.19).
clicks: Option<Vec<ClickEvent>>Click log captured at record time. Feeds auto-zoom detection
(crate::telemetry::auto_zoom_segments) and the cursor click-ripple
overlay (ED.19). None = no telemetry captured.
Implementations§
Source§impl EditProject
impl EditProject
Sourcepub fn apply(&mut self, op: &EditOp) -> Result<(), EditError>
pub fn apply(&mut self, op: &EditOp) -> Result<(), EditError>
Apply an edit operation, mutating the project in place.
Prefer driving edits through crate::History, which makes them
undoable; this is the underlying primitive.
§Errors
Returns EditError for an out-of-range segment index, an empty
range, an unknown zoom id, or a split past the end of the timeline.
fn apply_split(&mut self, at: Frame) -> Result<(), EditError>
fn apply_trim( &mut self, index: usize, edge: TrimEdge, to: Frame, ) -> Result<(), EditError>
fn apply_ripple_delete(&mut self, d0: Frame, d1: Frame) -> Result<(), EditError>
fn apply_set_speed( &mut self, index: usize, timescale: f64, ) -> Result<(), EditError>
fn apply_add_zoom(&mut self, zoom: ZoomSegment)
fn apply_remove_zoom(&mut self, id: ZoomId) -> Result<(), EditError>
fn apply_move_zoom( &mut self, id: ZoomId, start: Frame, end: Frame, ) -> Result<(), EditError>
fn apply_set_zoom_ease( &mut self, id: ZoomId, ease: EditEase, ) -> Result<(), EditError>
fn apply_set_crop(&mut self, rect: CropRect)
Sourcepub fn check_invariants(&self) -> Result<(), String>
pub fn check_invariants(&self) -> Result<(), String>
Check the project’s structural invariants. Used by tests (and a
useful debugging aid): segments are non-empty and within the
source; the zoom list is sorted, each zoom is non-empty, and every
zoom id is below next_zoom_id.
§Errors
Returns a human-readable description of the first violated invariant.
Source§impl EditProject
impl EditProject
Sourcepub fn from_recording(source: ClipRef) -> Self
pub fn from_recording(source: ClipRef) -> Self
Build a fresh project from a source recording: a single, full-length, real-time segment with default framing and no zooms — i.e. “the recording, untouched”, ready to edit.
Sourcepub fn project_duration(&self) -> Frame
pub fn project_duration(&self) -> Frame
Total length of the edited timeline in project frames.
Sourcepub fn segment_offsets(
&self,
) -> impl Iterator<Item = (usize, Frame, &TimelineSegment)> + '_
pub fn segment_offsets( &self, ) -> impl Iterator<Item = (usize, Frame, &TimelineSegment)> + '_
Walk the segments with their cumulative project-frame start
offset: yields (index, project_start, segment).
This is the single accumulation site for the segment→project-time
walk — locate, segment_project_range,
and the UI’s timeline lanes all derive from it instead of
re-implementing the running sum.
Sourcepub fn segment_project_range(&self, index: usize) -> Option<(Frame, Frame)>
pub fn segment_project_range(&self, index: usize) -> Option<(Frame, Frame)>
The [start, end) project-frame range occupied by segment
index, or None if the index is out of range.
Sourcepub fn locate(&self, project_frame: Frame) -> Option<(usize, Frame)>
pub fn locate(&self, project_frame: Frame) -> Option<(usize, Frame)>
Locate a project frame: returns (segment index, source frame),
or None if the frame is at/past the end of the timeline.
This is the core of the editor’s time model — it walks the segment
list accumulating project-frame lengths until it finds the segment
containing project_frame, then maps the within-segment offset to
a source frame via that segment’s timescale.
Sourcepub fn source_time(&self, project_frame: Frame) -> Option<Frame>
pub fn source_time(&self, project_frame: Frame) -> Option<Frame>
Map a project frame to the source frame the renderer should
decode, or None past the end of the timeline.
Sourcepub fn canvas_dims(&self) -> (u32, u32)
pub fn canvas_dims(&self) -> (u32, u32)
The composed-output canvas dimensions in pixels — the source’s
longer edge reframed to the project’s aspect ratio
(e.g. a 1920×1080 recording → 1080×1920 when aspect is Vertical).
Both edges are even (H.264 chroma subsampling needs it). The source
frame is letterboxed/pillarboxed into this canvas at render time, so
changing the aspect reframes the export without distorting the content.
This is the unclamped canvas (the live preview composes at it
directly); the export path additionally passes it through
media::encode::fit_within_encoder_limits for the HW-encoder edge cap.
Sourcepub fn zoom_cursor_target(&self, frame: Frame) -> (f32, f32)
pub fn zoom_cursor_target(&self, frame: Frame) -> (f32, f32)
The normalized (x, y) a cursor-targeted zoom should punch into at
project frame — the cursor’s position there from
cursor_track, or the frame centre (0.5, 0.5)
when no track was captured. Pure; the basis for the editor’s
“zoom to cursor” authoring action.
Sourcepub fn generate_auto_zooms(&mut self) -> usize
pub fn generate_auto_zooms(&mut self) -> usize
Generate auto-zoom blocks from the captured click log (ED.17 — the “Auto-Zoom: detect from cursor” feature). Returns the number generated.
A no-op (returns 0) unless detection is enabled
(CursorConfig::auto_zoom), a
click log is present, and no zooms exist yet — so a freshly recorded
clip arrives already punched-in on its click clusters, while a re-opened
edit keeps the zooms the user already tuned (the generator never
clobbers an existing list). The blocks are ordinary editable
ZoomSegments (crate::telemetry::auto_zoom_segments) — the user
nudges, deletes, or retunes them like any other zoom.
Trait Implementations§
Source§impl Clone for EditProject
impl Clone for EditProject
Source§fn clone(&self) -> EditProject
fn clone(&self) -> EditProject
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for EditProject
impl Debug for EditProject
Source§impl<'de> Deserialize<'de> for EditProject
impl<'de> Deserialize<'de> for EditProject
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for EditProject
impl PartialEq for EditProject
Source§fn eq(&self, other: &EditProject) -> bool
fn eq(&self, other: &EditProject) -> bool
self and other values to be equal, and is used by ==.