Video formats in WordPress: MOV, MP4 or WebM? (Adobe effects & web)

Video formats in WordPress: MOV, MP4 or WebM? (Adobe effects & web)

Last verified: September 20, 2026
8 min read
News
UI/UX designer
500+ WP projects

Common problem for motion designers and video editors starting with websites: “I made a beautiful animation in Adobe After Effects, rendered to .mov (in best quality!), uploaded to WordPress, and nothing. Black screen, error, or the file weighs 500 MB and loads for an hour.”

The file is not broken. It was made for an edit suite, and a browser is not an edit suite.

#The problem with .mov files

.mov is a container, not a codec. What makes it unusable on the web is usually what is inside it: ProRes, or uncompressed frames.

The sizes are not a matter of opinion. Apple publishes them. At 1920x1080 and 29.97 fps, the ProRes white paper gives target data rates of 45 Mbps for 422 Proxy, 102 Mbps for 422 LT, 147 Mbps for 422, 220 Mbps for 422 HQ, 330 Mbps for 4444 and 495 Mbps for 4444 XQ. The appendix in the same document restates those as gigabytes per hour: 422 HQ is 99 GB per hour, which is about 1.65 GB for a single minute of footage. A twenty second hero loop straight out of After Effects can therefore be larger than the entire rest of the site.

Two things then go wrong inside WordPress, in this order.

The upload may not finish at all. wp_max_upload_size() reads upload_max_filesize and post_max_size from PHP and returns the smaller of the two. On shared hosting those are frequently left at modest defaults, and a multi hundred megabyte POST dies before the media library ever sees it.

If it does finish, it still will not play. This is the part nobody explains. WordPress accepts the file because wp_get_mime_types() contains 'mov|qt' => 'video/quicktime'. But wp_get_video_extensions(), the function that decides what core considers a playable video source, returns only mp4, m4v, webm, ogv and flv. MOV is not on that list. So the attachment sits in the library looking like a video and behaving like a download.

Even if you force the markup by hand, the browser will not save you. MDN’s container guide records no QuickTime playback in current Chrome, Edge, Firefox or Safari, and notes that the QuickTime framework itself has been gone from macOS since 10.15 Catalina. A ProRes bitstream has no decoder in any shipping browser.

#HTML5 standard: MP4 with H.264 and WebM

Two formats cover the whole web, and the choice between them is less dramatic than it was when this article was first written.

#1. MP4 with H.264

The safe default. caniuse puts H.264 in MP4 at roughly 97 percent global support, going back to Chrome 4, Safari 3.2 and IE 9. If you ship one file, ship this one.

Two settings decide whether your export actually works, and both are invisible in a preview player.

Chroma subsampling. ProRes 422 is, as the name says, 4:2:2, and the 422 family is 10 bit. Hand that to libx264 without instruction and it will happily encode a High 4:2:2 profile stream that no browser can decode. Force 8 bit 4:2:0:

ffmpeg -i source.mov -c:v libx264 -crf 23 -preset slow \
  -pix_fmt yuv420p -c:a aac -b:a 128k \
  -movflags +faststart web.mp4

Where the index lives. FFmpeg’s muxer documentation describes -movflags +faststart as a second pass that runs “moving the index (moov atom) to the beginning of the file”, and explicitly notes it is not enabled by default. Without it the browser cannot begin playback until the whole file has arrived, which is exactly the “loads for an hour” symptom. Verify rather than assume, because the flag is silent when it is missing:

grep -abo -m2 -e moov -e mdat web.mp4

That prints the byte offset of the first moov and the first mdat. You want the moov offset to be the smaller one.

If you are exporting from Adobe Media Encoder rather than the command line, pick H.264 as the format, not QuickTime, and then run the two checks above on the result. The format list is the only thing that matters; preset names move between releases.

#2. WebM with VP9, and AV1

Google’s own VP9 page claims the codec “can reduce video bit rates by as much as 50% compared with other known codecs”. Treat that as a ceiling reached on hard content, not a number you will hit on every clip, but the saving on a flat motion graphic is real.

The stale advice on this topic is that WebM is a Chrome and Firefox format. It is not, and has not been for several years. caniuse records full WebM support in Safari on macOS from version 16 and in Safari on iOS from 17.4. That puts global support at 96.25 percent, under a point behind H.264 in MP4.

ffmpeg -i source.mov -c:v libvpx-vp9 -crf 33 -b:v 0 -row-mt 1 \
  -pix_fmt yuv420p -c:a libopus -b:a 96k web.webm

AV1 sits one generation further on. caniuse gives it 79.26 percent full support, rising to 94.28 percent only if you count partial, and Safari is the partial one because playback there depends on hardware decode. That makes AV1 a first <source>, never the only one.

Transparency is the one place where no single file wins. VP9 in WebM carries an alpha channel if you encode to yuva420p, and Chromium and Firefox render it. Safari does not. Apple’s answer is HEVC with alpha, which it documents in its HEVC Video with Alpha Interoperability Profile. If an After Effects composition needs a real alpha channel on the web, you are shipping two files and a solid colour fallback.

HandBrake covers all of this in a GUI if you prefer one: its feature list names AV1, H.265, H.264, VP8 and VP9 as encoders, with MP4, MKV and WebM as containers.

#The video tag strategy in HTML5

If you are self hosting, for instance as a hero background, list sources best first. The browser takes the first one it can decode and never looks at the rest.

<video autoplay loop muted playsinline preload="none"
       poster="/media/hero-poster.avif">
  <source src="/media/hero.webm" type="video/webm; codecs=vp9">
  <source src="/media/hero.mp4" type="video/mp4; codecs=avc1.42E01E">
  Your browser doesn't support video.
</video>

The attributes are doing specific jobs:

  • muted plus playsinline: mobile browsers refuse autoplay without both. Without playsinline, iOS takes the video fullscreen the moment it starts, which destroys a background loop.
  • preload="none": nothing is fetched until playback is requested, so the poster carries the first paint. Use metadata if you need duration up front, and auto almost never.
  • poster: an AVIF or WebP still is a fraction of the video and is what the visitor actually sees during the first seconds.
  • the codecs= part of the type string: it lets the browser reject a source without downloading a byte of it.

In the block editor you do not have to write this by hand. The core Video block carries autoplay, controls, loop, muted, playsInline, poster, preload, src and tracks as attributes, and playsInline is exposed in the sidebar as the “Play inline” toggle. The Cover block has no such attribute: its block.json exposes no playsInline key, and its save output hardcodes playsInline on the background video, so a Cover video loop is always inline and there is no toggle to check.

#Or maybe YouTube or Vimeo

Self hosting gives you one file at one bitrate delivered by progressive HTTP download. There is no adaptive ladder. WordPress builds resized renditions for images at upload time and does nothing equivalent for video, because core ships no transcoder. A visitor on a weak mobile connection gets your 1080p file or gets nothing, and stalls while it buffers.

So the rule is about what the video is, not how big it is. Content with sound that a visitor came to watch, an interview, a tutorial, a case study walkthrough, belongs on YouTube or Vimeo, where the platform encodes a ladder of renditions and switches between them. A silent decorative loop behind a headline belongs on your own server, because an embed drags in a third party player and its cookies for something that is closer to a moving background image.

Bandwidth is the second half of that decision. A 10 MB loop on a page that gets fifty thousand views a month is half a terabyte of egress, and on entry level hosting that is a conversation with your provider.

#Workflow summary

  1. Edit and master in After Effects or Premiere against .mov and ProRes. That part was never wrong.
  2. Export for the web as H.264 in MP4, forcing -pix_fmt yuv420p and -movflags +faststart.
  3. Confirm the export: check that moov sits at a lower byte offset than mdat, and check with ffprobe that the pixel format is yuv420p, not yuv422p10le.
  4. Add a VP9 WebM copy and list it before the MP4 in the <video> element. Add AV1 above both if you are chasing the last few hundred kilobytes.
  5. Give the element a poster image and preload="none", and keep muted and playsinline on any autoplaying loop.
  6. If the clip has sound and someone is meant to sit and watch it, put it on YouTube or Vimeo instead and embed it.

If this sits inside a build we maintain, we set the encode step up once in the deploy pipeline so nobody has to remember the flags. That is part of our WordPress development services.

Next step

Turn the article into an actual implementation

This block strengthens internal linking and gives readers the most relevant next move instead of leaving them at a dead end.

Want this implemented on your site?

If you want to convert the article into a working site improvement, redesign, or build plan, I can define the scope and implement it.

Related cluster

Explore other WordPress services and knowledge base

Strengthen your business with professional technical support in key areas of the WordPress ecosystem.

Why does my .mov upload but refuse to play in WordPress?#
The upload works because video/quicktime is in the default mime map returned by wp_get_mime_types(). Playback fails because wp_get_video_extensions() returns mp4, m4v, webm, ogv and flv, and mov is not on that list, so the Video block never hands the browser a source it can decode. MDN's container guide reports no QuickTime playback in current Chrome, Edge, Firefox or Safari.
How big is a ProRes file really?#
Apple's own white paper puts ProRes 422 HQ at 1920x1080 and 29.97 fps at about 220 Mbps, and its appendix converts that to 99 GB per hour, so roughly 1.65 GB per minute. Plain ProRes 422 is 147 Mbps and 66 GB per hour. That is before you reach the default PHP upload ceiling that wp_max_upload_size() reads from upload_max_filesize and post_max_size.
Is WebM still a Chrome and Firefox only format?#
No, and that advice is the most common stale claim on this topic. caniuse records full WebM support in Safari on macOS from version 16 and in Safari on iOS from 17.4, putting global support at 96.25 percent, under a point behind H.264 in MP4. An MP4 fallback is still worth keeping for older iOS devices that will never get an update.
Why does my exported MP4 only start playing after it fully downloads?#
The moov atom is at the end of the file. FFmpeg's muxer documentation describes -movflags +faststart as a second pass that moves that index to the beginning, which is what lets a browser start playback from a partial download. Check the order by scanning the file for the two atom names, for example grep -abo -m2 -e moov -e mdat web.mp4, and confirm the moov offset is the smaller one.
Can I put a transparent After Effects animation on a web page?#
Partly. VP9 in WebM carries an alpha channel when you encode to yuva420p, which Chromium and Firefox render. Safari does not read that, and Apple's route is HEVC with alpha, documented in its HEVC Video with Alpha Interoperability Profile. There is no single transparent video file that covers every browser, so plan a non-transparent fallback.

Need an FAQ tailored to your industry and market? We can build one aligned with your business goals.

Let’s discuss

Related Articles

AI-slop content cleanup

A YMYL diagnostic for WordPress sites: how to find fake stats, fabricated citations, duplicate AI pages, wrong dates, and invented team bios before they damage trust, compliance, or AI citations.