Skip to content

Client-side media: add timeout and size guardrails to GIF to video conversion #80376

Description

@adamsilverstein

What problem does this address?

The client-side GIF→video conversion works well for typical GIFs, but for large ones it can degrade badly. During testing on #80260, @andrewserong uploaded raw screen-recording GIFs (large pixel dimensions, ~20 MB) and hit conversions that appeared hung - one eventually finished after 30 minutes on a MacBook Air (comment, test GIFs).

As discussed in this comment and this one, the feature ceases to be useful once conversion takes longer than a "fairly quick" amount of time. The GIF itself uploads fine; the companion video is a progressive enhancement - so when conversion is expensive we should skip or abandon it rather than churn the user's CPU for minutes.

What is your proposed solution?

Add two guardrails so the conversion is seamless: fast when it can be, invisible when it can't.

1. Conversion timeout (default: 30 seconds)

If the GIF→video conversion has not completed within a timeout (default 30s), abandon it and keep only the uploaded GIF:

  • Cancel the in-flight conversion. The worker loop in packages/video-conversion/src/index.ts already checks inProgressOperations at every async boundary (including per frame), so an existing cancellation path can be reused.
  • Silently cancel the companion-video sideload, exactly like the existing "unsupported" graceful-skip path in convertGifToVideoOperation (packages/upload-media/src/store/private-actions.ts). No user-facing error - from the user's perspective they uploaded an image and it worked.
  • Log the skip to the console for debuggability, following the existing unconditional console.error( '[video-conversion] …' ) pattern used for real engine failures in the same catch block (client-side code has no WP_DEBUG signal; the plain-console pattern is the established precedent here).

The timeout should be filterable/configurable so hosts or plugins can raise it (e.g. 0 to disable).

2. Maximum size gate (don't even try)

Before running the encode loop, check whether the GIF is plausibly convertible in a reasonable time. The cost is roughly proportional to width × height × frameCount (total decoded pixels), so a single pixel-budget threshold covers all three dimensions.

This can be checked cheaply: in packages/video-conversion/src/index.ts, frameCount and the frame dimensions are available right after decoder.tracks.ready resolves, before any frame is decoded or encoded. If the budget is exceeded:

  • Throw the existing Unsupported-prefixed error (or a new dedicated prefix) so the caller takes the graceful-skip path - GIF stays as-is, no companion video, no user-facing error.
  • Log a console warning explaining the skip and the threshold, so developers testing large GIFs understand why no video was produced.

The default budget needs benchmarking against real-world GIFs (Andrew's test files above are a good starting corpus), but the goal is: anything that would plausibly blow the 30s timeout on modest hardware shouldn't start at all. Like the timeout, the budget should be filterable.

Interaction with related work

Step-by-step reproduction instructions

  1. Enable client-side media processing.
  2. Upload a large raw screen-recording GIF, e.g. 2026-07-10 14.44.24.gif from this comment.
  3. Observe the conversion runs for many minutes (up to ~30 minutes on a MacBook Air) with the upload appearing hung.

Expected with this enhancement: the GIF uploads normally; the video conversion either finishes within ~30s or is skipped/abandoned silently, with a console message explaining why.

Activity

  1. added and removed
    [Feature] MediaAnything that impacts the experience of managing media
    on Jul 17, 2026
  2. added
    [Type] BugAn existing feature does not function as intended
    and removed on Jul 17, 2026
  3. moved this from 🏗️ In Progress to ✅ Done in WordPress 7.1 Editor Taskson Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

[Feature] Client Side MediaMedia processing in the browser with WASM[Status] In ProgressTracking issues with work in progress[Type] BugAn existing feature does not function as intended

Type

Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions