Skip to content

test: ogv.js WebM polyfill for Safari VP9 playback#271

Draft
devin-ai-integration[bot] wants to merge 1 commit intoperf/optimize-landing-assetsfrom
test/libavjs-polyfill
Draft

test: ogv.js WebM polyfill for Safari VP9 playback#271
devin-ai-integration[bot] wants to merge 1 commit intoperf/optimize-landing-assetsfrom
test/libavjs-polyfill

Conversation

@devin-ai-integration
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot commented Mar 3, 2026

test: ogv.js WebM polyfill for Safari VP9 playback

Summary

Adds a WebMVideo React component that uses ogv.js (WASM-based VP9 decoder, ~444KB) to play WebM videos on Safari/iOS, where native VP9 WebM playback is unreliable. Chrome/Firefox continue using native <video> with zero overhead.

This is a test branch for comparison against test/mp4-high-quality (higher quality MP4 fallback approach). Not intended for direct merge without Safari verification.

How it works:

  • On mount, WebMVideo detects Safari via user-agent sniffing
  • Safari: dynamically loads ogv.js script → creates OGVPlayer instance → renders WebM via WASM decoder to canvas
  • Chrome/Firefox: renders standard <video> with <source> tags (WebM first, MP4 fallback)
  • If ogv.js fails to load, falls back to native <video> with MP4

Review & Testing Checklist for Human

  • 🔴 Test on Safari desktop + iOS Safari — This is the entire purpose of this branch and has NOT been tested by Devin (no Safari available). Verify: (1) ogv.js loads without console errors, (2) both hero and trophy videos play, (3) autoplay/loop work, (4) video is correctly sized and positioned
  • 🔴 Verify ogv.js canvas rendering matches styled-component sizing — On Safari, the component renders a <div> (not <video>) with an ogv.js canvas inside. The CSS from styled(WebMVideo) (fixed 552×552 hero, absolute-positioned 396×396 trophy) may not apply correctly to this different DOM structure. Check for layout breakage.
  • 🟡 Check for duplicate script loading — Two WebMVideo instances exist on the page (hero + trophy). The current implementation injects the ogv.js <script> tag in each component's useEffect with no deduplication. This likely loads ogv.js twice.
  • 🟡 Review OGVPlayer type casts and DOM manipulation — The component casts window.OGVPlayer as HTMLVideoElement (it's not) and uses innerHTML = "" to clear the container ref (React anti-pattern). These are functional shortcuts that may cause subtle issues.
  • 🟢 Compare visual quality vs. MP4 HQ branch — Open both preview URLs on Safari side-by-side to decide which approach is better

Notes


Summary by cubic

Adds a WebMVideo component that enables reliable VP9 WebM playback on Safari/iOS using ogv.js, while keeping native

  • New Features
    • Added WebMVideo: native video on Chromium/Firefox; Safari loads ogv.js; MP4 used if ogv.js fails.
    • Loads ogv.js from /ogv on demand (~444KB) only on Safari.
    • Replaced
    • Vendored ogv.js JS/WASM assets under public/ogv; no npm dependency.

Written for commit 87a2254. Summary will update on new commits.


Open with Devin

On Safari/iOS, VP9 WebM doesn't play natively. Instead of falling back
to lower-quality MP4, use ogv.js (WASM VP9 decoder, ~444KB) to play
WebM on Safari via canvas rendering.

- Add WebMVideo component that detects Safari and loads ogv.js
- Chrome/Firefox use native <video> with WebM (no overhead)
- Safari loads ogv.js WASM files from /ogv/ on demand
- Keep MP4 as ultimate fallback if ogv.js fails to load

Co-Authored-By: Junho Yeo <i@junho.io>
@devin-ai-integration
Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tokscale Error Error Mar 3, 2026 5:23pm

Request Review

cubic-dev-ai[bot]

This comment was marked as resolved.

@junhoyeo junhoyeo marked this pull request as draft March 17, 2026 00:55
Copy link
Copy Markdown
Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 3 additional findings in Devin Review.

Open in Devin Review

Comment on lines +110 to +113
const player = new OGVPlayer();
player.src = webmSrc;
player.muted = !!muted;
player.loop = !!loop;
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🔴 OGVPlayer ignores loop — videos won't loop on Safari

The ogv.js OGVPlayer class has a no-op loop setter (loop:{get:function getLoop(){return!1},set:function setLoop(t){}}), so player.loop = !!loop at line 113 is silently ignored. On Safari/iOS (the ogv.js path), both the hero video and trophy cup video will play once and stop instead of looping continuously. The native <video> path (Chrome/Firefox) works correctly because the HTML video element supports loop natively. The component should listen for the ended event on the ogv player and manually restart playback when loop is true, similar to how autoPlay is manually handled via player.play() at WebMVideo.tsx:124-128.

Suggested change
const player = new OGVPlayer();
player.src = webmSrc;
player.muted = !!muted;
player.loop = !!loop;
const player = new OGVPlayer();
player.src = webmSrc;
player.muted = !!muted;
player.loop = !!loop;
// OGVPlayer's loop setter is a no-op, so manually implement looping
if (loop) {
player.addEventListener("ended", () => {
player.stop();
player.src = webmSrc;
player.play().catch(() => {});
});
}
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant