Skip to content

Conversation

@fengjinyi98
Copy link

Summary

This PR implements the FFmpeg-based recording backend proposed in #69.

  • Uses an FFmpeg process (main process) instead of MediaRecorder to produce higher quality, constant frame rate (CFR) MP4/H.264.
  • Targets Windows + macOS first. Linux intentionally falls back to the existing MediaRecorder pipeline for now.

Closes #69.

Key changes

Main process: FFmpeg recorder

  • Adds electron/recording/ffmpegRecorder.ts (FfmpegRecorder)
    • Spawns ffmpeg for capture and encoding.
    • Stops gracefully by sending q to stdin, with a kill timeout fallback.
    • Runs ffprobe after stopping to return basic metadata (codec / size / fps) for a lightweight self-check.
    • Encoder selection with fallback:
      • Windows: h264_nvenc / h264_amf / h264_qsv ? libx264
      • macOS: h264_videotoolbox ? libx264
    • Forces CFR via -vf fps=... and normalizes output dimensions to even numbers.

IPC + preload API

  • Adds IPC handlers:
    • start-recording / stop-recording (FFmpeg backend)
  • Exposes preload APIs:
    • electronAPI.startRecording() / electronAPI.stopRecording()

Renderer integration (fallback preserved)

  • useScreenRecorder prefers the FFmpeg backend when available and supported:
    • Windows: screen: and window: sources
    • macOS: screen: sources only
    • Linux: returns unsupported ? falls back to existing MediaRecorder pipeline

Windows window-capture improvements

  • Captures the raw window title (rawName) from the source selector and tries it first for gdigrab title=... matching.

Robustness

  • Prevents accidental double-start creating multiple FFmpeg processes:
    • Start mutex in main recorder + UI debounce in renderer

Automated verification (no screen capture required)

  • Adds scripts/verify-ffmpeg.mjs and npm run verify:ffmpeg
    • Generates a 2s 720p60 test pattern via lavfi and validates the MP4 output via ffprobe.
    • This is intended to reduce manual ?record and watch a video? validation.

Manual verification

macOS

  1. Ensure ffmpeg and ffprobe are available in PATH (or set OPENSCREEN_FFMPEG_PATH / OPENSCREEN_FFPROBE_PATH).
  2. Run npm run dev.
  3. Select a screen source and record.
  4. Stop recording and verify the resulting MP4.

Windows

  1. Ensure ffmpeg and ffprobe are available in PATH (or set env overrides).
  2. Run npm run dev.
  3. Select a screen or window source and record.
  4. Stop recording and verify the resulting MP4.

Notes / limitations

  • Linux is not enabled yet by design (fallback to MediaRecorder).
  • macOS currently supports screen sources only (window capture is not wired up).

Configuration

  • Optional env overrides:
    • OPENSCREEN_FFMPEG_PATH
    • OPENSCREEN_FFPROBE_PATH

fengjinyi and others added 4 commits December 18, 2025 09:07
- Add complete i18n infrastructure with I18nProvider and useI18n hook
- Add Chinese (Simplified) translations for all UI elements
- Auto-detect browser language preference
- Add language switcher in settings panel
- Create bilingual README with language toggle
- Add GitHub Actions workflow for automated releases

Closes: i18n support
- Update paths from release/*.ext to release/**/*.ext
- electron-builder outputs to release/${version}/ subdirectory
- Add safety check for artifacts directory listing
- Add artifactName for Windows builds to match macOS/Linux naming convention
- Include all necessary build artifacts (.exe, .dmg, .AppImage, .blockmap files, latest*.yml)
- Optimize release file path matching with precise glob patterns
- Ensure auto-update metadata files are included in artifacts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
…m#69)

- 新增主进程 FFmpeg 录制器(硬编优先回退 + CFR + ffprobe 自检)\n- Renderer 优先 FFmpeg,失败回退 MediaRecorder;Linux 暂不启用\n- 增加 verify:ffmpeg 冒烟脚本,减少人工录屏验证\n- 修复重复点击导致多 ffmpeg 进程:主进程互斥 + UI 防抖
@fengjinyi98
Copy link
Author

Manual verification on macOS (local
pm run dev): recorded a short clip via the FFmpeg backend. ffprobe output for the resulting MP4 shows: codec_name=h264, pix_fmt=yuv420p, width=2880, height=1800, avg_frame_rate=60/1. Stop/finish path is clean (ffmpeg receives 'q' and finalizes moov atom).

@suenyiyang
Copy link
Contributor

Seems you mixed the code of #71 into this PR. It is really hard to review such a huge change in one time. 😭

@fengjinyi98
Copy link
Author

Seems you mixed the code of #71 into this PR. It is really hard to review such a huge change in one time. 😭看来你把 #71 的代码混入到这个 PR 里了。这么大的改动真的很难一次性审核。😭

Thanks for pointing this out — sorry about the large PR. You’re right: this PR ended up including the changes from #71
(i18n) plus a couple CI workflow fixes, on top of the FFmpeg recording backend.

I understand that makes it hard to review in one go. To make it easier without asking you to digest everything at
once, the PR is structured as 4 separate commits:

If it works for you, please review it commit-by-commit, with the main focus on f9d5347. If you’d prefer this handled
differently (e.g., split PRs), please let me know. Thanks again for your time and patience.

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.

Replace MediaRecorder with FFMPEG process for screen recording workflow

3 participants