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

Tech, Insights & Process, Web Development

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

How do you bypass autoplay blocking in Safari (iOS/macOS) in Low Power Mode? Learn about the playsinline attribute, handling video.play() errors, and fallback techniques with animated WebP/GIF.

The real challenge in Safari:

In many cases Safari allows autoplay of muted videos embedded in content, but on iOS devices the user or the system can block it. In practice this means you cannot guarantee autoplay on an iPhone - so you need to detect whether playback started, and if not, show a subtle "tap to play" message or an animated placeholder image. This keeps the user experience consistent even in Low Power Mode.

A solid solution: progressive enhancement

Start with a standard <video> element with muted, playsinline, autoplay, and light preload. Then attempt to start playback using video.play(). If the browser rejects the promise (for example, in low power mode), smoothly switch to a fallback - show an animated image (GIF/WebP/APNG) or a visible "Play" button. This approach respects the user's settings while maximizing engagement.

<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 (e.g., 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 (e.g., 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 this works (and what to avoid):

  • Progressive enhancement: First we try muted autoplay; if it is not allowed, we switch to an animated image or a clear "Play" button. That way users always see motion or can start playback with one click.
  • Standards compliance: Using muted, playsinline, autoplay, and light preload aligns with browser autoplay policies.
  • Avoid hacks: Do not try to "play" a video via an <img> pointing to an MP4 file - images do not render video. Use a real animated image (GIF/WebP/APNG) instead.

Optional: embedded players (YouTube/Vimeo)

If you use iframes, you can request muted autoplay, but the user or the system can still block it. That is why you should always keep a play overlay or a poster image.

<!-- Vimeo example -->
<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>

Benefits and impact:

With this approach, you provide a consistent and user-friendly experience on both iOS and desktop. You preserve the design intent while respecting browser rules and energy-saving constraints. The result is higher engagement even when autoplay is blocked.

Summary:

Treat autoplay on Apple devices as a "nice-to-have" rather than a guarantee. Build solutions with muted embedded video, detect play() failures, and if needed switch to an animated preview or a one-click play action. This approach combines performance, accessibility, and brand impact.

Your support is appreciated

If you want to support new projects or say thank you for the work so far, it would be greatly appreciated. To donate, click PayPal.me - the secure PayPal system will take care of the rest. Thank you for your support!

Continue Reading

See all articles