How to Enable Autoplay Videos in Low Power Mode on iOS and macOS
07 Jun '23

How to Enable Autoplay Videos in Low Power Mode on iOS and macOS

Autoplay in Safari can turn off in Low Power Mode. Below is a tested approach: playsinline, error handling for play() and fallback.

What Really Blocks Autoplay in Safari

Safari often allows muted videos to autoplay, but on iOS, the user or the system can disable this. In practice, autoplay on iPhones is not guaranteed . Therefore, you need to check whether the video has actually started, and if not, show a "play" button or a light, animated preview. This ensures a consistent experience, even in power-saving mode.

Proven Approach: Progressive Improvement

First, implement a standard <video> with muted , playsinline , autoplay , and a light preload. Then try to trigger playback via video.play() . If the browser rejects the promise (e.g., in low-power mode), seamlessly switch to an alternative—an animated image (GIF/WebP/APNG) or an explicit "Play" button. This respects user preferences and doesn't break the project.

<div class="hero-video"> <video id="heroVideo" preload="metadata" autoplay muted playsinline loop poster="https://site.com/video-poster.jpg" class="fullscreen-video"> <source src="https://site.com/video.mp4" type="video/mp4"> <!-- Optional: add WebM for broader support --> <source src="https://site.com/video.webm" type="video/webm"> </video> <!-- Fallback shown if autoplay is blocked (eg, iOS Low Power Mode) --> <img id="fallbackGif" src="https://site.com/video-fallback.gif" alt="Animated preview" style="display:none" /> <button id="playButton" class="button button--primary" aria-controls="heroVideo" aria-label="Play video" hidden>Play</button> </div> <!-- Styles (example) --> <style> .fullscreen-video { width: 100%; height: auto; } .button--primary { position:absolute; left: 1rem; bottom: 1rem; } @media (prefers-reduced-motion: reduce) { .hero-video video { display: none; } #fallbackGif { display: block !important; } } </style> <!-- Script --> <script> (function () { var v = document.getElementById('heroVideo'); var fallback = document.getElementById('fallbackGif'); var btn = document.getElementById('playButton'); function showFallback() { if (v) v.style.display = 'none'; if (fallback) fallback.style.display = 'block'; if (btn) btn.hidden = false; } function tryAutoplay() { if (!v || !v.play) return showFallback(); v.muted = true; // important for mobile autoplay v.playsInline = true; var p = v.play(); if (p && typeof p.then === 'function') { p.then(function () { // autoplay succeeded; keep video visible }).catch(function () { // autoplay blocked (eg, iOS Low Power Mode) showFallback(); }); } else { // Older browsers showFallback(); } } document.addEventListener('DOMContentLoaded', tryAutoplay); if (btn) { btn.addEventListener('click', function () { if (fallback) fallback.style.display = 'none'; if (v) { v.style.display = ''; v.play().catch(function(){ /* user can tap again if needed */ }); } btn.hidden = true; }); } })(); </script> Why It Works (and What to Avoid) <div class="hero-video"> <video id="heroVideo" preload="metadata" autoplay muted playsinline loop poster="https://site.com/video-poster.jpg" class="fullscreen-video"> <source src="https://site.com/video.mp4" type="video/mp4"> <!-- Optional: add WebM for broader support --> <source src="https://site.com/video.webm" type="video/webm"> </video> <!-- Fallback shown if autoplay is blocked (eg, iOS Low Power Mode) --> <img id="fallbackGif" src="https://site.com/video-fallback.gif" alt="Animated preview" style="display:none" /> <button id="playButton" class="button button--primary" aria-controls="heroVideo" aria-label="Play video" hidden>Play</button> </div> <!-- Styles (example) --> <style> .fullscreen-video { width: 100%; height: auto; } .button--primary { position:absolute; left: 1rem; bottom: 1rem; } @media (prefers-reduced-motion: reduce) { .hero-video video { display: none; } #fallbackGif { display: block !important; } } </style> <!-- Script --> <script> (function () { var v = document.getElementById('heroVideo'); var fallback = document.getElementById('fallbackGif'); var btn = document.getElementById('playButton'); function showFallback() { if (v) v.style.display = 'none'; if (fallback) fallback.style.display = 'block'; if (btn) btn.hidden = false; } function tryAutoplay() { if (!v || !v.play) return showFallback(); v.muted = true; // important for mobile autoplay v.playsInline = true; var p = v.play(); if (p && typeof p.then === 'function') { p.then(function () { // autoplay succeeded; keep video visible }).catch(function () { // autoplay blocked (eg, iOS Low Power Mode) showFallback(); }); } else { // Older browsers showFallback(); } } document.addEventListener('DOMContentLoaded', tryAutoplay); if (btn) { btn.addEventListener('click', function () { if (fallback) fallback.style.display = 'none'; if (v) { v.style.display = ''; v.play().catch(function(){ /* user can tap again if needed */ }); } btn.hidden = true; }); } })(); </script>

  • Progressive enhancement: We first attempt autoplay, and if that fails, we show a fallback or "Play" button. The user always sees the action or has a clear choice.
  • Compliance with standards: muted , playsinline , autoplay and light preload are the minimum that works as widely as possible.
  • Avoid tricks: <img> doesn't play MP4. If you need movement, use animated GIF/WebP/APNG.

Optional: Embedded Players (YouTube/Vimeo)

If you use iFrames, you can request muted autoplay, but the system may still block it. So always have a "Play" button overlay or a preview image handy.

<!-- Przykład Vimeo --> <iframe src="https://player.vimeo.com/video/12345?background=1&autoplay=1&muted=1&loop=1&playsinline=1" allow="autoplay; fullscreen; picture-in-picture" loading="lazy" style="width:100%;aspect-ratio:16/9;border:0"></iframe> What do you gain? <!-- Przykład Vimeo --> <iframe src="https://player.vimeo.com/video/12345?background=1&autoplay=1&muted=1&loop=1&playsinline=1" allow="autoplay; fullscreen; picture-in-picture" loading="lazy" style="width:100%;aspect-ratio:16/9;border:0"></iframe>

This approach maintains a consistent experience across iOS and desktop. It preserves the design intent while still adhering to browser rules and power-saving constraints. The result? Engagement even when autoplay is disabled.

Summary

Treat autoplay on Apple devices as a "nice-to-have" rather than a requirement. Use muted videos, check play() score, and if blocked, show an animated preview or button. This combines efficiency, accessibility, and communication consistency.

Support My Work

If you'd like to support new projects or just say thanks, I'd appreciate it. Click PayPal.me — the rest is handled securely by PayPal. Thank you!

Choose amount

Donate via

* Please refrain from donating less than $1. Most of it will be processed as a PayPal transaction fee and the actual donation amount will be $0.

Continue Reading

See all articles