You probably ran into a bug where your video that had muted, loop, playsinline, autoplay properties set was not playing and had a giant play button overlay on it when using Safari.

This happens due to Low Power Mode. Apple prevents automatic playback of any video with LPM enabled.

Unfortunately there is no way around it other than getting the user to press the native play button or a custom one that calls the play() function on the video element.

~ UPDATE ~
There is a very clever workaround that is specific to Mobile Safari.

Delivering Video Content for Safari | Apple Developer DocumentationImprove the performance and appearance of video in your website in Safari.developer.apple.com/documentation/webkit/delivering-video-content-for-safari

Apple has this example documented in their WebKit docs so it shouldn't get patched in the next Safari release.

1<picture>
2 <source srcset="explosion.mp4" type="video/mp4">
3</picture>

No way to detect LPM

iOS does not expose a way to detect if Low Power Mode is enabled to prevent fingerprinting risk when websites track you.

However you can specifically target Safari with CSS to show this hacky <picture> element with an MP4 source while hiding it for every other browser by default.

Three.js and React Three Fiber also affected

With Low Power Mode enabled, you will not be able to autoplay a video plane inside a Three.js scene either without user interaction.

WebP workaround for short videos

If this is a tiny decorative video there is a possible way to work around this issue. Safari treats animated images differently than videos and lets them autoplay without any restrictions in LPM.

Only supported in Safari 16 or newer. Safari 14 and 15 have partial support but you might encounter issues.

You're going to need to use ffmpeg to convert your video into WebP first.

1ffmpeg -i VIDEO_FILE.mp4 -vcodec libwebp -lossless 0 -q:v 80 -loop 0 -an OUTPUT.webp

Then set up a component that loads up the video and checks if it can be played. If playback fails then hide the video element and show an <img> with a WebP source in its place.

However, I truly do not recommend this method as the WebP file will most likely be much larger than the original video and take longer to load + use even more resources.

Easier to just let go and give up. You win this one, Tim Apple. 😩

Update: Use the MP4 as a <picture> source workaround instead!

Thanks for your attention.