OpenCut/apps/web
Andrés Villagrán 6f7dacb4d4 feat(export): offer server transcode to MP4 when WebCodecs is missing
The MediaRecorder export fallback introduced in #797 always emits a
WebM container (most browsers don't expose an MP4 muxer through
MediaRecorder). WebM plays in Chrome / Firefox / VLC but not
natively in QuickTime or Safari, so users on browsers without
WebCodecs who picked the MP4 format end up with a file they can't
open in those players.

This adds an opt-in escape hatch in the export popover:

- When `isWebCodecsExportSupported()` is false AND the user picked
  MP4, the popover surfaces a "Browser compatibility" section that
  explains the situation and offers a "Transcode to H.264 MP4 on
  the server" checkbox (defaulted to on, since the user did ask
  for MP4).
- When the checkbox is on, the post-export flow wraps the produced
  WebM buffer in a `File` and runs it through `convertVideoToH264`,
  which already routes to the existing `/api/convert-video` ffmpeg
  endpoint. The downloaded file is a real H.264 MP4.
- If the user opts out, the popover keeps the WebM extension and
  mime type so the saved file matches its real container.
- If the server transcode fails, the export is preserved as WebM
  and the user is notified via a toast.

A small "Transcoding to MP4 on server…" section is shown in the
popover between the export finishing and the download starting,
since that step can take a noticeable amount of time on large
clips.

The WebCodecs-capable code path is unchanged: the warning section
is only rendered when `!isWebCodecsExportSupported() && format ===
"mp4"`.
2026-05-16 22:01:00 -04:00
..
migrations chore: normalize line endings 2026-03-29 15:56:48 +02:00
public chore: delete ffmpeg public assets 2026-04-21 13:00:26 +02:00
scripts chore: normalize line endings 2026-03-29 15:56:48 +02:00
src feat(export): offer server transcode to MP4 when WebCodecs is missing 2026-05-16 22:01:00 -04:00
.env.example chore: remove transcription envs 2026-04-04 08:53:10 +02:00
.gitignore chore: update .gitignore 2026-03-29 18:55:56 +02:00
Dockerfile chore: remove transcription envs 2026-04-04 08:53:10 +02:00
components.json chore: normalize line endings 2026-03-29 15:56:48 +02:00
content-collections.ts feat: new-release notice and colocate changelog under domain 2026-04-15 02:05:41 +02:00
drizzle.config.ts fix: correct schema path in drizzle config 2026-04-15 06:04:29 +02:00
next.config.ts feat: migrate GPU renderer from WebGL to wgpu/WASM 2026-04-01 13:57:32 +02:00
open-next.config.ts chore: add missing open-next config 2026-03-29 15:58:46 +02:00
package.json chore: switch from biome to eslint + prettier; fix ton of lint issues 2026-05-02 03:27:23 +02:00
postcss.config.mjs feat: masks, properties refactor, shaders, storage migrations, and more 2026-03-29 15:48:22 +02:00
tsconfig.json chore: switch from biome to eslint + prettier; fix ton of lint issues 2026-05-02 03:27:23 +02:00
wrangler.jsonc chore: normalize line endings 2026-03-29 15:56:48 +02:00