Skip to content

fix(editor): refresh companion audio preview#586

Merged
meiiie merged 2 commits into
mainfrom
fix/editor-refresh-companion-audio-preview
May 24, 2026
Merged

fix(editor): refresh companion audio preview#586
meiiie merged 2 commits into
mainfrom
fix/editor-refresh-companion-audio-preview

Conversation

@meiiie
Copy link
Copy Markdown
Collaborator

@meiiie meiiie commented May 24, 2026

Summary

  • Refresh editor companion-audio fallback discovery when the recording session updates after native/background finalization.
  • Resume and play external source audio preview from the editor Play action so late .mic.wav sidecars are audible in preview.
  • Keep capture/export unchanged; this only affects editor preview playback for companion audio.

Root cause

Native Windows recordings can open the editor before the browser microphone sidecar finishes writing. Export reads companion audio later and succeeds, but editor preview can miss or fail to unlock the .mic.wav sidecar after it becomes available.

Validation

  • User local smoke test: new mic recording now has mic audio in editor preview.
  • npx biome check src/components/video-editor/VideoEditor.tsx src/components/video-editor/audio/useSourceAudioFallback.ts src/components/video-editor/audio/useVideoEditorAudio.ts src/components/video-editor/audio/useAudioPreviewSync.ts --formatter-enabled=false
  • npx tsc --noEmit --pretty false
  • npm test -- src/lib/exporter/sourceTrackRoutingPolicy.test.ts src/lib/exporter/sourceAudioFallback.test.ts
  • git diff --check

Summary by CodeRabbit

  • Bug Fixes

    • More reliable audio playback resume when toggling play/pause.
    • Source-audio fallback refreshes correctly when the recording session changes.
  • Refactor

    • Audio preview and sync logic reorganized for smoother, more stable preview playback.
    • Control to trigger source-audio preview is exposed to the audio subsystem for improved responsiveness.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 054752b7-7e03-4377-b97f-dae4488e6f1e

📥 Commits

Reviewing files that changed from the base of the PR and between 9b3270b and fe47b07.

📒 Files selected for processing (1)
  • src/components/video-editor/VideoEditor.tsx

📝 Walkthrough

Walkthrough

VideoEditor adds a refresh key state and calls audio.playSourceAudioPreview() when resuming playback. useAudioPreviewSync exposes a stable playSourceAudioPreview callback. The refresh key is passed through useVideoEditorAudio to useSourceAudioFallback to re-fetch fallback audio when sessions change.

Changes

Audio Playback and Fallback Refresh

Layer / File(s) Summary
Playback callback infrastructure and hook return
src/components/video-editor/audio/useAudioPreviewSync.ts, src/components/video-editor/audio/useVideoEditorAudio.ts, src/components/video-editor/VideoEditor.tsx
Refactors internal callbacks to useCallback, introduces and returns playSourceAudioPreview from useAudioPreviewSync, surfaces it via useVideoEditorAudio, and uses it in VideoEditor when resuming playback (replacing direct video.play() calls). Auto-play starts when a resolved source track loads and the player is already playing.
Fallback refresh key propagation and trigger
src/components/video-editor/VideoEditor.tsx, src/components/video-editor/audio/useVideoEditorAudio.ts, src/components/video-editor/audio/useSourceAudioFallback.ts
Adds sourceAudioFallbackRefreshKey state in VideoEditor, increments it on matching recording-session changes, passes it into useVideoEditorAudio as sourceAudioFallbackRefreshKey, which forwards it as refreshKey to useSourceAudioFallback so the hook re-runs its effect when the key changes.

Sequence Diagram(s)

sequenceDiagram
  participant VideoEditor
  participant useVideoEditorAudio
  participant useAudioPreviewSync
  VideoEditor->>useVideoEditorAudio: call hook with sourceAudioFallbackRefreshKey
  useVideoEditorAudio->>useAudioPreviewSync: call hook
  useAudioPreviewSync->>useAudioPreviewSync: setup callbacks as useCallback
  useAudioPreviewSync-->>useVideoEditorAudio: return playSourceAudioPreview
  useVideoEditorAudio-->>VideoEditor: return playSourceAudioPreview and audio state
  VideoEditor->>VideoEditor: user toggles play
  VideoEditor->>useVideoEditorAudio: call audio.playSourceAudioPreview()
  useVideoEditorAudio->>useAudioPreviewSync: invoke playSourceAudioPreview
  useAudioPreviewSync->>useAudioPreviewSync: ensure audio context and play sources
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • webadderallorg/Recordly#280: Both PRs touch the editor’s source/mic companion-audio fallback flow and related fallback resolution logic.

Suggested labels

Checked

Poem

🐇 I hop through lines of audio code,
Stable callbacks take the load.
A key that bumps, a preview starts,
Fallbacks fetched and synced in parts.
Playback hums — the editor glows.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description includes a Summary section explaining the changes, Root cause analysis, and Validation steps covering testing. However, it does not follow the provided template structure with Description, Motivation, Type of Change, Related Issues, Screenshots/Video, Testing Guide, and Checklist sections. Restructure the description to match the repository template: add explicit Description and Motivation sections, select Type of Change (Bug Fix), include Related Issue link (#586), add Testing Guide section, and complete the Checklist items.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(editor): refresh companion audio preview' directly matches the main change: refreshing companion audio fallback discovery and resuming source audio preview playback in the editor when recording sessions update.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/editor-refresh-companion-audio-preview

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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 and usage tips.

@meiiie
Copy link
Copy Markdown
Collaborator Author

meiiie commented May 24, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 24, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/components/video-editor/VideoEditor.tsx (2)

2301-2323: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Normalize session.videoPath before matching the active source.

Line 2234 already runs this field through fromFileUrl(...), but this handler compares the raw event payload to videoSourcePath. If onRecordingSessionChanged delivers the same file-URL shape, the equality check never matches and setSourceAudioFallbackRefreshKey() never fires, so the late sidecar refresh path is skipped entirely.

Suggested fix
return window.electronAPI.onRecordingSessionChanged((session) => {
+	const sessionSourcePath = session?.videoPath ? fromFileUrl(session.videoPath) : null;
 	console.log("[VideoEditor] onRecordingSessionChanged received!", {
 		hasSession: Boolean(session),
 		hasSessionVideoPath: Boolean(session?.videoPath),
 		hasVideoSourcePath: Boolean(videoSourcePath),
-		match: session?.videoPath === videoSourcePath,
+		match: sessionSourcePath === videoSourcePath,
 		hasWebcamPath: Boolean(session?.webcamPath),
 	});

-	if (!session || session.videoPath !== videoSourcePath) {
+	if (!session || sessionSourcePath !== videoSourcePath) {
 		return;
 	}
🤖 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 `@src/components/video-editor/VideoEditor.tsx` around lines 2301 - 2323, The
handler passed to window.electronAPI.onRecordingSessionChanged compares the raw
session.videoPath to videoSourcePath, which can mismatch if one side was
normalized earlier with fromFileUrl; update the callback in
onRecordingSessionChanged to normalize session.videoPath via the same
fromFileUrl(...) utility (use the same import/utility already used elsewhere)
before logging and before the equality check, then use that normalized value for
the if-check and for setting webcam/source fields so
setSourceAudioFallbackRefreshKey(...) runs when paths truly match.

3188-3198: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Route all resume paths through the same source-audio helper.

This fixes the toolbar Play button, but Lines 3898-3911 still resume playback with playback.play() directly. Starting preview via the spacebar shortcut can still miss late companion audio, so the new behavior remains inconsistent.

Suggested fix
+const startPlayback = useCallback(() => {
+	const playback = videoPlaybackRef.current;
+	if (!playback?.video) return;
+	audio.playSourceAudioPreview();
+	void playback.play().catch((err) => console.error("Video play failed:", err));
+}, [audio.playSourceAudioPreview]);
+
 function togglePlayPause() {
 	const playback = videoPlaybackRef.current;
 	const video = playback?.video;
 	if (!playback || !video) return;

 	if (!video.paused && !video.ended) {
 		playback.pause();
 	} else {
-		audio.playSourceAudioPreview();
-		playback.play().catch((err) => console.error("Video play failed:", err));
+		startPlayback();
 	}
 }

Then use startPlayback() in the shortcut branch too.

🤖 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 `@src/components/video-editor/VideoEditor.tsx` around lines 3188 - 3198, The
resume logic must go through the same helper used by the toolbar: replace direct
uses of playback.play() in the keyboard shortcut/resume branch with a call to
startPlayback() (the same helper that ensures audio.playSourceAudioPreview()
runs before starting video and wraps playback.play() with proper error
handling); locate the spacebar/shortcut handler (the branch currently calling
playback.play() directly) and change it to invoke startPlayback(), and update
any other resume paths that call playback.play() directly so all resume flows
use startPlayback().
🤖 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.

Outside diff comments:
In `@src/components/video-editor/VideoEditor.tsx`:
- Around line 2301-2323: The handler passed to
window.electronAPI.onRecordingSessionChanged compares the raw session.videoPath
to videoSourcePath, which can mismatch if one side was normalized earlier with
fromFileUrl; update the callback in onRecordingSessionChanged to normalize
session.videoPath via the same fromFileUrl(...) utility (use the same
import/utility already used elsewhere) before logging and before the equality
check, then use that normalized value for the if-check and for setting
webcam/source fields so setSourceAudioFallbackRefreshKey(...) runs when paths
truly match.
- Around line 3188-3198: The resume logic must go through the same helper used
by the toolbar: replace direct uses of playback.play() in the keyboard
shortcut/resume branch with a call to startPlayback() (the same helper that
ensures audio.playSourceAudioPreview() runs before starting video and wraps
playback.play() with proper error handling); locate the spacebar/shortcut
handler (the branch currently calling playback.play() directly) and change it to
invoke startPlayback(), and update any other resume paths that call
playback.play() directly so all resume flows use startPlayback().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2b0aafde-5c76-4bc5-bbc5-3b488e640520

📥 Commits

Reviewing files that changed from the base of the PR and between d47550b and 9b3270b.

📒 Files selected for processing (4)
  • src/components/video-editor/VideoEditor.tsx
  • src/components/video-editor/audio/useAudioPreviewSync.ts
  • src/components/video-editor/audio/useSourceAudioFallback.ts
  • src/components/video-editor/audio/useVideoEditorAudio.ts

@meiiie meiiie merged commit ac2b393 into main May 24, 2026
3 checks passed
@meiiie meiiie deleted the fix/editor-refresh-companion-audio-preview branch May 24, 2026 17:33
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