Skip to content

Conversation

@oscartbeaumont
Copy link
Contributor

@oscartbeaumont oscartbeaumont commented Oct 2, 2025

The issue seems to be because the mp4 library is reading bogus durations from the mp4. I have switched it for ffmpeg which seems to be correct.

Also improved the UX. Previously it would show the error toast and the upgrade flow. Now it just shows the upgrade flow.

Summary by CodeRabbit

  • New Features

    • Improved video validation and duration detection using a more robust backend for better compatibility and accuracy.
    • More reliable video processing initialization to reduce upload/processing failures.
  • Bug Fixes

    • Suppressed a brief, confusing error popup when sharing/exporting without the required plan.
    • Added a short delay in the upload flow to prevent UI flicker when sharing is blocked.
  • Chores

    • Reduced bundled dependencies and enabled additional static checks in CI.

@oscartbeaumont oscartbeaumont changed the title Improve the 5min studio export limit dialog Improve the 5 min studio export limit dialog Oct 2, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 2, 2025

Walkthrough

Adds a SilentError and brief delay to suppress a spurious global error during export/upload when sharing is disallowed. Removes the mp4 crate and replaces manual MP4 parsing with FFmpeg-based video validation and duration extraction in the Tauri Rust backend. Renames an internal MP4 encoder field from last_timestamp to last_pts.

Changes

Cohort / File(s) Summary
Export upload flow
apps/desktop/src/routes/editor/ExportDialog.tsx
Adds a non-exported SilentError and a ~1s wait before throwing it when sharing is disallowed; updates upload onError to suppress global error dialogs for SilentError while preserving dialogs for other errors.
Tauri Cargo manifest
apps/desktop/src-tauri/Cargo.toml
Removes the mp4 crate dependency.
Video validation & metadata (Rust)
apps/desktop/src-tauri/src/lib.rs
Replaces Mp4Reader-based parsing with FFmpeg: adds ffmpeg init (best-effort in run() and guarded in metadata paths), renames is_valid_mp4is_valid_video, validates by checking for video streams via ffmpeg::format::input, computes duration via input.duration() / AV_TIME_BASE, and updates call sites and error messages accordingly.
MP4 encoder internal rename
crates/enc-avfoundation/src/mp4.rs
Renames internal field last_timestamp: Option<cm::Time>last_pts: Option<cm::Time> and updates all internal usages (initialization, updates, clearing, logging); no public API changes.
CI toolchain
.github/workflows/ci.yml
Adds the clippy component to the Rust toolchain setup.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Dialog as ExportDialog
  participant Uploader

  User->>Dialog: Click "Share/Upload"
  Dialog->>Dialog: Check sharing allowed?
  alt Not allowed (requires upgrade)
    Dialog->>Dialog: wait 1s
    Dialog-->>Uploader: throw SilentError (control-flow interrupt)
  else Allowed
    Dialog->>Uploader: start upload
    Uploader-->>Dialog: success / error
  end

  rect lightgrey
  Note over Dialog: onError handler
  alt error is SilentError
    Dialog->>Dialog: Suppress global error dialog
  else other error
    Dialog->>Dialog: Show global error dialog
  end
  end
Loading
sequenceDiagram
  autonumber
  participant Caller as Rust API
  participant FFmpeg as ffmpeg::format

  Caller->>FFmpeg: ffmpeg::init() (best-effort / guarded)
  Caller->>FFmpeg: format::input(path)
  alt input ok (has video stream)
    FFmpeg-->>Caller: Input context (duration, streams)
    Caller->>Caller: duration = input.duration() / AV_TIME_BASE
    Caller-->>Caller: return valid + duration
  else input err or no video
    FFmpeg-->>Caller: error / no video
    Caller-->>Caller: return invalid / error
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

codex

Poem

I thump my paw and hold my breath,
A tiny pause avoids a fret,
I swap a crate, I tweak a name,
I hop through streams and tame their frame,
🐇✨ Quiet fixes, tidy code.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly describes the core issue being addressed—the incorrect enforcement of the five-minute studio export limit—without extraneous detail or noise, making it clear to reviewers what bug is being fixed.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-5min-studio-mode-limit

📜 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 83db782 and 7052a33.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Clippy
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (1)
.github/workflows/ci.yml (1)

96-101: Clippy component install looks good

Adding the clippy component ensures the subsequent clippy-check step has the tool available. 👍


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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9054998 and 88fc640.

📒 Files selected for processing (1)
  • apps/desktop/src/routes/editor/ExportDialog.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/desktop/**/*.{ts,tsx}: Do not manually import icons in the desktop app; rely on auto-imported icons
In the desktop app, use @tanstack/solid-query for server state management

Files:

  • apps/desktop/src/routes/editor/ExportDialog.tsx
**/*.{ts,tsx,js,jsx,rs}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not add inline, block, or docstring comments in any language; code must be self-explanatory

Files:

  • apps/desktop/src/routes/editor/ExportDialog.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use strict TypeScript and avoid any; leverage shared types from packages

**/*.{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/ExportDialog.tsx
**/*.{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/ExportDialog.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (2)
apps/desktop/src/routes/editor/ExportDialog.tsx (2)

50-50: LGTM!

The custom error class is well-named and appropriately scoped for internal use within this module.


381-385: LGTM!

The error handling logic correctly suppresses dialogs for SilentError while preserving user feedback for genuine errors. State cleanup happens consistently regardless of error type.

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: 2

🧹 Nitpick comments (1)
apps/desktop/src-tauri/src/lib.rs (1)

48-48: Avoid relying on FFI constant if a safe wrapper exists

Using ffmpeg::ffi::AV_TIME_BASE couples to C FFI. Prefer a safe abstraction (e.g., rescaling via stream time_base or a crate-provided constant accessor) if available.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88fc640 and b0e5840.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • apps/desktop/src-tauri/Cargo.toml (0 hunks)
  • apps/desktop/src-tauri/src/lib.rs (4 hunks)
💤 Files with no reviewable changes (1)
  • apps/desktop/src-tauri/Cargo.toml
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx,rs}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not add inline, block, or docstring comments in any language; code must be self-explanatory

Files:

  • apps/desktop/src-tauri/src/lib.rs
**/*.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:

  • apps/desktop/src-tauri/src/lib.rs
🧬 Code graph analysis (1)
apps/desktop/src-tauri/src/lib.rs (2)
crates/enc-ffmpeg/src/mux/mp4.rs (1)
  • init (31-67)
crates/media/src/lib.rs (1)
  • init (12-16)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (1)
apps/desktop/src-tauri/src/lib.rs (1)

67-67: LGTM

BufWriter import is appropriate and used in PNG encoding.

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

♻️ Duplicate comments (3)
apps/desktop/src-tauri/src/lib.rs (3)

889-892: sum::<Result<_, _>>() likely fails to compile

The previously flagged compile issue remains: use try_fold(0.0, |acc, p| get_duration_for_path(p).map(|d| acc + d))? to properly accumulate Results and short-circuit on error.

Based on past review comment.


680-682: is_valid_mp4 still accepts any FFmpeg-openable format

This implementation returns true for any container FFmpeg can open, but callers assume MP4. The previously suggested fix remains applicable:

  • Verify .mp4 extension (case-insensitive)
  • Check FFmpeg init with is_err() pattern
  • Confirm at least one video stream exists

Based on past review comment suggesting the same fix.


866-871: Missing guard for unknown duration

input.duration() can be unknown (≤ 0). The previously suggested fix remains necessary: check if duration > 0 before dividing by AV_TIME_BASE, otherwise handle gracefully (return 0.0 or error with context).

Based on past review comment.

🧹 Nitpick comments (1)
apps/desktop/src-tauri/src/lib.rs (1)

1818-1822: Consider failing fast on FFmpeg init failure

While the current approach allows graceful continuation, FFmpeg operations will fail later anyway. Consider either:

  1. Making init failure more visible (e.g., show error dialog)
  2. Failing fast if FFmpeg is critical to core functionality

However, is_valid_mp4 (line 681) doesn't check if init succeeded before calling FFmpeg functions, which could cause silent failures.

As per coding guidelines

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b0e5840 and ddeb2f9.

📒 Files selected for processing (1)
  • apps/desktop/src-tauri/src/lib.rs (5 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx,rs}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not add inline, block, or docstring comments in any language; code must be self-explanatory

Files:

  • apps/desktop/src-tauri/src/lib.rs
**/*.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:

  • apps/desktop/src-tauri/src/lib.rs
🧬 Code graph analysis (1)
apps/desktop/src-tauri/src/lib.rs (2)
crates/enc-ffmpeg/src/mux/mp4.rs (1)
  • init (31-67)
crates/media/src/lib.rs (1)
  • init (12-16)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (2)
apps/desktop/src-tauri/src/lib.rs (2)

48-48: LGTM!

The AV_TIME_BASE import is necessary for FFmpeg duration calculations and is used correctly at line 869.


67-67: LGTM!

Correct import for the BufWriter usage at line 1239 in the PNG encoding path.

@oscartbeaumont oscartbeaumont changed the title Improve the 5 min studio export limit dialog Fix the 5 min studio export limit being enforced incorrectly Oct 2, 2025
@oscartbeaumont oscartbeaumont marked this pull request as draft October 2, 2025 13:09
@oscartbeaumont oscartbeaumont marked this pull request as ready for review October 2, 2025 13:16
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: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ddeb2f9 and 2dfae28.

📒 Files selected for processing (1)
  • apps/desktop/src-tauri/src/lib.rs (8 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx,rs}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not add inline, block, or docstring comments in any language; code must be self-explanatory

Files:

  • apps/desktop/src-tauri/src/lib.rs
**/*.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:

  • apps/desktop/src-tauri/src/lib.rs
🧬 Code graph analysis (1)
apps/desktop/src-tauri/src/lib.rs (2)
crates/rendering/src/project_recordings.rs (4)
  • new (20-48)
  • new (64-88)
  • duration (178-180)
  • duration (196-207)
crates/media/src/lib.rs (1)
  • init (12-16)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Analyze (rust)

@Brendonovich Brendonovich merged commit c1e481a into main Oct 2, 2025
15 checks passed
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