Commit Graph
518 Commits
Author SHA1 Message Date
webadderall f64267e2ec Merge pull request #292 from sp00kid/fix/preview-quality
fix: improve video preview quality by deferring filter attachment
2026-04-21 18:32:04 +10:00
webadderall 709b86bb90 Merge pull request #284 from meiiie/research/export-pipeline-profiling
chore(export): expand finalization profiling
2026-04-21 18:26:03 +10:00
webadderall 2872681ea6 Handle rename errors and prompt to save unsaved recordings 2026-04-21 15:14:10 +10:00
webadderall e8afbecb9f Cleanup rename and trim handling 2026-04-21 14:58:56 +10:00
webadderall ebd7e0d3ba Clean up dependent regions on clip resize 2026-04-21 14:51:12 +10:00
webadderall cdd2378992 Protect projectId from overwrite follow-up 2026-04-21 14:44:10 +10:00
webadderall 482134a03b fix(editor): address PR review feedback 2026-04-21 11:59:09 +10:00
webadderall e89b4e1317 fix(editor): port project save UX and clip cleanup to main 2026-04-21 11:46:07 +10:00
Ewazer 7349b3ae15 Fix: Update error messages for image upload failure 2026-04-20 15:58:06 +02:00
Ewazerandcoderabbitai[bot] 5d6e70cae2 Update src/i18n/locales/fr/timeline.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-04-20 15:51:31 +02:00
Ewazer c9e6f74c93 update 2026-04-20 13:24:20 +00:00
Ewazer b3fc91e9cf Update dialogs.json 2026-04-20 15:22:03 +02:00
wiiiii123 87c83eb8d4 fix(export): clean telemetry profiling rebase 2026-04-20 20:11:58 +07:00
wiiiii123 3c1923178b chore(export): add ffmpeg mux timing breakdown 2026-04-20 20:09:54 +07:00
wiiiii123 5ad4fee100 chore(export): add finalization stage profiling 2026-04-20 20:09:21 +07:00
Ewazer ff9bb9cb65 Update SettingsPanel.tsx 2026-04-20 14:40:36 +02:00
Ewazer cf64dc9b18 Update launch.json 2026-04-20 14:32:43 +02:00
Rajul Ranga e8d1d81837 fix: improve video preview quality by deferring filter attachment
The video preview was noticeably blurry/pixelated because PixiJS filters were always attached to the video container, even when inactive (blur=0, no motion). This forced every frame through an intermediate RenderTexture at renderer resolution, downsampling the native video before it even reached the screen.

Now filters are only attached during active zoom transitions when the camera is actually moving, and detached as soon as it settles. Added hysteresis to the motion threshold to prevent filter toggling when intensity hovers near the boundary.
2026-04-20 17:23:37 +05:30
Ewazer b081be30b5 Add French translations to I18nContext 2026-04-20 13:36:52 +02:00
Ewazer fee60ea173 Update config.ts 2026-04-20 13:35:54 +02:00
Ewazer 72eca472a1 Merge branch 'webadderall:main' into main 2026-04-20 13:35:21 +02:00
Ewazer 819f89fbb8 Add files via upload 2026-04-20 13:16:44 +02:00
webadderall 1106805af8 Merge pull request #283 from meiiie/fix/export-finalization-timeouts
fix(export): make audio finalization timeouts progress-aware
2026-04-20 20:56:28 +10:00
webadderall 31e917c28b Merge pull request #278 from meiiie/fix/export-media-paths
fix(export): reopen saved videos and default to source quality
2026-04-20 20:35:21 +10:00
wiiiii123 7d1bbd744d fix(export): cancel timed out finalization work 2026-04-20 11:21:52 +07:00
wiiiii123 d73ee94fef fix(export): only refresh watchdog on progress 2026-04-20 10:39:10 +07:00
wiiiii123 58de3f5759 test(export): share finalization watchdog logic 2026-04-20 10:19:25 +07:00
wiiiii123 07c4566554 fix(export): make audio timeouts progress-aware 2026-04-20 10:01:42 +07:00
wiiiii123 fdbcd36bda fix(export): scale audio finalization timeouts 2026-04-20 02:37:21 +07:00
webadderallandmeiiie b8e46623cd fix(recording): prefer playable browser capture codecs (#275)
Verifies the selected recording MIME type can also be decoded by the
in-app <video> element via canPlayType(), so that codecs like av1 —
which MediaRecorder.isTypeSupported() reports as supported for encoding
but are not decodable on fresh Windows installs without the AV1 Video
Extension — are not chosen.

Also passes undefined (not an unsupported fallback string) into
new MediaRecorder() when no preferred type is supported, letting the
browser pick a default instead of throwing NotSupportedError.

Replaces the previous 'as ProcessedDesktopSource' cast with a properly
typed LINUX_PORTAL_SOURCE constant.

Co-authored-by: meiiie <meiiie@users.noreply.github.com>
2026-04-20 01:08:12 +10:00
webadderall d2f5bbc9a6 fix: cast Linux portal sentinel as ProcessedDesktopSource to fix TS build error 2026-04-20 00:42:36 +10:00
wiiiii123 bddabaf1fb fix(export): reopen saved videos and default to source quality 2026-04-19 21:42:06 +07:00
Uri 186b08aa83 fix(linux/wayland): address PR review feedback
- electron/main.ts: treat missing sourceId on linux as portal sentinel
  so the request handler never calls getSources() (which itself opens
  an extra portal dialog) on fresh sessions.
- useScreenRecorder.ts: persist the synthesized portal sentinel via
  selectSource() so main has the source set before getDisplayMedia.
  Extract acquireLinuxPortalStream() helper to dedupe the three
  duplicated getDisplayMedia constraint blocks.
- LaunchWindow.tsx: hide the screen-source selector button (and its
  separator) on Linux so users cannot trigger an extra portal dialog
  via the dropdown.
2026-04-18 16:38:52 +03:00
Uri b6d2aaf5c6 fix(linux/wayland): collapse 3-step capture flow into a single portal dialog
Previously on Linux/Wayland, starting a fullscreen recording required three
separate picker interactions: an in-app source dropdown plus two xdg-desktop-portal
dialogs. The duplicate portal dialogs were caused by:

1. resolveBrowserCaptureSource() calling desktopCapturer.getSources() in the
   renderer, which itself triggers the portal on Wayland.
2. setDisplayMediaRequestHandler() in main also calling getSources(), which
   triggers another portal.
3. Returning a pre-enumerated source id to Chromium, which on Wayland is stale
   and forces Chromium to re-prompt via the portal during MediaStream creation.

Additionally, the editor window failed to appear after recording on some
Wayland sessions because 'ready-to-show' did not fire reliably.

Changes:
- LaunchWindow: skip the in-app source dropdown on Linux and start recording
  directly; the OS portal becomes the source picker.
- useScreenRecorder: introduce a 'screen:linux-portal' sentinel source. When
  set, route capture through navigator.mediaDevices.getDisplayMedia() so the
  portal handles selection in a single dialog. Skip resolveBrowserCaptureSource
  for the sentinel to avoid an extra getSources() call.
- electron/main: in setDisplayMediaRequestHandler, when the sentinel is set,
  skip desktopCapturer.getSources() entirely and return a synthetic source so
  Chromium opens the portal exactly once for the actual capture.
- electron/windows: in createEditorWindow, also call win.show() from
  did-finish-load as a fallback for Linux/Wayland where ready-to-show may
  not fire.
2026-04-18 16:17:08 +03:00
webadderall f275e8e65c Merge pull request #262 from webadderall/fix/export-pipeline-streaming-chunked
fix: streaming decode + chunked offline audio rendering for export
2026-04-18 22:12:10 +10:00
webadderall 120615ff74 fix: clear video src on timeout path in getMediaDurationSec 2026-04-18 22:04:40 +10:00
webadderall af72e8fdbf fix: address CodeRabbit review — fallback, i18n, return type cleanup
- Change ?? 99 fallback to ?? 100 in finalizing progress label
- Add editor.export.processingAudioEdits i18n key to all 5 locales
- Tighten sourceTimeToOutputTime return type to number (was number|null)
- Remove now-unused totalOutputDurationMs param from scheduleRegionForChunk
- Remove ?? fallbacks at call sites (function always returns a number)
2026-04-18 21:38:05 +10:00
webadderall f5389b0f11 fix: remove extension-sources, replace lucide-react with phosphor icons
- Remove extension-sources/ directory (91MB of bundled extension assets)
- Add extension-sources/ to .gitignore
- Replace all lucide-react imports with @phosphor-icons/react equivalents
  in TutorialHelp, ExtensionManager, and TimelineEditor
- Fixes #261 (missing lucide-react dependency + Twitter icon crash)

Closes #261
2026-04-18 21:18:12 +10:00
webadderall de2d34c971 fix: audio regions on silent video, interleaved >2ch stride, coderabbit config
- Fall back to video container duration when mainBuffer is null but
  audioRegions are present (prevents empty output)
- Use data.numberOfChannels as deinterleave stride instead of capped
  dataChannels (fixes garbled audio for 5.1+ sources)
- Fix .coderabbit.yaml: '*' is not valid regex, use '.*'
2026-04-18 20:45:46 +10:00
webadderall d4c6117406 fix: address CodeRabbit review — muxing error guard, dead code removal, i18n
- Add encoderError check after awaiting pendingMuxing to prevent
  finalization of corrupt exports (both exporters)
- Remove unreachable synchronous fast-path in getMediaDurationSec
- Set preload='metadata' before src for correct browser behavior
- Localize audio processing status text with t()
2026-04-18 20:43:48 +10:00
webadderall 9e2e2cce69 fix: replace real-time audio export with streaming decode + chunked offline rendering
Major rewrite of the audio export pipeline for stability and memory efficiency:

## Streaming Decode
- Primary decode path uses WebDemuxer + AudioDecoder (WebCodecs streaming)
- Falls back to bulk decodeAudioData if streaming fails
- Avoids holding full compressed file + decoded PCM simultaneously

## Chunked Offline Rendering
- Processes timeline in 30-second OfflineAudioContext chunks
- Memory bounded to ~30s of PCM per chunk regardless of recording length

## Chunked WAV Writing
- Writes PCM in ~256KB chunks instead of single massive ArrayBuffer
- Eliminates OOM for long recordings on the native/FFmpeg export path

## Chunked Encoding
- Single AudioEncoder kept alive across all chunks (clean AAC stream)
- Proper backpressure and error propagation per chunk

## scheduleBufferThroughTimeline chunk windowing
- Clips source nodes to chunk boundaries for correct cross-chunk audio
- Backwards compatible defaults when no chunk params provided

## Other export fixes
- Progress cap: 99% -> 100% in both exporters and UI
- Muxing errors: propagated instead of silently swallowed
- Mac recording: enhanced warning when no audio files for muxing
- Export timeout: eliminated by removing real-time rendering
2026-04-18 20:29:14 +10:00
webadderall b3b1be0833 fix: check both realpath and resolve forms in media URL handler, extract sync constants
- IPC get-local-media-url now checks both fs.realpath and path.resolve forms
  against approvedLocalReadPaths, so symlinks approved via approveUserPath work
- Extract duplicated sync correction parameters into shared constants in
  audioEncoder.ts (SYNC_SEEK_THRESHOLD_SEC, SYNC_PLAYBACK_RATE_OPTIONS)
2026-04-18 19:11:01 +10:00
webadderall d7d8a6368d fix: use drift-compensating scheduler in recording handler, fix media URL consistency
- Replace setInterval in recording handler with startCursorSampling() so
  the drift-compensating scheduler is used for actual recordings (was missed)
- Pass realpath-resolved path to buildMediaUrl for symlink consistency
- Use resolvedWebcamVideoUrl in thumbnail/export configs with file:// fallback
2026-04-18 19:03:36 +10:00
webadderall d39b9a4e32 fix: address CodeRabbit review feedback
- Fix telemetry drift reset: use nextExpectedMs - now for delay instead
  of stale drift value after baseline reset (avoids 1ms rapid sample)
- Use RECORDER_TIMESLICE_MS for mic fallback recorder (was hardcoded 1000)
- Return requested timeMs in extensionHost getCursorAt boundary clamps
- Remove premature null of webcam URL to prevent flicker on path change
- Use fs.realpath in IPC get-local-media-url to match media server check
2026-04-18 19:03:36 +10:00
webadderall 2fc74b200f fix: improve cursor telemetry accuracy under CPU load
- Replace setInterval with drift-compensating recursive setTimeout for
  cursor sampling. Under CPU load setInterval bunches or skips callbacks,
  creating irregular gaps in telemetry data.
- Add binary search + linear interpolation to export cursor lookup
  (modernFrameRenderer) matching the playback path. Was using O(n)
  nearest-neighbor which caused visible cursor jumping in exports.
- Apply same interpolation fix to extension API getCursorAt().
2026-04-18 19:03:36 +10:00
webadderall c4ada3505c fix: always apply aresample sync filter and tighten audio sync tolerances
- Always route audio through aresample=async=1:first_pts=0 filter during
  muxing on both macOS and Windows, even when duration delta is small.
  Previously skipped when delta ≤50ms, which left progressive clock drift
  (from CPU load) completely uncorrected.
- Lower sync detection threshold from 50ms to 20ms so tempo correction
  kicks in earlier.
- Use explicit 48kHz AudioContext sample rate in both browser recording
  and export rendering to prevent sample rate mismatch drift.
- Reduce MediaRecorder timeslice from 1000ms to 250ms to reduce chunk
  loss under CPU pressure.
- Tighten export audio sync: seek threshold 300ms→150ms, tolerance
  15ms→8ms, correction window 2s→0.5s, max adjustment ±8%→±12%.
- Lower companion audio start delay threshold from 50ms to 25ms.
2026-04-18 19:03:36 +10:00
webadderall 66172c9cd0 Merge pull request #258 from webadderall/feat/light-mode
feat: add light mode theme support
2026-04-18 17:34:29 +10:00
webadderall 8cd6a61f44 fix: default theme to system, set data-theme attribute on DOM
- Default preference to 'system' so first-run users get OS preference detection
- Set data-theme attribute on documentElement alongside .dark class toggle
2026-04-18 16:23:01 +10:00
webadderall 01d7efa085 fix: address CodeRabbit review for light mode theme
- Create missing ThemeContext.tsx (build-breaking)
- Fix text contrast on blue accent backgrounds (use text-white on bg-[#2563EB])
- Fix PlaybackControls border to use border-white/10 (dark overlay)
- Fix ExportSettingsMenu/FormatSelector active state text for light mode
- Fix ProjectBrowserDialog placeholder text on dark gradient
- Fix SettingsPanel dot preview border, accent text, hover text, X button text
- Fix TimelineEditor tooltip text and custom aspect input borders/bg
- Fix TutorialHelp malformed CSS class and kbd backgrounds
- Fix KeyboardShortcutsHelp kbd backgrounds for light mode
- Fix ExtensionManager badge text on blue pill
- Fix AnnotationSettingsPanel upload button hover text
- Fix index.css light mode timeline colors (was identical to dark)
2026-04-18 16:16:43 +10:00
webadderall 934fa6e7e3 fix: address CodeRabbit review feedback
- Use videoSourcePath instead of fromFileUrl(videoPath) for cursor
  telemetry — fixes broken path when videoPath is an HTTP media-server URL
- Validate filePath against approvedLocalReadPaths in get-local-media-url
  IPC handler before returning a URL
- Use fs.realpath() instead of path.resolve() to close symlink bypass
- Fix range parser to handle suffix ranges (bytes=-500) and guard
  against NaN values
- Add CORS headers (Access-Control-Allow-Origin) to media server
  responses to prevent canvas tainting when using video frames
- Handle OPTIONS preflight requests
- Clear stale resolvedWebcamVideoUrl before resolving new URL to
  prevent flash of stale content
2026-04-18 16:09:16 +10:00