Commit Graph
90 Commits
Author SHA1 Message Date
webadderall b7997e902b Address validated CodeRabbit findings for project saves and HUD lifecycle 2026-09-23 11:23:49 +10:00
webadderall e41ce83cd3 feat(ui): integrate recording library and cloud account into HeroUI editor 2026-09-20 18:52:27 +10:00
webadderall 0bed6fa598 perf: optimize application startup 2026-09-05 16:15:37 +10:00
webadderall 4b92215cc3 Prevent closed console streams from crashing Recordly 2026-09-05 05:15:40 +10:00
webadderall e83114a45d Use native update prompts off macOS 2026-09-03 12:09:31 +10:00
young 58faea68f1 Fix HUD capture protection across recording backends 2026-09-03 11:38:03 +10:00
webadderall f6041a6109 Address CodeRabbit lifecycle feedback 2026-09-02 20:27:25 +10:00
webadderall 7dffa98ae6 Fix Windows app and webcam lifecycle 2026-09-02 20:27:24 +10:00
webadderall 956b352985 Fix experimental update channel and toast 2026-08-31 18:50:39 +10:00
young 8120f82b85 Add live announcements and experimental updates 2026-08-30 21:23:11 +10:00
young 0375b9c183 Disable the extension system 2026-08-28 09:54:42 +10:00
webadderall b5bedd73d9 Show Recordly in the Windows taskbar 2026-08-25 19:23:15 +10:00
young dba1fe2656 Show Recordly in the macOS Dock 2026-08-25 19:04:38 +10:00
wiiiii123 6b32385910 Merge branch 'main' into fix/electron-permission-policy 2026-07-11 10:32:47 +07:00
wiiiii123 6571f0fc6d fix(electron): scope capture permissions to the HUD 2026-07-10 12:43:12 +07:00
wiiiii123 3e80400269 fix(electron): constrain renderer navigation 2026-07-10 05:46:22 +07:00
webadderall c50d9e1d4e Revert "fix(linux): route X11 capture through real sources"
This reverts commit 9bb288b069.
2026-06-05 10:31:28 +10:00
wiiiii123 6858b53655 fix(hud): restore clickability after webcam preview 2026-05-29 02:53:33 +07:00
wiiiii123 9bb288b069 fix(linux): route X11 capture through real sources 2026-05-29 00:48:59 +07:00
wiiiii123 38f5ded48d fix(recording): stabilize capture quality and CUDA export canvas 2026-05-27 18:12:21 +07:00
webadderall de2fbafcf1 Update Recordly app branding assets 2026-05-11 19:20:21 +10:00
Alan Trebugeais b10f0bf4c3 fix: webcam recording, now it works, alongside the microphone etc 2026-05-10 23:37:07 +02:00
wiiiii123 6dab368631 fix(electron): avoid cjs dirname binding collision 2026-05-08 20:07:36 +07:00
wiiiii123 93e1312978 merge main into beta/pr410-native-gpu-export-test
# Conflicts:
#	electron/ipc/project/manager.ts
#	electron/ipc/register/export.ts
#	src/lib/exporter/modernVideoExporter.ts
2026-05-08 10:44:13 +07:00
webadderall d03054f723 Speed up Lightning export and relax local media reads 2026-05-08 11:32:04 +10:00
wiiiii123 678ece2f4a fix(export): harden native beta pipeline 2026-05-07 22:37:27 +07:00
wiiiii123 05327a12ce Add native GPU static layout export path 2026-05-03 22:43:23 +07:00
webadderall cd4ea8fc05 Improve HUD and update prompt UI 2026-04-25 21:34:55 +10:00
大彪 1280670740 chore(smoke-export): let the smoke harness open .recordly project files
Previously the smoke-export harness only accepted a raw MP4 input path.
Validating the export pipeline on a real editor project (with its own
zoom regions, wallpaper, annotations, and webcam state) required
opening the editor by hand and clicking through the GUI.

This adds three new environment variables that are picked up by the
existing smoke-export query string plumbing:

- RECORDLY_SMOKE_EXPORT_PROJECT  — path to a .recordly project file;
  when set, the editor opens it via openProjectFileAtPath and applies
  the saved state before the auto-export fires.
- RECORDLY_SMOKE_EXPORT_QUALITY  — overrides the hard-coded "good"
  quality used by the auto-export trigger; accepts medium / good /
  high / source.
- RECORDLY_SMOKE_EXPORT_FPS      — overrides the frame rate; accepts
  24 / 30 / 60.

No behavior change for existing RECORDLY_SMOKE_EXPORT_INPUT runs;
the new inputs are strictly additive and optional. The startup log
line prefers the project path over the raw-input path when both are
populated.
2026-04-24 16:02:37 +08:00
大彪 bd8a941c12 fix(export): stream MP4 output to disk to unblock >2 GiB exports
Long recordings (35-minute screencaps were the motivating case) fail at
the 99% "Finalizing" step with a RangeError once the muxed MP4 would
exceed V8's ~2 GiB per-ArrayBuffer limit. Both export paths accumulate
the whole file in renderer memory and round-trip it through IPC, so no
output size past that point can complete:

- Legacy: src/lib/exporter/muxer.ts uses mediabunny's BufferTarget,
  which holds the entire MP4 in a single ArrayBuffer. finalize() → Blob
  → blob.arrayBuffer() → ipcRenderer.invoke('write-exported-video-to-
  path', arrayBuffer, path) — every step wants a ≥2 GiB contiguous
  allocation.
- Lightning: native-video-export-finish did fs.readFile(finalizedPath)
  and shipped the bytes back to the renderer, which re-serialized them
  again. Same ceiling.

This change moves the finished MP4 across the renderer↔main boundary
via a temp file instead of an ArrayBuffer:

- New electron/ipc/export/exportStream.ts manages streaming temp files
  via fh.write(buf, 0, len, position) so out-of-order writes (moov box
  rewrites, etc.) stay safe. Each session lives in a 0700 mkdtemp()
  directory opened with O_CREAT | O_EXCL so a hostile local user on a
  shared tempdir cannot pre-plant a symlink at the predicted path.
- New renderer-facing IPCs: export-stream-open/write/close,
  finalize-exported-video (renames temp to final path, copy+unlink
  fallback on EXDEV/EPERM/ENOTEMPTY with console.warn on leaked bytes),
  mux-exported-video-audio-from-path (FFmpeg audio fallback that takes
  a path instead of an ArrayBuffer), and discard-exported-temp. Every
  handler validates the caller-supplied path against an owned-export-
  paths registry before touching disk, so a compromised renderer cannot
  route arbitrary filesystem paths into main-process deletes/moves.
- The muxer now picks mediabunny's StreamTarget automatically when the
  Electron bridge is available (BufferTarget stays for tests and any
  non-Electron callers). finalize() returns { mode, tempFilePath,
  bytesWritten } or { mode, blob } so the exporter can branch.
- Exporters forward tempFilePath through ExportResult. Lightning's
  finish returns the ffmpeg temp path directly; the FFmpeg audio
  fallback forks on the muxer result type. modernVideoExporter's
  Lightning success branch now accepts tempFilePath (previously it
  checked blob only, which regressed every native export).
- VideoEditor.tsx dispatches on tempFilePath: finalize via the new IPC,
  keep the temp in place when the save dialog is canceled so "Save
  Again" still works without re-rendering, keep the pending-save entry
  alive on non-canceled save failures, and discard the temp on unmount
  or explicit clear. GIF and smoke-test code paths still use the
  legacy Blob path unchanged.
- app.on('before-quit') also reaps any open streaming sessions via
  cleanupAllExportStreams().

Chunk size is 16 MiB — well under Electron/Mojo IPC message limits
while keeping total writes low (~160 for a 2.5 GB export).

Tested locally: exported a 35:13 source (~2.7 GiB H.264 input) at
Original 1920×1080 + Balanced. Previously failed on finalize with a
RangeError; with this patch the Legacy pipeline produced a valid 3.7
GiB MP4 whose ffmpeg -i duration/streams match the source.

Addresses #194.
2026-04-24 16:02:37 +08:00
webadderall eaa67fce80 Merge pull request #302 from meiiie/fix/linux-wayland-gpu-switches
fix(linux): avoid forcing EGL on Wayland
2026-04-23 12:37:18 +10:00
wiiiii123 4207664c4a fix(recording): recover from fullscreen countdown failures 2026-04-21 20:46:37 +07:00
wiiiii123 de53d398d7 fix(linux): avoid forcing EGL on Wayland 2026-04-21 02:49:08 +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 596d6faa8d refactor: remove redundant Linux platform guard in GPU config 2026-04-18 22:05:05 +10:00
webadderall dbd5a2a9a2 fix: Linux GPU fallback and HUD window show safety net
- Add Linux GPU config: use EGL (better Wayland compat), disable VAAPI
  video decoder/encoder (many distros ship broken drivers causing
  'vaInitialize failed' and preventing renderer from loading)
- Add ready-to-show fallback for HUD window: if did-finish-load never
  fires (GPU failure), show the window after 500ms via ready-to-show

Ref #261
2026-04-18 21:32:18 +10:00
webadderall 794e2944d6 fix: serve video files via local HTTP server to fix loading on Windows
On Windows, the packaged app serves the renderer from http://127.0.0.1:PORT,
which causes Chromium to block file:// URLs in <video> elements — even with
webSecurity disabled. This affects all users running the packaged build.

Add a local media HTTP server (random port) that streams approved video files
with range request support for seeking. The renderer now resolves video paths
through this server instead of using file:// URLs directly.

- electron/mediaServer.ts: HTTP server with path validation against
  approvedLocalReadPaths and Content-Range support
- IPC handler 'get-local-media-url' converts file paths to HTTP URLs
- resolveVideoUrl() in renderer falls back to file:// if server unavailable
- Improved <video> onError to log actual MediaError details

Fixes #244
2026-04-18 15:55:43 +10:00
webadderall 26f1ce2476 feat: add H.264 stream-copy export, overhaul exporter pipeline, rename native binaries
- IPC: new inputMode 'h264-stream' — browser VideoEncoder output stream-copied
  into MP4 via ffmpeg rather than piping raw RGBA frames, cuts memory usage
- Security: replace flat approvedLocalReadPaths with userApprovedPaths fed from
  dialog pickers and project load; isAllowedLocalReadPath uses it alongside
  dir prefix / existsSync checks
- nativeVideoExport: add buildNativeH264StreamExportArgs for stream-copy path
- frameRenderer / modernFrameRenderer: cursor-follow camera integration,
  annotation blur post-processing, shadow profile, squircle geometry
- audioEncoder / streamingDecoder / gifExporter / muxer: full pipeline
  hardening — drift correction, backpressure, proper teardown
- Rename native helpers openscreen-* → recordly-* on darwin-arm64 and
  darwin-x64; update helpers-manifest.json for win32-x64
- electron/main, windows, updater, rendererServer: startup and window
  lifecycle improvements
- preload: expose inputMode and new IPC surface to renderer
2026-04-16 17:51:41 +10:00
webadderall 18d5a091f8 feat: extension system with marketplace, permissions, and security hardening
- Extension loader with manifest validation, ID sanitization, and path traversal protection
- Permission-gated runtime API (render, cursor, audio, timeline, ui, assets, export)
- Extension host with lifecycle management (activate/deactivate)
- Marketplace client for browsing, downloading, and installing extensions
- Extension Manager UI panel with enable/disable/uninstall
- IPC bridge for extension discovery, management, and marketplace operations
- Proxy guard on window.electronAPI to block extension access to privileged IPC
- Zip-slip protection via post-extraction directory traversal validation
- Safe PowerShell invocation for Windows zip extraction (no string interpolation)
- File URL resolution with path escape prevention
2026-04-12 01:37:28 +10:00
webadderall f56f39ddb3 Hotfix 1.1.17 2026-04-06 18:10:29 +10:00
webadderall e7cd2004fe Improve tray and packaged editor restore paths 2026-04-06 15:22:58 +10:00
webadderall bd7524ca04 Fix Windows tray restore during recording 2026-04-05 23:23:16 +10:00
webadderall de3b396d89 Load packaged renderer over localhost 2026-04-05 18:51:51 +10:00
webadderall 495b714ab8 fix(windows): align Win10 HUD restore with interactive fallback 2026-04-04 17:22:37 +11:00
webadderall e85ceb6497 configure smoke export window boot flow 2026-04-04 13:07:49 +11:00
webadderall c069eb015e fix(electron): Windows HUD visibility - moveTop after show, reassert mouse state on recording start 2026-04-02 21:09:32 +11:00
webadderall 393be9b76a fix(electron): Win10 HUD click-through recovery 2026-04-02 16:29:51 +11:00
webadderall 8709834901 fix: add setDevicePermissionHandler for Windows 11 webcam access
Chromium (Electron 17+) requires setDevicePermissionHandler in addition
to setPermissionCheckHandler/setPermissionRequestHandler. Without it,
device-level access is silently denied on Windows 11 even though the
permission check passes, causing getUserMedia to throw NotAllowedError.
2026-03-30 15:41:01 +11:00
webadderall 3ac1de6996 fix: add Windows camera/microphone permission status logging
- Check systemPreferences.getMediaAccessStatus on Windows startup
- Log warnings when camera/mic access is denied so users know to check
  Windows Settings > Privacy > Camera/Microphone
2026-03-30 15:27:47 +11:00