fix(desktop): upload videos without ffmpeg on macOS - #6532
Conversation
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Use macOS's built-in AVFoundation converter when ffmpeg is unavailable, including the extensionless temp-file shape used by deferred uploads. The fallback strips source metadata by default and produces fast-start H.264 MP4 accepted by the relay. Co-authored-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Remove partial staged sources when a fallback copy fails, and honor cancellation before starting AVFoundation conversion. Co-authored-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Run the extensionless QuickTime conversion against a tiny checked-in H.264 fixture on every macOS test pass, and validate all AVFoundation output with the relay's production video validator before upload. Co-authored-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Keep the macOS production dependency for avconvert validation while retaining the dev dependency used by cross-platform snapshot contract tests. Co-authored-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
wesbillman
left a comment
There was a problem hiding this comment.
Carl, an automated reviewer, commenting via Wes’s GitHub account.
Reviewed base f7942167372501576c9f0f589cf2c166882668bb through exact head d10c1b5352c1370d6006810bd577205563740d80.
No blocking correctness finding. I traced both picker and deferred raw-byte upload paths through video detection, ffmpeg/avconvert selection, extensionless source staging, process cancellation/timeout, temp-file cleanup, relay-format validation, upload, composer recovery, and raw Tauri error presentation.
The macOS fallback uses the absolute system binary with a cleared environment, preserves the existing ffmpeg path where available, cleans staged/output files on failure and cancellation, and validates avconvert output with the relay's actual video validator before upload. The checked-in extensionless QuickTime fixture exercises avconvert and that validator. The frontend change correctly preserves non-empty raw string rejections while retaining the fallback for empty or non-text values.
git diff --check passed and the review worktree was clean at the exact head. The PR's focused macOS fixture/live-relay evidence and pre-push results cover the changed behavior. GitHub CI was still running when this review completed, so I am not claiming a final CI result and did not duplicate its broad suites locally.
jedwards27
left a comment
There was a problem hiding this comment.
:bot: Jude’s code review agent
Verdict: COMMENT — no blocking correctness finding
Reviewed: f7942167372501576c9f0f589cf2c166882668bb..d10c1b5352c1370d6006810bd577205563740d80 (exact head d10c1b5352c1370d6006810bd577205563740d80)
Risk: high — this changes macOS native process/filesystem handling, cancellation and cleanup, media-format enforcement, a production dependency edge, and user-visible upload failure reporting.
Behavior/contracts traced: picker and deferred paste/drop paths through detection, fd lifetime, staging, ffmpeg/avconvert selection, cancellation/timeout, process reaping, relay-format validation, upload, cleanup, and raw Tauri error presentation. I also checked the platform fence, dependency target gate, and the change against VISION.md / TESTING.md; I found no conflicting product or test-policy expansion.
Findings: no blocking issue.
- The fallback invokes absolute
/usr/bin/avconvertwith a cleared environment and no shell/PATH lookup, a finite 600s timeout, kill-and-reap cancellation, UUID temporary names, and cleanup across success/error/cancellation (desktop/src-tauri/src/commands/media_transcode.rs:450-577). Extensionless deferred sources are staged with a magic-derived extension using hard-link then bounded copy fallback; the original picker fd remains pinned. - Converted output is passed through the relay's production validator before upload (
media_transcode.rs:489-516,568-569;crates/buzz-media/src/validation.rs:290-416,847-943), enforcing size, MP4/H.264/AAC, duration/resolution, fast-start, track shape, and metadata constraints. Existing ffmpeg selection remains first, while non-macOS retains the prior ffmpeg-required error (media_transcode.rs:589-600). - Non-empty raw string rejections now remain actionable instead of becoming
Unknown error(desktop/src/features/messages/ui/useMentionSendFlow.helpers.ts:84-91). - Native macOS probes normalized Apple-generated HEVC MOV/M4V/MP4 and ProRes MOV to H.264 MP4. VP9 WebM and one ffmpeg-authored HEVC MOV were rejected with actionable stderr rather than uploading unsupported bytes. A separate generated HEVC QuickTime source produced H.264/
avc1output verified withffprobe. Temp residue scans found nobuzz-avconvert-*,buzz-avconvert-source-*, orbuzz-drop-*files.
Validation at matching clean head:
just desktop-tauri-test— pass; primary Tauri target2744 passed, 0 failed, 18 ignored, plus integration/workspace targets and both new avconvert tests.cd desktop && pnpm test/ repositoryjust desktop-testpath — pass;5354 passed, 0 failed.git diff --check— pass.- GitHub CI at submission: macOS Desktop Build, Rust Lint, all Desktop smoke/integration lanes, release-candidate contract, and DCO pass. Desktop Core and Windows Rust remain in progress, so this review does not claim final CI clearance.
Non-blocking risk / residual evidence limits:
- The macOS-target-gated normal
buzz-mediadependency adds roughly 23 production graph packages versus base, including storage/XML/system-information dependencies, solely to reuse the validator (desktop/src-tauri/Cargo.toml:61). This is packaging weight and coupling rather than a demonstrated functional defect; a validator-only feature or crate would be a useful follow-up. - The new avconvert regression test invokes
validate_avconvert_outputseparately after conversion (media_transcode.rs:659-675), so it would not fail if the production validation call at line 568 were removed. The production call is correct, but the test is not mutation-grade coverage of that wiring. - The fallback intentionally returns no generated poster (
media_transcode.rs:596). Stock macOS users without ffmpeg get a playable, validated upload with dimensions/duration but noBlobDescriptor.image; that is a visible quality degradation, not data loss or a blocker for the stated fix. - I did not independently exercise an installed/signed DMG upload or repeat the author-reported live-relay upload. The native conversion boundary was exercised directly on macOS with codec probes and the full Tauri suite; installed-artifact handoff remains residual risk.
Because the PR author's GitHub identity is also the review identity available here, this is filed as a comment rather than a self-approval. Final merge remains gated on the two running CI jobs.
Preserve both the new address-locked mention coverage from main and the deferred upload error regression coverage from this branch. Co-authored-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
jedwards27
left a comment
There was a problem hiding this comment.
:bot: Jude’s code review agent
Verdict: COMMENT — no blocking code finding; do not merge while the exact-head required Unit Tests gate is red
Reviewed: base 8c0f42e187ca82d701251fc849217530178ebace through exact head acde61c588a7c27185197dcbc9b2c970e19b1ca7.
The refreshed head is a merge of current main into the previously reviewed branch. The native media implementation, fixture, and macOS dependency declaration are byte-identical to the prior head. The only conflict-resolution delta in the PR surface preserves main’s address-locked mention helper/types while retaining this PR’s raw Tauri-string error handling. The three-dot PR scope remains six files; I found no unrelated schema, identity, migration, protocol, or release expansion.
No blocking correctness or product defect was found in the code at this head:
- The fallback remains macOS-only and ffmpeg-first; non-macOS keeps the prior ffmpeg-required path (
desktop/src-tauri/src/commands/media_transcode.rs:589-600). /usr/bin/avconvertis invoked by absolute path without a shell, under a cleared environment, bounded timeout, cancellation, and kill-and-wait reaping (media_transcode.rs:125-186,524-576).- Extensionless deferred inputs are magic-sniffed, staged by hard-link or bounded copy, and cleaned on success/error/cancellation (
media_transcode.rs:450-486,528-576; caller cleanup atdesktop/src-tauri/src/commands/media.rs:728-746). - Converted output is passed through the relay’s production
validate_video_filebefore bytes are read and uploaded (media_transcode.rs:489-516,568-569;crates/buzz-media/src/validation.rs:290-416). This enforces upload size, MP4/H.264/AAC, duration/resolution, fast-start, track shape, and metadata constraints. - Non-empty raw Tauri errors remain actionable while normal
Error.messageand fallback behavior are preserved (desktop/src/features/messages/ui/useMentionSendFlow.helpers.ts:84-91). - The fallback intentionally returns no generated poster (
media_transcode.rs:596). This is visible degradation for stock-macOS users without ffmpeg, but not a failure of the stated upload fix.
Exact-head validation:
just desktop-tauri-test— pass; primary target 2755 passed, 0 failed, 18 ignored, with all package integration/doc targets and both avconvert tests passing.cd desktop && pnpm test— pass, 5391/5391.git diff --check— pass.- Post-test residue scan found no
buzz-avconvert-*,buzz-avconvert-source-*, orbuzz-drop-*files. - HEAD remained
acde61c588a7c27185197dcbc9b2c970e19b1ca7and the review trees were clean after validation.
Merge condition: GitHub Unit Tests is failing at this exact head (job 97045315168): Linux cannot link sherpa-onnx-sys because sherpa-onnx-c-api is missing. The same failure is present on base 8c0f42e187ca82d701251fc849217530178ebace, so it is evidenced as a merged-main/base regression rather than a defect introduced by this six-file PR diff. Rust lint, Desktop Core/build, Windows Rust, Desktop smoke/integration, relay, security, and DCO pass. Nevertheless, the required repository gate is not green: rerun or fix it before merge.
Residual risk:
- The avconvert regression test separately invokes validation after conversion, so mutation-removing the production validator call at line 568 still leaves that test green. Production wiring is present and correctly placed, but the test is not causal protection for that call site.
- The macOS-target-gated normal
buzz-mediadependency is broad coupling solely to reuse validation (desktop/src-tauri/Cargo.toml:61). A validator-only feature/crate would reduce production graph breadth. - No exact-head installed/signed artifact plus real relay upload was independently exercised. The release-candidate workflow’s validation step was skipped and produced no artifact; native conversion and package tests do not prove installed-app handoff.
- Poster omission remains the intentional quality tradeoff described above.
Because the PR author’s GitHub identity is also the review identity available here, this is filed as a comment rather than a self-approval.
Summary
Unknown error.avconvertwhenffmpegis unavailable, while keeping the existing ffmpeg path on configured systems.Related issue
N/A. No matching open issue or PR found.
Testing
avconvert, and runs the result throughvalidate_video_file.896768fbf0f387d4cf092927b88f7a1e46321bd5: file-size gate plus Tauri clippy and full Tauri Rust tests. The prior push atec68dccf3379363bd31d1b729730fc7e27bfec18also passed desktop Biome, typecheck, and JavaScript tests.