Skip to content

feat: add live output preview frame before export#1076

Open
skypank-coder wants to merge 3 commits into
magic-peach:mainfrom
skypank-coder:feat/live-preview-before-export
Open

feat: add live output preview frame before export#1076
skypank-coder wants to merge 3 commits into
magic-peach:mainfrom
skypank-coder:feat/live-preview-before-export

Conversation

@skypank-coder
Copy link
Copy Markdown

@skypank-coder skypank-coder commented May 24, 2026

Description

Reframe had no way to preview edit settings before committing to a full export,
meaning users discovered wrong crop, rotation, or framing only after waiting
30–90 seconds for FFmpeg to process the entire file. This PR adds a "Preview
Frame" button that extracts a single JPEG frame at the midpoint of the trimmed
range using the identical filtergraph as the real export — guaranteeing true
WYSIWYG feedback in under 2 seconds. The feature is purely additive and the
existing export pipeline is completely untouched.

Related Issue

Closes #1052

Type of Contribution

  • New feature
  • Bug fix
  • Documentation update
  • Refactor
  • GSSoC contribution

Participant Info

  • GitHub username: skypank-coder
  • Contribution level (Beginner/Intermediate/Advanced): Advanced

What Changed

  • src/lib/ffmpeg.ts — refactored filter graph builder into standalone exported
    buildFilterGraph() function; added generatePreviewFrame() that uses
    input-side seeking (-ss before -i) to extract a single JPEG frame at the
    trimmed range midpoint with the full filter chain applied; virtual FS files
    cleaned up in finally block with unique session IDs to prevent collisions
  • src/hooks/useVideoEditor.ts — added previewUrl: string | null and
    isPreviewing: boolean state; added generatePreview action with guard
    against concurrent export; blob URL revoked on new preview, on file change,
    and on unmount to prevent memory leaks
  • src/components/PreviewPanel.tsx — new component with Preview button, loading
    state, and frame display using Next.js <Image> with unoptimized for blob
    URL support; all interactive elements have aria-label
  • src/components/VideoEditor.tsx — mounted <PreviewPanel> below existing
    controls, passing previewUrl, isPreviewing, generatePreview, isDisabled,
    and isExporting props

Technical Notes

The -ss seek flag is placed before -i (input-side seek) so FFmpeg jumps
directly to the midpoint without decoding the entire file, keeping preview
latency under 2 seconds on typical hardware. The generatePreviewFrame function
receives the already-loaded FFmpeg WASM instance as a parameter — no
re-initialization occurs. Blob URLs are revoked via URL.revokeObjectURL before
each new preview and on unmount to prevent memory accumulation. Preview is
disabled while an export is running.

Testing Done

  • Tested portrait video (9:16) with Fill framing
  • Tested landscape video (16:9) with Fit framing
  • Tested all 4 rotation values (0°, 90°, 180°, 270°)
  • Verified preview frame matches output of actual export
  • Verified no memory leaks — URL revoked on new preview and on unmount
  • Preview button disabled during active export
  • bun run lint passes — zero warnings, zero errors
  • bunx tsc --noEmit passes — zero errors
  • Tested in Chrome, Firefox, Safari

Screen Recording

Recording / Loom link:

GSSOC.REFRAME.1.1.mp4

Checklist

  • I have read the contribution guidelines
  • My changes follow the project structure
  • I have tested my changes in Chrome, Firefox, and Safari
  • bun run lint passes (no ESLint errors)
  • bunx tsc --noEmit passes (no TypeScript errors)
  • New interactive elements have aria-label / accessible names
  • No console.log statements left in
  • This PR is related to a valid issue
  • Screen recording attached above (required for UI/feature/design changes)

@vercel
Copy link
Copy Markdown

vercel Bot commented May 24, 2026

@skypank-coder is attempting to deploy a commit to the magic-peach1's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 24, 2026

✅ PR Format Check Passed — @skypank-coder

Basic format checks passed. A maintainer will review your code changes.

This does not mean the PR is approved — it just means the format is correct.

@github-actions github-actions Bot added level:advanced Advanced level - 55 pts type:bug Bug fix type:design UI/UX design type:docs Documentation type:feature New feature type:performance Performance type:refactor Code refactor type:testing Testing labels May 24, 2026
@github-actions
Copy link
Copy Markdown
Contributor

👋 Thanks for your PR, @skypank-coder!

Welcome to Reframe — a browser-based video editor built for everyone 🎬

🟠 GSSoC'26 PR detected — thanks for contributing under GirlScript Summer of Code 2026!

What happens next

  1. 🤖 Automated checks — build & TypeScript typecheck will run automatically
  2. Vercel preview — a preview deployment will be created (requires maintainer authorization for fork PRs)
  3. 👀 Code review — a maintainer will review your changes
  4. 🚀 Merge — once approved, your PR will be merged!

Quick checklist

  • PR title follows Conventional Commits (e.g. feat: add dark mode)
  • Linked the issue this PR closes (e.g. Closes #123)
  • Tested the changes locally (bun run dev)
  • Build passes (bun run build)

Useful links

Happy coding! 🎉

@github-actions github-actions Bot added the gssoc'26 GirlScript Summer of Code 2026 label May 24, 2026
@skypank-coder
Copy link
Copy Markdown
Author

Hey @magic-peach — just wanted to flag that issue #1052 was assigned to me via
the /assign bot, and I noticed another PR has been opened for the same issue.
I've implemented the full feature as described — generatePreviewFrame() with
input-side seeking, blob URL lifecycle management, PreviewPanel component, and
the buildFilterGraph() refactor — all with zero lint warnings and zero TypeScript
errors. Happy for you to compare both PRs and go with whichever implementation
you prefer. Let me know if you'd like any changes on my end! 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc'26 GirlScript Summer of Code 2026 level:advanced Advanced level - 55 pts type:bug Bug fix type:design UI/UX design type:docs Documentation type:feature New feature type:performance Performance type:refactor Code refactor type:testing Testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Add Client-Side Video Preview Before Export — Show Output Frame Using FFmpeg WASM Canvas Render

1 participant