Skip to content

fix: preserve embedded desktop audio in browser exports with mic sidecars - #984

Open
mvanhorn wants to merge 1 commit into
webadderallorg:mainfrom
mvanhorn:fix/792-recordly-browser-export-embedded-audio
Open

mvanhorn wants to merge 1 commit into
webadderallorg:mainfrom
mvanhorn:fix/792-recordly-browser-export-embedded-audio

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Pull Request Template

In src/lib/exporter/modernVideoExporter.ts, compute the browser audio source list from the loaded videoInfo using the existing getNativeAudioFallbackPaths normalization, which includes the local video when it has embedded audio and companion files are present. Pass that normalized list into the existing AudioProcessor.process call and its source-presence guard, preserving delay metadata, source settings, clips, trims, and speed edits; if the helper is renamed to describe its shared use, update its existing native caller in this same file. This causes the existing production routing in audioEncoder.ts to recognize embedded audio plus a microphone sidecar and use the established offline mixer instead of the single-sidecar fast path, without changing the routing policy or introducing a helper only used by tests.

The reporter hears system and microphone audio in the editor but gets an MP4 without any audio stream, confirmed with ffprobe, across Recordly versions through 1.3.5 on Windows 7 using VxKex-NEXT. They also report Lightning Export failure, but the bundle supplies only an external screenshot URL, not its error text. A second human reports on September 15 that Windows 11 exports retain microphone audio while losing desktop audio. The current clone contains a deterministic source-routing mismatch that can produce that second symptom, although neither reporter supplied a project establishing that this is their exact execution path.

Fixes #792

Description

In src/lib/exporter/modernVideoExporter.ts, compute the browser audio source list from the loaded videoInfo using the existing getNativeAudioFallbackPaths normalization, which includes the local video when it has embedded audio and companion files are present. Pass that normalized list into the existing AudioProcessor.process call and its source-presence guard, preserving delay metadata, source settings, clips, trims, and speed edits; if the helper is renamed to describe its shared use, update its existing native caller in this same file. This causes the existing production routing in audioEncoder.ts to recognize embedded audio plus a microphone sidecar and use the established offline mixer instead of the single-sidecar fast path, without changing the routing policy or introducing a helper only used by tests.

Motivation

Covered in the summary above.

Type of Change

  • New Feature
  • Bug Fix
  • Refactor / Code Cleanup
  • Documentation Update
  • Other (please specify)

Related Issue(s)

Not applicable to this change.

Screenshots / Video

No user-visible surface changes in this PR, so there is nothing to show.

Testing Guide

Regression: embedded desktop audio plus only C:\recordly\recording.mic.wav in the original fallback list, no edits, default source gains, and browser AAC support available. Public browser export must pass video plus microphone paths into the real audio routing boundary; the processor must mix both instead of demuxing only the microphone.
Reuse the existing audio preparation harness with distinguishable embedded and microphone buffers, asserting both reach the mix. Assert the WAV case goes through renderAndMuxOfflineAudio, not loadAudioFileDemuxer; do not test only a newly extracted helper.
Simulate native export failure followed by the existing browser retry with the same metadata and companion list. Assert the retried export retains both sources and does not retry indefinitely.
No embedded audio plus one mic sidecar must retain the direct single-sidecar path. Embedded-only and genuinely silent source videos must retain their current export behavior.
A video already present in the fallback list, including Windows file-URL/path representations, must not be added twice. Existing system+mic companions must retain dedicated-track precedence and avoid double-mixing an embedded copy.
Preserve explicit companion start delays, trim/speed edits, and source mute/volume settings when passing the normalized list. Rerun existing tests covering cancellation and clip mute; no new behavior is needed for these cases.
Validation during implementation: npm test -- src/lib/exporter/modernVideoExporter.fallback.test.ts src/lib/exporter/audioEncoder.test.ts src/lib/exporter/modernVideoExporter.nativeStaticLayout.test.ts src/lib/exporter/sourceTrackRoutingPolicy.test.ts src/lib/exporter/sourceAudioFallback.test.ts, followed by the repository TypeScript check using installed tooling and focused lint. Planning did not install dependencies or run tests.
When a suitable runtime is available, export a short local video with an embedded system tone and a separate microphone tone through the browser route; ffprobe must report an audio stream and playback must contain both tones without doubled gain or timing drift. An audio stream alone is insufficient proof of retaining desktop audio. Verify both buffer and file-backed output using existing export modes. Do not claim Windows 7 or Lightning reproduction without that environment and the missing error details.

Checklist

  • I have performed a self-review of my code.
  • I have added any necessary screenshots or videos.
    Not verified: this needs a person on the named hardware or environment.
  • I have linked related issue(s) and updated the changelog if applicable.

Thank you for contributing!

Summary by CodeRabbit

  • Bug Fixes
    • Improved audio handling during video exports when embedded audio and microphone or system audio fallback files are used.
    • Prevented duplicate audio sources when local video files are referenced through different path formats.
    • Improved retry behavior when switching export processing methods.
    • Skipped unnecessary audio processing for silent video sources.
    • Improved Windows path handling for offline audio exports.

@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: c5f33dff-926e-4d30-a1c6-2f3326bc83b9

📥 Commits

Reviewing files that changed from the base of the PR and between b3ea775 and bdeaf6b.

📒 Files selected for processing (3)
  • src/lib/exporter/audioEncoder.test.ts
  • src/lib/exporter/modernVideoExporter.fallback.test.ts
  • src/lib/exporter/modernVideoExporter.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The exporter now normalizes audio fallback paths before audio finalization and native audio-plan construction. Tests cover Windows paths, sidecar deduplication, embedded and silent sources, native-to-WebCodecs retry, and offline audio preparation.

Changes

Audio fallback routing

Layer / File(s) Summary
Normalized fallback path integration
src/lib/exporter/modernVideoExporter.ts
Audio finalization and native audio-plan construction now use normalized fallback paths. AudioProcessor.process receives the normalized list.
Browser audio routing coverage
src/lib/exporter/modernVideoExporter.fallback.test.ts
Tests cover embedded audio, sidecar forwarding, companion options, retry behavior, Windows path deduplication, demuxer routing, microphone-only routing, and silent sources.
Offline sidecar preparation coverage
src/lib/exporter/audioEncoder.test.ts
Tests cover Windows path decoding, microphone-only trimming, and dedicated system and microphone sidecars.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: webadderall

Merge Risk: ⚪ Minimal · up to bdeaf

The updated export paths consistently preserve embedded and sidecar audio routing, with no identified merge-blocking risk.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary bug fix: preserving embedded desktop audio when a microphone sidecar is present during browser exports.
Description check ✅ Passed The description is detailed and covers the change, motivation, bug-fix classification, testing guidance, and checklist. It references issue #792, although the Related Issue(s) section incorrectly says…
Linked Issues check ✅ Passed Issue #792 requires exported video files to retain recorded system and microphone audio. The exporter now normalizes browser audio fallback paths from video metadata, uses the normalized paths for aud…
Out of Scope Changes check ✅ Passed The source changes and added tests address browser audio-source normalization and offline mixer routing. The tests validate embedded audio, microphone sidecars, path deduplication, timing metadata, an…
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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.

[Bug]: Audio is recording perfectly, but no Audio in exported File

1 participant