Add ShadowClip Web: browser-based clip editing, no install required#22
Open
samyost wants to merge 1 commit into
Open
Add ShadowClip Web: browser-based clip editing, no install required#22samyost wants to merge 1 commit into
samyost wants to merge 1 commit into
Conversation
A fully client-side editor under web/ — drop ShadowPlay recordings into the page and trim/export clips without installing anything. Files never leave the machine. - Frame-by-frame scrubbing forwards AND backwards: exact frame rate is parsed from the MP4 sample table (stts/mdhd) and steps are anchored to the presentation timestamp of the on-screen frame via requestVideoFrameCallback, so rapid stepping stays frame-exact. - Drag-on-video fine scrubbing (~1 ms/px, Shift for coarse), click to play/pause, keyboard shortcuts matching the desktop app. - Segments with per-segment speed (0.25x-4x) and center zoom (1x/2x/4x), timeline with thumbnail filmstrip and draggable segment edges; segments are concatenated on export like the desktop app. - In-browser export via ffmpeg.wasm using the same filter graph as the desktop FfmpegEncoder (trim/setpts, scale+crop zoom, setpts/atempo speed, concat, optional setdar 16:9), with stream-copy fast path under the same restrictions. Output is normalized to the source frame rate when speeds change, fixing timestamp mangling the CFR default causes. - Screenshot to clipboard (Safari-compatible promise ClipboardItem), audio presence probing for non-MP4 containers, HEVC/undecodable sources still exportable via parsed metadata, Infinity-duration WebM handling, and single-threaded ffmpeg core so no COOP/COEP headers are needed (hostable on GitHub Pages). - vendor/ffmpeg-worker.js: self-contained @ffmpeg/ffmpeg 0.12.10 module worker (MIT) so the engine loads from a CDN cross-origin. Verified end-to-end in headless Chromium with pixel-level frame checks (33 assertions: fps parsing incl. 59.94/moov-at-end, bidirectional and rapid stepping, segment ops, copy/re-encode/video-only/WebM exports decoded and checked with native ffmpeg). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NiZVridAzJ92rnDPXWh3PK
There was a problem hiding this comment.
Pull request overview
Adds a new ShadowClip Web client-side editor under web/ that enables trimming and exporting gameplay clips in the browser (including frame stepping and segment-based edits) using ffmpeg.wasm, plus documentation and a vendored ffmpeg worker to support module-worker loading.
Changes:
- Introduces the web UI (HTML/CSS) and main editor logic (file list, playback/stepping, segments, timeline, screenshot, export flow).
- Adds an MP4 metadata parser to derive exact FPS / frame count / audio presence for accurate stepping and export decisions.
- Implements in-browser export via
ffmpeg.wasm, including stream-copy vs re-encode modes, and a vendored module worker for ffmpeg core loading.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| web/vendor/ffmpeg-worker.js | Vendored/inlined ffmpeg worker to support module-worker loading and CDN core usage. |
| web/README.md | Documents running the static site, features, shortcuts, and limitations/self-hosting notes. |
| web/js/mp4.js | Minimal MP4 parser to extract exact FPS and track/audio metadata. |
| web/js/exporter.js | ffmpeg.wasm engine loader and export pipeline (filter graph + copy/encode modes). |
| web/js/app.js | Main web app: UX, playback, frame stepping, segments/timeline, screenshot, export wiring. |
| web/index.html | Static page layout and controls for the web editor. |
| web/css/style.css | Styling for the web editor UI. |
| README.md | Root README updated to link to the new web app. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| throw new Error(`ffmpeg exited with code ${rc}\n${logTail.slice(-8).join('\n')}`); | ||
| const out = await ff.readFile(outputName); | ||
| if (!out || out.length === 0) throw new Error('ffmpeg produced an empty file'); | ||
| return new Blob([out.buffer], { type: 'video/mp4' }); |
Comment on lines
+695
to
+698
| function xToTime(clientX) { | ||
| const rect = timelineEl.getBoundingClientRect(); | ||
| return clamp(((clientX - rect.left) / rect.width) * state.duration, 0, state.duration); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A fully client-side editor under web/ — drop ShadowPlay recordings into the page and trim/export clips without installing anything. Files never leave the machine.
Verified end-to-end in headless Chromium with pixel-level frame checks (33 assertions: fps parsing incl. 59.94/moov-at-end, bidirectional and rapid stepping, segment ops, copy/re-encode/video-only/WebM exports decoded and checked with native ffmpeg).
Claude-Session: https://claude.ai/code/session_01NiZVridAzJ92rnDPXWh3PK