Skip to content

Conversation

@EricWiener
Copy link
Contributor

@EricWiener EricWiener commented Jun 11, 2025

Example usage shown below:
https://github.com/user-attachments/assets/6f0381a2-87d3-4f46-8268-20af74d419fc

Summary by CodeRabbit

  • New Features

    • Segment speed control added to the editor sidebar with multipliers (0.25x–8x).
    • Visual timescale indicator shows when a segment runs at non-1x speed.
    • Changing segment speed mutes that segment’s audio and updates segment timing.
  • UI

    • Dedicated "Segment Settings" block added above clip settings; sidebar padding slightly adjusted.
    • Waveform display now only shown for segments at 1x speed.
    • New icons added across the UI for improved clarity.

@EricWiener EricWiener force-pushed the ewiener/clip-speed-up branch from b1b37c9 to 77372d7 Compare June 11, 2025 13:37
@Brendonovich
Copy link
Contributor

Speed changes are only implemented in the video renderer at the moment, audio rendering will need to be modified to respect the timescale as well. Pitch correction would be nice to have for this but a more simple implementation will do for now.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 3, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Renames Segment → SegmentMedia and segments → segment_medias across crates; replaces TimelineSegment.recording_segment with recording_clip; adds per-segment timescale state + UI/action; threads clip_index/timescale through audio, playback, and rendering paths; updates frame/decoder lookups and minor desktop UI/CI/icon typings.

Changes

Cohort / File(s) Summary
Core type & API renames
crates/editor/src/editor_instance.rs, crates/editor/src/lib.rs, crates/editor/src/playback.rs, crates/editor/src/segments.rs, crates/export/src/lib.rs
Rename public type SegmentSegmentMedia; replace segments collections with segment_medias; update exports, imports and call sites across editor, playback, segments util, and export crate.
Project configuration / timeline
crates/project/src/configuration.rs
Rename TimelineSegment.recording_segmentrecording_clip (serde name preserved). Change get_segment_time signatures to return Option<(f64, &TimelineSegment)> and propagate reference-based returns; timeline-absent behavior now yields None.
Rendering / frame lookup updates
crates/rendering/src/lib.rs, crates/editor/src/editor_instance.rs, apps/desktop/src-tauri/src/lib.rs
Look up clip data via recording_clip in render_segments / segment_medias, fetch decoders/frames/cursor from render_segment/SegmentMedia, and rename parameter segmentsrender_segments.
Audio cursor & renderer adjustments
crates/editor/src/audio.rs
Replace AudioRendererCursor.segment_index with clip_index: u32 and add timescale: f64; propagate timescale, default to 1.0, and early-return render_frame_raw when timescale != 1.0.
Playback & segment-media plumbing
crates/editor/src/playback.rs, crates/editor/src/segments.rs
Playback stores segment_medias: Arc<Vec<SegmentMedia>>; get_audio_segments now accepts &[SegmentMedia]; boundary/lookup logic uses segment.recording_clip.
Desktop recording mapping
apps/desktop/src-tauri/src/recording.rs
project_config_from_recording now sets TimelineSegment.recording_clip (uses clip index) instead of recording_segment.
Editor context action (timescale)
apps/desktop/src/routes/editor/context.ts
Add projectActions.setClipSegmentTimescale(index: number, timescale: number) which recalculates a segment’s start/end, computes length diff and applies adjustments to zoomSegments within a produce/setProject update.
Segment speed UI
apps/desktop/src/routes/editor/ConfigSidebar.tsx
Add "Segment Settings" block with Speed radio group (0.25x, 0.5x, 1x, 1.5x, 2x, 4x, 8x) wired to projectActions.setClipSegmentTimescale; minor spacing/padding tweak.
ClipTrack UI & rendering gating
apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx
Use optional chaining for offsets, compute end-time using (offset + duration)/timescale, hide WaveformCanvas when segment.timescale !== 1, show timescale indicator (fast-forward icon + x{timescale}) for non-1× segments, and simplify marker transform.
Icon typings / auto-imports
packages/ui-solid/src/auto-imports.d.ts
Add multiple new icon typings, reorder/remove several legacy icons and adjust import formatting; non-functional typing/export changes.
CI runner matrix
.github/workflows/ci.yml
Replace fixed runs-on: macos-latest in clippy job with runs-on: ${{ matrix.settings.runner }} to derive runner from matrix.
Desktop audio waveform source change
apps/desktop/src-tauri/src/lib.rs
Iterate over editor_instance.segment_medias instead of editor_instance.segments when collecting waveforms.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as ConfigSidebar\n(Speed Control)
    participant Actions as projectActions\n.setClipSegmentTimescale
    participant Project as ProjectState
    participant ClipTrack as ClipTrack UI

    User->>UI: choose multiplier (e.g., 2x)
    UI->>Actions: setClipSegmentTimescale(index, timescale)
    activate Actions
    Actions->>Project: update segment.timescale, start, end
    Actions->>Project: propagate length diffs to zoomSegments
    deactivate Actions

    Note over Project: segment.timescale ≠ 1

    Project->>ClipTrack: state update
    alt timescale == 1
        ClipTrack->>ClipTrack: render WaveformCanvas
    else timescale != 1
        ClipTrack->>ClipTrack: hide waveform
        ClipTrack->>ClipTrack: show indicator (⏩ x{timescale})
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

  • Files/areas needing extra attention:
    • crates/project/src/configuration.rs — API signature changes returning references and timeline-absent behavior require caller updates.
    • crates/editor/src/audio.rs & crates/rendering/src/lib.rs — ensure timescale propagation and the early-return on non-1× segments do not break audio/video playback paths.
    • Cross-crate renames (Segment → SegmentMedia) — verify exports, serde stability, and all import sites updated.

Possibly related PRs

Suggested labels

Desktop

Poem

🐰 I hopped through code with tiny feet,

Renamed the segments, tuned their beat.
Speeds now sprint — or dawdle slow,
Waveforms hide when tempos grow.
A rabbit cheers: "New clips—let's go!"

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add clip speed editing' clearly and concisely describes the main feature being added across all changes in this PR.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 47ccad4 and b5b5ee2.

📒 Files selected for processing (1)
  • apps/desktop/src/routes/editor/ConfigSidebar.tsx (2 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d0f4ae and 49d13a2.

📒 Files selected for processing (14)
  • apps/desktop/src-tauri/src/lib.rs (2 hunks)
  • apps/desktop/src-tauri/src/recording.rs (1 hunks)
  • apps/desktop/src/routes/editor/ConfigSidebar.tsx (1 hunks)
  • apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx (4 hunks)
  • apps/desktop/src/routes/editor/context.ts (1 hunks)
  • crates/editor/src/audio.rs (6 hunks)
  • crates/editor/src/editor_instance.rs (9 hunks)
  • crates/editor/src/lib.rs (1 hunks)
  • crates/editor/src/playback.rs (5 hunks)
  • crates/editor/src/segments.rs (1 hunks)
  • crates/export/src/lib.rs (2 hunks)
  • crates/project/src/configuration.rs (3 hunks)
  • crates/rendering/src/lib.rs (3 hunks)
  • packages/ui-solid/src/auto-imports.d.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Format Rust code using rustfmt and ensure all Rust code passes workspace-level clippy lints.
Rust modules should be named with snake_case, and crate directories should be in kebab-case.

Files:

  • crates/editor/src/segments.rs
  • crates/editor/src/lib.rs
  • apps/desktop/src-tauri/src/lib.rs
  • crates/editor/src/audio.rs
  • crates/rendering/src/lib.rs
  • apps/desktop/src-tauri/src/recording.rs
  • crates/export/src/lib.rs
  • crates/project/src/configuration.rs
  • crates/editor/src/editor_instance.rs
  • crates/editor/src/playback.rs
crates/*/src/**/*

📄 CodeRabbit inference engine (AGENTS.md)

Rust crates should place tests within the src/ and/or a sibling tests/ directory for each crate inside crates/*.

Files:

  • crates/editor/src/segments.rs
  • crates/editor/src/lib.rs
  • crates/editor/src/audio.rs
  • crates/rendering/src/lib.rs
  • crates/export/src/lib.rs
  • crates/project/src/configuration.rs
  • crates/editor/src/editor_instance.rs
  • crates/editor/src/playback.rs
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use a 2-space indent for TypeScript code.
Use Biome for formatting and linting TypeScript/JavaScript files by running pnpm format.

Files:

  • apps/desktop/src/routes/editor/ConfigSidebar.tsx
  • apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx
  • apps/desktop/src/routes/editor/context.ts
  • packages/ui-solid/src/auto-imports.d.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Use kebab-case for filenames for TypeScript/JavaScript modules (e.g., user-menu.tsx).
Use PascalCase for React/Solid components.

Files:

  • apps/desktop/src/routes/editor/ConfigSidebar.tsx
  • apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx
  • apps/desktop/src/routes/editor/context.ts
  • packages/ui-solid/src/auto-imports.d.ts
🧬 Code graph analysis (6)
crates/editor/src/lib.rs (1)
crates/editor/src/editor_instance.rs (1)
  • create_segments (291-375)
crates/editor/src/audio.rs (1)
crates/editor/src/playback.rs (1)
  • start (50-171)
apps/desktop/src/routes/editor/ConfigSidebar.tsx (1)
apps/desktop/src/routes/editor/ui.tsx (1)
  • Field (25-47)
crates/project/src/configuration.rs (1)
apps/desktop/src/utils/tauri.ts (1)
  • TimelineSegment (475-475)
crates/editor/src/editor_instance.rs (1)
crates/editor/src/segments.rs (1)
  • segments (7-36)
crates/editor/src/playback.rs (1)
crates/editor/src/segments.rs (1)
  • get_audio_segments (6-37)
🔇 Additional comments (16)
packages/ui-solid/src/auto-imports.d.ts (1)

1-113: Auto-generated file - changes look appropriate.

This file is auto-generated by unplugin-auto-import. The icon additions (e.g., IconLucideFastForward, IconLucideRabbit, IconCapClock) align with the PR's clip speed editing feature.

crates/editor/src/audio.rs (6)

22-28: LGTM: Cursor structure updated correctly.

The refactoring from segment_index to clip_index with the addition of timescale appropriately supports the new clip-based speed control model.


85-95: LGTM: Initialization values are appropriate.

Default values correctly initialize the cursor: clip_index: 0 for the first clip, timescale: 1.0 for normal playback speed, and samples: 0 for the starting position.


97-112: LGTM: Playhead positioning correctly integrates clip and timescale data.

The method properly extracts clip_index and timescale from the segment, with appropriate fallback values when no segment is found.


114-140: LGTM: Cursor adjustment logic correctly updated.

The method properly handles clip transitions and timescale changes, with the comparison at line 135 correctly using clip_index to detect segment boundaries.


181-181: LGTM: Track access correctly uses clip_index.

The array indexing properly references the current clip using clip_index.


204-212: LGTM: Clip offset resolution correctly uses clip_index.

The lookup properly matches clips by clip_index to retrieve the appropriate offsets.

crates/export/src/lib.rs (1)

4-4: LGTM: Straightforward type rename.

The import and field type have been correctly updated from Segment to SegmentMedia, consistent with the broader refactor across the codebase.

Also applies to: 127-127

apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx (3)

225-237: LGTM: Correct timescale integration.

The segment duration calculations correctly account for timescale by dividing (segment.end - segment.start) / segment.timescale, converting recorded time to playback time.


475-482: Good: Conditional waveform rendering.

Gating WaveformCanvas rendering to only show when timescale === 1 is appropriate, as waveforms would be misleading when the clip is sped up or slowed down. This aligns with the note in the UI that speed changes affect audio.


592-596: LGTM: Helpful timescale indicator.

The visual indicator showing the timescale multiplier when it's not 1x provides good user feedback about which segments have modified speed.

crates/editor/src/playback.rs (2)

19-19: LGTM: Consistent type and field renames.

The changes correctly update:

  • Import from Segment to SegmentMedia
  • Field from segments to segment_medias
  • Function call to use the new field name

Also applies to: 33-33, 83-83


114-122: Correct: Updated segment lookup to use recording_clip.

The segment lookup has been updated to index by segment.recording_clip instead of the previous approach, consistent with the field rename throughout the PR.

crates/rendering/src/lib.rs (1)

192-192: LGTM: Clear parameter rename and updated segment access.

The changes correctly:

  1. Rename the parameter to render_segments for clarity
  2. Update segment lookups to use segment.recording_clip as the index
  3. Pass additional parameters (needs_camera, offsets) to get_frames
  4. Access cursor data from the render_segment

All changes are consistent with the broader refactor.

Also applies to: 216-226, 232-259

crates/editor/src/editor_instance.rs (1)

29-29: LGTM: Comprehensive and consistent type rename.

The changes thoroughly update:

  1. Field names from segments to segment_medias
  2. Type names from Segment to SegmentMedia
  3. Segment lookups to use segment.recording_clip indexing
  4. Function signatures and return types

All changes maintain consistency across the public API and internal implementation.

Also applies to: 84-84, 149-149, 210-240, 284-294, 319-319, 364-364

apps/desktop/src/routes/editor/ConfigSidebar.tsx (1)

548-551: Audio muting behavior is correctly implemented and matches the UI message.

The verification confirms that audio IS automatically muted when timescale changes. In crates/editor/src/audio.rs at lines 177-179, the audio rendering explicitly returns None whenever timescale != 1.0, preventing any audio output. This automatic muting prevents the sync issues mentioned in the review (avoiding out-of-speed audio playback). The UI warning accurately describes the implemented behavior.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/ui-solid/src/auto-imports.d.ts (1)

11-115: Inconsistent quote styles in auto-generated declarations.

The newly added icon declarations use double quotes (e.g., lines 11, 13, 17, 23, 33, etc.), while existing declarations use single quotes. Since this file is auto-generated by unplugin-auto-import, the inconsistency may stem from the tool's configuration or from different upstream icon package exports.

Consider verifying the unplugin-auto-import configuration to ensure consistent quote style generation, though this is a low-priority cosmetic issue.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3dd80e and 47ccad4.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml (1 hunks)
  • apps/desktop/src-tauri/src/lib.rs (2 hunks)
  • apps/desktop/src/routes/editor/ConfigSidebar.tsx (1 hunks)
  • packages/ui-solid/src/auto-imports.d.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/desktop/src-tauri/src/lib.rs
  • apps/desktop/src/routes/editor/ConfigSidebar.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use a 2-space indent for TypeScript code.
Use Biome for formatting and linting TypeScript/JavaScript files by running pnpm format.

Files:

  • packages/ui-solid/src/auto-imports.d.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Use kebab-case for filenames for TypeScript/JavaScript modules (e.g., user-menu.tsx).
Use PascalCase for React/Solid components.

Files:

  • packages/ui-solid/src/auto-imports.d.ts
🔇 Additional comments (2)
.github/workflows/ci.yml (1)

100-108: Good refactor: make clippy runner platform-specific via matrix.

Using ${{ matrix.settings.runner }} aligns the clippy job with the build-desktop and rust-cache jobs, ensuring each target runs on its appropriate OS. Previously, clippy would attempt to lint Windows targets on macOS, which is both inefficient and potentially problematic for platform-specific checks.

packages/ui-solid/src/auto-imports.d.ts (1)

1-7: Auto-generated file – changes reflect icon usage elsewhere.

This file is automatically generated by unplugin-auto-import. The new icon declarations added throughout this file correspond to icons now used in the clip speed editing UI and other features. No manual changes should be made directly to this file.

@Brendonovich Brendonovich merged commit b047e93 into CapSoftware:main Nov 4, 2025
1 of 3 checks passed
@DEV-SimpliflowAI
Copy link

audio doesnt't work in 1x clip, after adding a intermediate sped up clip section

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants