Skip to content

feat: Adding background sound effects. #235

Closed
prayaslashkari wants to merge 8 commits intosiddharthvaddem:mainfrom
prayaslashkari:feature/bg-sound-effects
Closed

feat: Adding background sound effects. #235
prayaslashkari wants to merge 8 commits intosiddharthvaddem:mainfrom
prayaslashkari:feature/bg-sound-effects

Conversation

@prayaslashkari
Copy link
Contributor

@prayaslashkari prayaslashkari commented Mar 18, 2026

Pull Request Template

Description

Adds background music (sound effects) support to the video editor. Users can select a bundled music track or upload a custom MP3, preview it live during playback, adjust volume, and have it automatically mixed into the final exported video.

What changed

  • Shared constants (constants.ts) — Extracts WALLPAPERS, GRADIENTS, AUDIO_TRACKS, and resolveBackgroundMusicUrl into a single module, removing duplication between SettingsPanel and projectPersistence.
  • Audio assets (public/audio/) — Bundles the first built-in track (Upbeat Happy Corporate). New tracks can be added by dropping an MP3 and registering it in AUDIO_TRACKS.
  • Project persistence — Adds backgroundMusic (track ID or data URL) and backgroundMusicVolume (0–1) to ProjectEditorState with validation in normalizeProjectEditor, so selections survive save/load.
  • Settings panel UI — New Sound Effects accordion section with track selection buttons, custom MP3 upload via FileReader, and a volume slider that appears when a track is active.
  • Live preview (VideoPlayback) — Manages a looping HTMLAudioElement that syncs play/pause with the video and updates volume reactively.
  • Export pipeline (audioEncoder + videoExporter) — Fetches and decodes background music via the Web Audio API, mixes it with source audio PCM (both trim-only and speed-region paths), and passes the result to the muxer. Also handles videos with no source audio track.

Motivation

Screen recordings typically have no music, making demos and tutorials feel flat. This feature lets creators add background music without leaving the editor. The original audio is preserved and mixed at a user-controlled volume, keeping the workflow non-destructive. The architecture is extensible, i.e., adding a new bundled track is a one-line addition to AUDIO_TRACKS.

Type of Change

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

Related Issue(s)

Screenshots / Video

Screenshot (if applicable):
Expanded
image
Collapsed
image

Volume Slider
image

Custom Audio
image

Video (if applicable):

audio-bg-effect.mov

Testing

Checklist

  • I have performed a self-review of my code.
  • I have added any necessary screenshots or videos.
  • I have linked related issue(s) and updated the changelog if applicable.

Thank you for contributing!

Extract WALLPAPERS, GRADIENTS, AUDIO_TRACKS, DEFAULT_BG_MUSIC_VOLUME, and
resolveBackgroundMusicUrl into a dedicated constants.ts to eliminate
duplication between SettingsPanel and projectPersistence.
Add upbeat-happy-corporate.mp3 as the first bundled background music track.
Add backgroundMusic (track id or data URL) and backgroundMusicVolume fields
to ProjectEditorState with validation/normalization in normalizeProjectEditor.
Also refactor WALLPAPER_PATHS to derive from the shared WALLPAPERS constant.
- Add Music accordion section with built-in and custom audio track selection
- Support uploading custom MP3 files as background music
- Show volume slider when a track is active
- Refactor inline WALLPAPERS/GRADIENTS arrays to use shared constants
Thread backgroundMusic and backgroundMusicVolume state into persistence,
export config, SettingsPanel props, and VideoPlayback props.
- Add bgAudioRef to hold a looping HTMLAudioElement for background music
- Sync audio play/pause with the video playback state
- Adjust volume reactively via a dedicated effect
- Resolve bundled track IDs or data URLs via resolveBackgroundMusicUrl
- audioEncoder: support mixing a background music AudioBuffer with the source
  audio track using the Web Audio API; handles videos with no source audio
- videoExporter: pass backgroundMusicUrl and backgroundMusicVolume through
  to AudioProcessor; include background music in hasAudio decision for muxer
@coderabbitai
Copy link

coderabbitai bot commented Mar 18, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c36836c4-90bc-4049-a6ff-4da227de0de5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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

When a video has no source audio track, the background-music-only
generation path was writing raw samples at full volume, ignoring the
user's volume setting. Scale bgSamples by the gain before encoding.
import type { ProjectMedia } from "@/lib/recordingSession";
import { normalizeProjectMedia } from "@/lib/recordingSession";
import { ASPECT_RATIOS, type AspectRatio } from "@/utils/aspectRatioUtils";
import { DEFAULT_BG_MUSIC_VOLUME, WALLPAPERS } from "./constants";
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I should probably move it to assets/constants.

@siddharthvaddem Wdy think?

Copy link
Owner

Choose a reason for hiding this comment

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

yup.

Copy link
Owner

Choose a reason for hiding this comment

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

@prayaslashkari could you briefly explain how it works when an audio clip is 10 seconds, and the video is 1 min. or the audio is 1 min and the video is 5 seconds, Is this audio configurable element? or would that just be added to the track from start to end. Idk if I'm making sense?

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.

2 participants