Make WordPress Core

Opened 4 weeks ago

Closed 4 weeks ago

Last modified 4 weeks ago

#65664 closed defect (bug) (fixed)

Media: GIF to video conversion fails because the video-conversion worker is missing from the import map

Reported by: adamsilverstein Owned by: adamsilverstein
Priority: normal Milestone: 7.1
Component: Media Version:
Severity: normal Keywords: has-patch has-unit-tests commit
Cc: Focuses:

Description

Animated GIF uploads through the client-side media pipeline never produce their animated_video companion file (added in #65549). The conversion fails silently for users; the console shows:

[video-conversion] GIF to video conversion failed: TypeError: Failed to resolve module specifier '@wordpress/video-conversion/worker'

followed by a secondary blob: ... net::ERR_FILE_NOT_FOUND error. Other client-side processing (thumbnails via vips, HEIC, AVIF) works, which masks the problem.

Root cause

upload-media.js loads the conversion worker lazily via import( '@wordpress/video-conversion/worker' ), resolved through the script modules import map. Two bugs break that resolution:

  1. wp_set_client_side_media_processing_flag() (hooked on admin_init) calls:
    wp_scripts()->add_data(
            'wp-upload-media',
            'module_dependencies',
            array( '@wordpress/vips/worker' )
    );
    
    WP_Scripts::add_data() overwrites rather than merges, so this clobbers the module_dependencies already registered from script-loader-packages.php, which declare both @wordpress/vips/worker and @wordpress/video-conversion/worker. The call was harmlessly redundant when introduced in [62428] (see #64919) - at that point the packages file only declared the vips worker - and silently became destructive when the video-conversion dependency was added to the asset file. Result: the import map only ever contains the vips worker, and the dynamic import throws.
  1. After fixing the above, environments running with SCRIPT_DEBUG still fail: the Gutenberg build only ships video-conversion/worker.min.js (like the VIPS modules, the unminified file is large inlined worker code and is not produced), but wp_default_script_modules() only special-cases vips/ to always use the minified file. The import map then points at a non-existent worker.js, which 404s.

Steps to reproduce

  1. On trunk (secure context or localhost, Chromium), open the block editor.
  2. Upload an animated, non-transparent GIF.
  3. Note the console error above and that the resulting attachment's media_details contains no animated_video / animated_video_poster entries.

Proposed fix

  • Remove the add_data() call from wp_set_client_side_media_processing_flag() - the packages asset file already registers both workers when wp-upload-media is registered.
  • Extend the always-minified condition in wp_default_script_modules() to cover video-conversion/worker.js.

Verified manually: after the fix the import map contains both workers, the GIF upload completes with no console errors, and the attachment gains animated_video: <name>.mp4 and animated_video_poster: <name>.jpeg with both companions sideloaded.

PR: https://github.com/WordPress/wordpress-develop/pull/12598

Related: #64919, #65549. Surfaced while testing the Media Library grid pipeline work on #65661.

Change History (6)

#1 @adamsilverstein
4 weeks ago

  • Owner set to adamsilverstein
  • Status newreviewing

This ticket was mentioned in PR #12598 on WordPress/wordpress-develop by @adamsilverstein.


4 weeks ago
#2

  • Keywords has-patch added

## What

Fixes animated GIF to video conversion, which currently fails silently everywhere client-side media processing runs (block editor included): no animated_video companion is created, and the console shows:

[video-conversion] GIF to video conversion failed: TypeError: Failed to resolve module specifier '@wordpress/video-conversion/worker'

## Why

Two separate bugs prevent upload-media.js from lazily importing the conversion worker:

  1. wp_set_client_side_media_processing_flag() clobbers the import map. It calls wp_scripts()->add_data( 'wp-upload-media', 'module_dependencies', array( '@wordpress/vips/worker' ) ) on every admin request. add_data() overwrites rather than merges, wiping the module_dependencies already registered from script-loader-packages.php - which include both @wordpress/vips/worker and @wordpress/video-conversion/worker. The call was harmlessly redundant when introduced in [62428] (the packages file only declared the vips worker then) and became destructive when the video-conversion dependency landed in the asset file. With the entry missing from the import map, the dynamic import() throws. Since the packages registration already handles this correctly, the call is simply removed.
  1. The unminified video-conversion/worker.js is never shipped. Like the VIPS modules, the Gutenberg build only produces worker.min.js (the file is large inlined worker code with no debugging value), but wp_default_script_modules() only special-cases vips/ to always use the minified file. With SCRIPT_DEBUG enabled, the import map pointed at a non-existent worker.js and the import 404ed. The existing vips condition is extended to cover video-conversion/worker.js.

## Testing

Manually verified on trunk (Chrome, cross-origin isolated via Document-Isolation-Policy):

Before: uploading an animated GIF logs the module-specifier TypeError (plus a secondary blob: ... ERR_FILE_NOT_FOUND error), and the attachment's media_details has no animated_video.

After: the same upload completes with no console errors, the import map contains both workers, and the attachment gains animated_video: <name>.mp4 and animated_video_poster: <name>.jpeg, with both companion files sideloaded to the uploads directory.

The generic module_dependencies API tests in tests/phpunit/tests/dependencies/scripts.php and tests/phpunit/tests/script-modules/wpScriptModules.php are unaffected; php -l and PHPCS pass on both changed files.

#3 @adamsilverstein
4 weeks ago

  • Keywords has-unit-tests added

#4 @adamsilverstein
4 weeks ago

  • Keywords commit added

This is approved for commit.

#5 @adamsilverstein
4 weeks ago

  • Resolutionfixed
  • Status reviewingclosed

In 62807:

Media: Fix animated GIF to video conversion module loading.

Fix an issue with animated GIF conversion where the conversion worker could not be resolved from the script modules import map. wp_set_client_side_media_processing_flag() re-declared the wp-upload-media module dependencies via WP_Scripts::add_data(), which overwrites rather than merges, wiping the @wordpress/video-conversion/worker entry already registered from the packages asset file.

Additionally, only a minified build of the video-conversion worker is shipped, so with SCRIPT_DEBUG enabled the import map pointed at a non-existent worker.js. The always-minified exception in wp_default_script_modules() is extended from the vips modules to also cover video-conversion/worker.js.

Follow-up to [62428].

Props andrewserong, swissspidy.
Fixes #65664.

Note: See TracTickets for help on using tickets.