feat: Implement Windows ARM build
Summary by CodeRabbit
-
New Features
- Windows ARM64 build added; publish workflow inputs to select Windows target and toggle macOS builds. Build matrix expanded with platform/arch entries and run gating.
-
Bug Fixes
- Clamp invalid recording segment durations with warnings.
- Safer FPS/duration estimation with multiple fallbacks and warnings.
- More reliable encoder setup, header handling and flush/error propagation.
-
Chores
- Architecture-aware FFmpeg retrieval; platform-targeted dependency layouts.
- Desktop app version bumped.
Walkthrough
Added Windows ARM64 target across configs and CI; expanded per-target Cargo dependencies; extended publish workflow with platform/arch matrix and RUN_BUILD gating; made FFmpeg setup architecture-aware; validated/clamped recording durations and updated TimelineSegment field; adjusted Windows encoder locking/flush and FPS/duration fallbacks; bumped desktop version.
Changes
| Cohort / File(s) | Summary |
|---|---|
Hakari config /.config/hakari.toml |
Added aarch64-pc-windows-msvc to platforms. |
CI workflows .github/workflows/ci.yml |
Added aarch64-pc-windows-msvc to job matrices and updated Clippy condition to include it. |
Publish workflow .github/workflows/publish.yml |
Added inputs windowsTarget and buildMac; expanded matrix to include platform/arch; introduced RUN_BUILD gating across build/sign/upload steps; adjusted tag creation/async usage and payloads. |
Workspace dependencies crates/workspace-hack/Cargo.toml |
Replaced direct getrandom with an aliased entry and added extensive per-target [target.*.dependencies] and build-dependencies for macOS aarch64 and Windows (x86_64/aarch64). |
FFmpeg setup script scripts/setup.js, package.json |
Architecture-aware FFmpeg ZIP selection (latest release), arch fallback to x86_64, computed names/paths, standardized download/extract/rename variables, and updated PowerShell vswhere invocation. |
Desktop version apps/desktop/src-tauri/Cargo.toml |
Bumped package version 0.3.82 β 0.3.83. |
Recording: timeline segments apps/desktop/src-tauri/src/recording.rs |
Clamp non-finite/non-positive segment durations to 0.0 with a warning; use recording_segment (was recording_clip) and set segment start to 0.0. |
Recording: encoder path crates/recording/src/output_pipeline/win.rs |
Make Windows encoder path message-driven, acquire output lock before queuing/flush, move header write into encoder thread, consolidate AsFFmpeg usage, and propagate errors via ready signaling. |
Rendering: duration/fps guards crates/rendering/src/project_recordings.rs |
Guard fps/division by zero; compute duration from container, stream, packets, or frames/fps fallbacks; clamp non-finite/<=0 durations to 0.0 and log diagnostics. |
FFmpeg encoding metadata crates/enc-ffmpeg/src/video/h264.rs |
Initialize and assign AVRational frame-rate fields on the output stream from input frame rate (unsafe block added). |
Sequence Diagram(s)
sequenceDiagram
autonumber
participant User as Trigger
participant Publish as .github/workflows/publish.yml
participant Matrix as build matrix
participant Runner as GitHub runner
User->>Publish: start workflow (inputs: windowsTarget, buildMac)
Publish->>Matrix: expand to entries with platform + arch
Publish->>Publish: compute RUN_BUILD based on matrix + inputs
alt RUN_BUILD == true
Matrix->>Runner: run gated build/sign/upload steps
else RUN_BUILD == false
Publish-->>Runner: skip build steps
end
sequenceDiagram
autonumber
participant Setup as scripts/setup.js
participant GH as GitHub Releases
participant Cache as local cache
Setup->>GH: request "latest" release assets
GH-->>Setup: return asset list
Setup->>Setup: pick asset by arch (aarch64 or x86_64), fallback to x86_64
alt asset found
Setup->>Cache: download ZIP -> extract -> rename -> cache
else asset missing
Setup-->>Setup: fallback handling (use x86_64)
end
Estimated code review effort
π― 4 (Complex) | β±οΈ ~60 minutes
Points to review closely:
crates/workspace-hack/Cargo.tomlβ large per-target dependency lists and aliasedgetrandom..github/workflows/publish.ymlβ correctness ofRUN_BUILDexpression, new inputs, matrix expansion, and step gating.scripts/setup.jsβ FFmpeg asset selection/fallback, extraction/rename, and PowerShellvswhereinvocation.crates/recording/src/output_pipeline/win.rsβ encoder message handling, header write relocation, flush and locking semantics.crates/rendering/src/project_recordings.rsβ duration/fps fallback logic and logging correctness.
Possibly related PRs
- CapSoftware/Cap#1297 β touches
crates/recording/src/output_pipeline/win.rsand encoder setup; overlaps with Windows encoder changes. - CapSoftware/Cap#1121 β modifies Windows recording/encoding pipeline and frame handling; related to message-driven changes.
- CapSoftware/Cap#976 β touches Windows target configuration and dependency manifests; related to added aarch64 Windows target.
Suggested reviewers
- Brendonovich
Poem
π I hop through CI and Cargo trees,
ARM64 now joins the Windows breeze,
FFmpeg zips pick arch with care,
Durations clamped, encoders flush and share,
Version bumped β I nibble a carrot, bright! π₯
Pre-merge checks and finishing touches
β Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | β οΈ Warning | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
β 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 accurately describes the main change: implementing Windows ARM build support across multiple configuration files, CI/CD workflows, and dependencies. |
β¨ Finishing touches
- [ ] π Generate docstrings
π§ͺ Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
- [ ] Commit unit tests in branch
windows-arm
π 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 d8aec67491150f9c68624fcd23607408d586fb35 and d7cd6244995f410e5240033ab7816986ad2d3a49.
π Files selected for processing (1)
crates/rendering/src/project_recordings.rs(1 hunks)
π§° Additional context used
π Path-based instructions (2)
**/*.rs
π CodeRabbit inference engine (AGENTS.md)
**/*.rs: Format Rust code usingrustfmtand 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/rendering/src/project_recordings.rs
crates/*/src/**/*
π CodeRabbit inference engine (AGENTS.md)
Rust crates should place tests within the
src/and/or a siblingtests/directory for each crate insidecrates/*.
Files:
crates/rendering/src/project_recordings.rs
π§ Learnings (2)
π Learning: 2025-10-17T05:58:22.586Z
Learnt from: Brendonovich
Repo: CapSoftware/Cap PR: 1219
File: crates/enc-avfoundation/src/mp4.rs:350-373
Timestamp: 2025-10-17T05:58:22.586Z
Learning: In crates/enc-avfoundation/src/mp4.rs, the `finish()` method intentionally skips video extension when `is_paused` is true. This is correct behavior because if recording is paused, the video should not be extended beyond the pause pointβthe pause is user-initiated, unlike the case where ScreenCaptureKit stops providing frames during static content.
Applied to files:
crates/rendering/src/project_recordings.rs
π Learning: 2025-10-28T08:39:42.230Z
Learnt from: Brendonovich
Repo: CapSoftware/Cap PR: 1305
File: crates/recording/src/output_pipeline/macos.rs:80-90
Timestamp: 2025-10-28T08:39:42.230Z
Learning: In `crates/recording/src/output_pipeline/macos.rs`, the `AVFoundationMp4Muxer` intentionally holds the `Mutex<MP4Encoder>` lock during retry attempts in `send_video_frame()` and `send_audio_frame()`. This blocking behavior is correct because frame processing must happen sequentially to prevent audio and video frames from being interleaved incorrectly in the encoder.
Applied to files:
crates/rendering/src/project_recordings.rs
𧬠Code graph analysis (1)
crates/rendering/src/project_recordings.rs (2)
apps/desktop/src-tauri/src/export.rs (1)
fps(17-22)apps/desktop/src/utils/tauri.ts (1)
Video(484-484)
β° 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 (aarch64-apple-darwin, macos-latest)
- GitHub Check: Clippy (aarch64-pc-windows-msvc, windows-latest)
- GitHub Check: Clippy (x86_64-pc-windows-msvc, windows-latest)
- GitHub Check: Analyze (rust)
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
looks like a merge went wrong or something, a bunch of changes have been undone