Skip to content

fix(export): run the app's own ffmpeg for the video watermark - #2192

Merged
debpalash merged 6 commits into
debpalash:mainfrom
kevin9327:fix/export-overlay-resolves-ffmpeg
Sep 18, 2026
Merged

debpalash merged 6 commits into
debpalash:mainfrom
kevin9327:fix/export-overlay-resolves-ffmpeg

Conversation

@kevin9327

@kevin9327 kevin9327 commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Video watermark exports and dubbing keyframe extraction use the shared FFmpeg resolver, including the bundled executable, instead of requiring a system binary named ffmpeg. Existing missing-tool and failed-overlay fallbacks remain unchanged.

Current main is merged, the changelog conflict is resolved with contributor credit, and dubbing documentation describes bundled-tool support. CodeRabbit and Greptile reviews were checked.

Validation: 109 offline export, video-context, router, watermark and changelog tests passed. Resolver stubs keep tests isolated from the real executable-probe cache.

Included in #2191 with contributor history preserved. The combined PR runs full CI before landing and will absorb this PR; do not merge this separately.

Review disposition: the changelog entries stay under ### Fixed, which CLAUDE.md explicitly permits beneath a short Highlights list. The request to move every entry into Highlights conflicts with that governing rule; the deterministic changelog tests pass.

kevin9327 and others added 2 commits September 18, 2026 07:40
Two call sites still reached for the bare name `ffmpeg` instead of
services.ffmpeg_utils.find_ffmpeg(), which every other call site uses. The
bare name only resolves a system install: imageio-ffmpeg -- the app's
default source, and a locked dependency -- ships its binary as
`ffmpeg-<platform>-v<version>`, and ensure_media_tools_on_path() publishes
that directory on PATH without giving the file an `ffmpeg` name. So on a
host with no separate system ffmpeg, which is most installs:

- /export dropped the visible video watermark. is_visible_video_enabled()
  defaults to ON, the spawn raised FileNotFoundError, and the except arm
  quietly plain-copied the file -- the user asked for a watermarked export
  and got an unmarked one with no error anywhere.
- video_context._extract_keyframes gated on shutil.which("ffmpeg") and
  logged "ffmpeg not found, skipping frame extraction", so the dubbing
  director's visual context was empty while the app's own ffmpeg sat on
  disk, resolvable. Same shape as debpalash#1256.

The export also no longer spawns anything when nothing resolves: it goes
straight to the plain copy instead of failing a subprocess to get there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 42ec3123-f0c2-4891-bb5b-719f48818c48

📥 Commits

Reviewing files that changed from the base of the PR and between 58ad330 and 3f0ec01.

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

Included review availability: Your plan provides up to 10 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

The PR updates video watermark overlays and keyframe extraction to use the resolved FFmpeg executable. It preserves plain-copy and no-executable fallback behavior and adds tests for resolved and missing FFmpeg paths.

Changes

FFmpeg resolution

Layer / File(s) Summary
Export overlay resolution
backend/api/routers/exports.py, tests/test_exports_api.py, CHANGELOG.md
The export overlay uses the path returned by find_ffmpeg(). When no path resolves, the export copies the source without spawning a subprocess. Tests cover resolved execution, missing FFmpeg, and FFmpeg failure.
Keyframe extraction resolution
backend/services/video_context.py, tests/test_video_context.py, docs/electron-dubbing.md
Keyframe extraction uses the resolved FFmpeg path and returns no frames when resolution fails. Tests cover both paths. The documentation describes bundled FFmpeg usage.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 3f0ec

The documented FFmpeg-resolution updates have no supported unresolved defect in the supplied evidence, so no merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 7 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 4 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The description explains the main changes, fallback behavior, testing, documentation, and related pull requests. It does not follow the required template structure and omits explicit Type and Checklis… Rewrite the description using the repository template. Add the required Summary, Changes, Type, Testing, Checklist, and Release cadence sections. Mark the applicable Type and Checklist items, and explicitly confirm the smoke-matrix regressi…
✅ Passed checks (7 passed)
Check name Status Explanation
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.
Cross-Platform Default Parity ✅ Passed The PR changes default behavior by routing watermark and keyframe FFmpeg calls through the existing shared resolver. The resolver is unchanged, provides platform-specific imageio-ffmpeg wheels for mac…
I18n Completeness (21 Locales) ✅ Passed No frontend or Electron files changed in the reviewed range. The patch adds no frontend t('...') keys and no frontend user-facing strings, so there are no locale completeness gaps to report across the…
Local-First Guarantee ✅ Passed The PR adds no cloud request, account/API-key requirement, or telemetry. It changes two local FFmpeg call sites to use the existing find_ffmpeg() resolver. That resolver only checks local environmen…
Backward Compatibility ✅ Passed PASS — The pull request changes only FFmpeg executable resolution for video watermark export and visual-context keyframe extraction, plus tests and documentation. The authoritative diff contains no da…
Title check ✅ Passed The title uses Conventional Commit format with the required scope and accurately describes the FFmpeg export change. The issue reference appears in the pull request body as #2191.
Full details: Docstring Coverage

Explanation

Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 4 files. (1 skipped: 1 unsupported.)

Full details: Description check

Explanation

The description explains the main changes, fallback behavior, testing, documentation, and related pull requests. It does not follow the required template structure and omits explicit Type and Checklist sections, including confirmation of the regression fixture requirement.

Resolution

Rewrite the description using the repository template. Add the required Summary, Changes, Type, Testing, Checklist, and Release cadence sections. Mark the applicable Type and Checklist items, and explicitly confirm the smoke-matrix regression fixture status or explain why it is not applicable.

  • Fix all pre-merge checks with AI

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.

@greptile-apps

greptile-apps Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Retrigger

The implementation appears functionally safe, but the explicit changelog placement requirement must be satisfied before merging.

Fix All in Claude CodeFindings

  1. P2 **Incorrect changelog placement**
Summary

The PR routes video watermarking and dubbing keyframe extraction through the shared FFmpeg resolver so bundled executables work without a system installation.

  • Preserves plain-copy and skipped-extraction fallbacks when FFmpeg is unavailable or overlaying fails.
  • Adds isolated coverage for resolved and missing executables.
  • Documents bundled FFmpeg support.

Reviews (4) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..."

@kevin9327

Copy link
Copy Markdown
Contributor Author

Heads-up on the CHANGELOG: ## [Unreleased] is empty on main, so this PR and my siblings (#2190 / #2191 / #2192) each recreate the Highlights + Fixed scaffold and will collide there. Whichever lands first, I'll re-file the others onto its block — or just drop my two lines at merge time and I'll follow up.

kevin9327 and others added 4 commits September 18, 2026 07:47
The module's Pillow-floor check read pyproject.toml with a bare
read_text(), i.e. in the locale code page, so the whole module errored out
on a Chinese, Japanese or Korean Windows and the tests added here could not
be run there. TOML is UTF-8; name it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread CHANGELOG.md

### Fixed

- Video watermark exports and dubbing keyframes use the bundled FFmpeg without requiring a system install (#2192) — thanks @kevin9327!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 The new entry is under Fixed, but the repository requires Unreleased entries in the short Highlights list. Move this single-line credited entry to Highlights; this requirement must be satisfied before merging.

Context Used: Review as a panel of senior domain experts (ML inference, audio DSP, desktop systems). Comment ONLY on findings that would change what gets merged: a concrete bug, a violated house rule from CLAUDE.md, a real security/data risk. Per finding: at most ... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code

@debpalash
debpalash merged commit 9cdf126 into debpalash:main Sep 18, 2026
15 of 19 checks passed
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.

2 participants