Skip to content

Add/remove/solo tracks#41

Open
PlkMarudny wants to merge 7 commits into
ronak-create:mainfrom
PlkMarudny:add-tracks
Open

Add/remove/solo tracks#41
PlkMarudny wants to merge 7 commits into
ronak-create:mainfrom
PlkMarudny:add-tracks

Conversation

@PlkMarudny

@PlkMarudny PlkMarudny commented Jul 23, 2026

Copy link
Copy Markdown
Contributor
image

What does this PR do?

Add/delete/solo track feature has been added. +V adds a video track, +A add an audio track. Empty track can be removed via a context menu.
Each track has an additional 'solo' button, that toggles the active state of it, disabling other tracks.

Type of change

  • Bug fix
  • New feature (GUI/API)
  • Docs
  • Refactor / internal

How was it verified?

  • node --check server.js && node --check app.js && node --check mcp-server.js passes
  • Opened the editor and confirmed the change in preview
  • Confirmed the change in an export (fast or realtime), if it affects rendering
  • Updated CLAUDE.md / README.md if the schema, props, or API changed

Checklist

  • No new runtime dependencies added
  • Preview and export render identically (single compositor)
  • Commits are focused and messages are descriptive

Summary by CodeRabbit

  • New Features
    • Data-driven timeline tracks with +V / +A track creation, empty-track removal via context menu, and updated keyboard shortcuts.
    • More robust solo behavior with clearer toggle/restore interactions.
    • Projects now persist dynamic track setup, including variable video/audio counts.
    • Upgraded linked audio from fixed stereo to N-way per-channel stems with synchronized editing/playback and discrete routing.
  • Documentation
    • Updated schema and README editing guidance for dynamic tracks, channel labeling, and removal/solo rules.
  • Style
    • Refreshed track header layout and controls, including improved solo button visuals and context menu styling.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e9173e71-6d13-45f9-bc18-abc9a13d3c32

📥 Commits

Reviewing files that changed from the base of the PR and between f35266f and 1fc4700.

📒 Files selected for processing (2)
  • README.md
  • app.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • README.md

📝 Walkthrough

Walkthrough

The PR replaces fixed timeline tracks with persisted dynamic video/audio lanes, adds lane creation, removal, enable, and solo controls, and extends linked audio from stereo pairs to discrete multichannel stems across playback, metering, display, and export.

Changes

Dynamic tracks and multichannel audio

Layer / File(s) Summary
Dynamic track model and project persistence
app.js, CLAUDE.md
Track definitions are generated, loaded, persisted, validated against clips, and applied to shared track-height and audio-track state.
Track controls and timeline interface
app.js, index.html, style.css, README.md
Timeline headers support adding, removing, enabling, and soloing tracks, with updated context-menu, shortcut, and visual-state behavior.
Linked multichannel audio routing
app.js
Video-linked audio is created per source channel, labeled and routed through dynamic buses, and mixed through the same discrete-channel path during playback and export.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Media
  participant Timeline
  participant AudioGraph
  participant Export
  Media->>Timeline: add video and linked channel clips
  Timeline->>AudioGraph: assign clips to dynamic audio buses
  AudioGraph->>AudioGraph: route discrete channels
  Export->>AudioGraph: mix routed channels offline
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.91% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main track-management additions: adding, removing, and soloing tracks.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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.

@PlkMarudny

Copy link
Copy Markdown
Contributor Author

Accidentally, I include also another commit, this one is big. As AAC audio can contain more than one channel, all of them are linked and displayed on a timeline, not just a stereo pair. If there is not enough audio tracks on the timeline, they are added to incorporate all channels.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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)
app.js (1)

2768-2799: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Delete buses for removed tracks in syncAudioGraphTracks.

Buses are created for new ids but never removed for deleted ones, so audio.trackBus accumulates stale, disconnected nodes. Because a re-added track reuses the same id (nextTrackId returns max+1), the stale bus is reused and only reconnected to master inside the if (audio.meter) branch — so if the meter worklet failed to install, a re-added track's bus would stay silent.

♻️ Suggested cleanup
   const ids = audioTrackIds();
   for (const id of ids) {
     if (!audio.trackBus[id]) {
       const g = audio.ctx.createGain();
       audio.trackBus[id] = g;
       g.connect(audio.master);
     }
   }
+  for (const id of Object.keys(audio.trackBus)) {
+    if (!ids.includes(id)) {
+      try { audio.trackBus[id].disconnect(); } catch { }
+      delete audio.trackBus[id];
+    }
+  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app.js` around lines 2768 - 2799, Update syncAudioGraphTracks to remove
entries from audio.trackBus whose IDs are absent from the current ids list,
disconnecting each removed bus before deletion. Perform this cleanup
independently of the audio.meter branch, and ensure buses for current IDs are
connected to audio.master so re-added tracks remain audible even when meter
installation failed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app.js`:
- Around line 169-181: Update ensureTracksCoverClips so each newly discovered
track name is marked as present immediately after adding it, before processing
subsequent clips. Use the existing TRACK_IDS set (or an equivalent per-call seen
set) to prevent multiple makeTrack calls for the same missing lane, while
preserving the existing sorting and height application behavior.
- Around line 1671-1677: Update buildTrackDOM() so the track ID interpolation in
the generated innerHTML uses escapeHtml(t.id), matching the existing escaping
used for clip labels. Leave the surrounding track controls and other
interpolation unchanged.

---

Nitpick comments:
In `@app.js`:
- Around line 2768-2799: Update syncAudioGraphTracks to remove entries from
audio.trackBus whose IDs are absent from the current ids list, disconnecting
each removed bus before deletion. Perform this cleanup independently of the
audio.meter branch, and ensure buses for current IDs are connected to
audio.master so re-added tracks remain audible even when meter installation
failed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2afad12f-9da9-477a-a4d6-5ba8a93f5b5a

📥 Commits

Reviewing files that changed from the base of the PR and between d584430 and 3a61499.

📒 Files selected for processing (5)
  • CLAUDE.md
  • README.md
  • app.js
  • index.html
  • style.css

Comment thread app.js
Comment thread app.js
@PlkMarudny

Copy link
Copy Markdown
Contributor Author

Apologies, not the whole commit was included.

@PlkMarudny

Copy link
Copy Markdown
Contributor Author

The feature has been updated. Now, dropping a video file with more audio channels than is available on the timeline, adds a necessary number of audio tracks.

@PlkMarudny

Copy link
Copy Markdown
Contributor Author

I am a little bit lost, not sure now if I mentioned anywhere the major upgrade how AAC audio tracks are handled. Let's say we have a multichannel audio - 3.0 layout. Before, an audio track was treated as a stereo pair, now all the channels are extracted into 3 mono audio tracks.

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.

1 participant