12

I have these videos on my site with attributes listed below:

<video width="100%" poster="poster_url.png" autoplay loop muted playsinline>
<source src="video_url.mp4" type="video/mp4">
</video>    

Everything worked just fine until I’ve installed Safari 11. This version shows poster images and does not autoplay videos even though they don't have an audio track. Take a look at it on my site.

I saw autoplay videos working on other sites (even without muted property) on my own laptop in Safari.

Any help would be greatly appreciated!

Andrey
  • 123
  • 1
  • 1
  • 4

5 Answers5

11

Yup, it appears Safari is also blocking muted video's (that don't even have sound)...

I have found a workaround, but it isn't pretty and I'm not proud of it:

var ua = navigator.userAgent.toLowerCase();
var is_safari = (ua.indexOf("safari/") > -1 && ua.indexOf("chrome") < 0);
if(is_safari) {
    var video = document.getElementById('#video-element-id');
    setTimeout(function() {
       video.play();
    }, 50);
}                       

I have tried doing this without the timeout, but Safari is rejecting this by throwing a Promise rejection. I don't know why...

PIDZB
  • 903
  • 1
  • 15
  • 38
6

I ran into this issue as well for a short mp4 that played in the background of a website. I was able to get a solution working for iOS Safari 11 without the need for JS by qualifying the video tag with controls="true" and playsinline.

Example:

<video autoplay loop playsinline muted controls="true" src="~/background.mp4" type="video/mp4"></video>

Note: Safari doesn't support .webm so don't be like me and struggle with that for longer than you'd like to admit.

Ben Sampica
  • 2,912
  • 1
  • 20
  • 25
  • also does not work. in my case i have videos that autoplay perfectly with `playsinline` but i'm trying to toggle mute on a user gesture of clicking a certain button (can't show controls). adding in the controls attribute doesn't allow toggling of the volume as i'm doing. my project works in desktop chrome/desktop ff - just not desktop safari/mobile safari. – Stephen Tetreault Jul 14 '18 at 21:19
  • was at my wits end because the issue didn't make sense. turns out a nuxt module for vuejs was butchering ranged requests. apologies if i offended you. – Stephen Tetreault Sep 25 '18 at 23:08
4

The most reliable way I've found is to ensure:

  • at least one user interaction on the page (chrome mobile)
  • muted attribute on tag (all)
  • playsinline attribute on tag (safari)

Which looks like this:

<style>
  video {
    display: none;
  }
  video.active {
    display: block;
  }
</style>
<button id="button">Show video</button>
<video id="video" muted playsinline></video>
<script>
    var button = document.getElementById('button');
    var video = document.getElementById('video');
    button.addEventListener('click', function() {
        video.className = 'active';
        video.src = 'https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4';
        video.play();
    });
</script>

One trick is to reuse the same video player for each video. Then it only needs to be activated the first time. Every consecutive play can occur automatically.

Kim T
  • 5,770
  • 1
  • 52
  • 79
1

Put the src attribute inside the <video> instead of using <source>

<video src="video_url.mp4" width="100%" poster="poster_url.png" autoplay loop muted playsinline></video>

With <source> it only works if the element is in view when the page loads (tested on safari 11.0)

A link of Auto-Play Policy Changes for macOS.

0

I ran into a similar problem and solved it with the canplaythrough event (or the canplay event). This might solve the need for setTimeout in Abayob's solution:

const video = document.getElementById('#video-element-id');
video.oncanplaythrough = function() {
    video.play();
}
Adam Kiryk
  • 55
  • 4