[javascript] Video auto play is not working in Safari and Chrome desktop browser

I spent quite a lot of time trying to figure out why video embedded like here:

<video height="256" loop autoplay muted controls id="vid">
         <source type="video/mp4" src="video_file.mp4"></source>
         <source type="video/ogg" src="video_file.ogg"></source>
</video>

starts playing automatically once the page is loaded in FireFox but cannot do autoplay in Webkit based browsers. This only happened on some random pages. So far I was unable to find the cause. I suspect some unclosed tags or extensive JS created by CMS editors.

This question is related to javascript html google-chrome safari webkit

The answer is


Try this:

  <video width="320" height="240"  autoplay muted>
            <source src="video.mp4" type="video/mp4">
  </video>

Chrome does not allow to auto play video with sound on, so make sure to add muted attribute to the video tag like this

<video width="320" height="240"  autoplay muted>
  <source src="video.mp4" type="video/mp4">
</video>

Adding the below code at the bottom of the page worked for me . I dont know why it works :(

 setTimeout(function(){
     document.getElementById('vid').play();
 },1000);

I had a case where it had something to do with the order of the different filetypes. Try to change it and see if that helps.


I started out with playing all the visible videos, but old phones weren't performing well. So right now I play the one video that's closest to the center of the window and pause the rest. Vanilla JS. You can pick which algorithm you prefer.

//slowLooper(playAllVisibleVideos);
slowLooper(playVideoClosestToCenter);

function isVideoPlaying(elem) {
    if (elem.paused || elem.ended || elem.readyState < 2) {
        return false;
    } else {
        return true;
    }
}
function isScrolledIntoView(el) {
    var elementTop = el.getBoundingClientRect().top;
    var elementBottom = el.getBoundingClientRect().bottom;
    var isVisible = elementTop < window.innerHeight && elementBottom >= 0;
    return isVisible;
}
function playVideoClosestToCenter() {
    var vids = document.querySelectorAll('video');
    var smallestDistance = null;
    var smallestDistanceI = null;
    for (var i = 0; i < vids.length; i++) {
        var el = vids[i];
        var elementTop = el.getBoundingClientRect().top;
        var elementBottom = el.getBoundingClientRect().bottom;
        var elementCenter = (elementBottom + elementTop) / 2.0;
        var windowCenter = window.innerHeight / 2.0;
        var distance = Math.abs(windowCenter - elementCenter);
        if (smallestDistance === null || distance < smallestDistance) {
            smallestDistance = distance;
            smallestDistanceI = i;
        }
    }
    if (smallestDistanceI !== null) {
        vids[smallestDistanceI].play();
        for (var i = 0; i < vids.length; i++) {
            if (i !== smallestDistanceI) {
                vids[i].pause();
            }
        }
    }
}
function playAllVisibleVideos(timestamp) {
    // This fixes autoplay for safari
    var vids = document.querySelectorAll('video');
    for (var i = 0; i < vids.length; i++) {
        if (isVideoPlaying(vids[i]) && !isScrolledIntoView(vids[i])) {
            vids[i].pause();
        }
        if (!isVideoPlaying(vids[i]) && isScrolledIntoView(vids[i])) {
            vids[i].play();
        }
    }
}
function slowLooper(cb) {
    // Throttling requestAnimationFrame to a few fps so we don't waste cpu on this
    // We could have listened to scroll+resize+load events which move elements
    // but that would have been more complicated.
    function repeats() {
        cb();
        setTimeout(function() {
            window.requestAnimationFrame(repeats);
        }, 200);
    }
    repeats();
}

This is because of now chrome is preventing auto play in html5 video, so by default they will not allow auto play. so we can change this settings using chrome flag settings. this is not possible for normal case so i have find another solution. this is working perfect... (add preload="auto")

<video autoplay preload="auto" loop="loop" muted="muted" id="videoBanner" class="videoBanner">
<source src="banner-video.webm" type="video/webm">
<source src="banner-video.mp4" type="video/mp4">
<source src="banner-video.ogg" type="video/ogg">

var herovide = document.getElementById('videoBanner');
       herovide.autoplay=true;
       herovide.load();  

Try swapping in autoPlay for autoplay.

It seems to be case sensitive at times. Very bizarre because it worked as autoplay for me, but only if I included controls


I've just get now the same issue with my video

<video preload="none" autoplay="autoplay" loop="loop">
  <source src="Home_Teaser.mp4" type="video/mp4">
  <source src="Home_Teaser" type="video/webm">
  <source src="Home_Teaser.ogv" type="video/ogg">
</video>

After search, I've found a solution:

If I set "preload" attributes to "true" the video start normally


Try this it is simple and short and it works with my code whereas I have the video full screen and behind other elements I simply use z-index -1;

    <video autoplay loop id="myVideo">

Angular 10:

<video [muted]="true" [autoplay]="true" [loop]="true">
    <source src="/assets/video.mp4" type="video/mp4"/>
</video>

Google just changed their policy for autoplay videos, it has to be muted

You can check here

so just add muted

<video height="256" loop="true" autoplay="autoplay" controls="controls" id="vid" muted>
         <source type="video/mp4" src="video_file.mp4"></source>
         <source type="video/ogg" src="video_file.ogg"></source>
</video>

It happens that Safari and Chrome on Desktop do not like DOM manipulation around the video tag. They will not fire the play order when the autoplay attribute is set even if the canplaythrough event has fired when the DOM around the video tag has changed after initial page load. Basically I had the same issue until I deleted a .wrap() jQuery around the video tag and after that it autoplayed as expected.


Google updated Autoplay Policy. Autoplay only work on mute mode. Check the link https://developers.google.com/web/updates/2017/09/autoplay-policy-changes


For me the issue was that the muted attribute needed to be added within the video tag. I.e.:

<video width="1920" height="1980" src="video/Night.mp4"
type="video/mp4" frameborder="0" allowfullscreen autoplay loop
muted></video>`

In React + Chrome, it's better to import the video than give it as src to .

import React from 'react';
import styled from 'styled-components';
import video from './videos.mp4';
const StyledVideo = styled.video`
width: 100%;
height: 100vh;
object-fit: cover;
`
const BackgroundVideo = () => {
return (
    <StyledVideo autoPlay loop muted>
        <source src={video} type="video/mp4" />
    </StyledVideo>
);
}

Remember

  • The video is in the same directory, to import it.
  • To autoplay, the video in the background, use autoPlay and muted props are there.

I got mine to autoplay by making it muted. I think Google rules won't let chrome auto-play unless it's muted.

<video id="video" controls autoplay muted
        border:0px solid black;"
        width="300"
        height="300">
    <source src="~/Videos/Lumen5_CTAS_Home2.mp4"
            type="video/mp4" />
    Your browser does not support the video tag.
    Please download the mp4 plugin to see the CTAS Intro.
</video>

None of the other answers worked for me. My workaround was to trigger a click on the video itself; hacky (because of the timeout that is needed) but it works fine:

function startVideoIfNotStarted () {
    $(".id_of_video_tag").ready(function () {
        window.setTimeout(function(){
            videojs("id_of_video_tag").play()
        }, 1000);
    });
}
$(startVideoIfNotStarted);

On safari iPhone when battery is low and iPhone is on Low Power Mode it won`t autoplay, even if you have the following attributes: autoplay, loop, muted, playsinline set on your video html tag.

Walk around I found working is to have user gesture event to trigger video play:

document.body.addEventListener("touchstart", function () {
    var allVideos = document.querySelectorAll('video');
    for (var i = 0; i < allVideos.length; i++) {
        allVideos[i].play();
    }
},{ once: true });

You can read more about user gesture and Video Policies for iOS in webkit site:

https://webkit.org/blog/6784/new-video-policies-for-ios/


Spent two hours trying all solutions mentioned above.

This is what finally worked for me:

var vid = document.getElementById("myVideo");
vid.muted = true;

I solved the same problem with,

$(window).on('pageshow',function(){
    var vids = document.querySelectorAll('video');
    for (var i = 0; i < vids.length;){
        vids[i].play();
    }
})

You have to launch the videos after the page has been shown.


Try this:

    <video height="256" loop autoplay controls id="vid">
     <source type="video/mp4" src="video_file.mp4"></source>
     <source type="video/ogg" src="video_file.ogg"></source>

This is how I normally do it. loop, controls and autoplay do not require a value they are boolean attributes.


var video = document.querySelector('video');
video.muted = true;
video.play()

Only this solution helped me, <video autoplay muted ...>...</video> didn't work...


After using jQuery play() or DOM maniupulation as suggested by the other answers, it was not still working (Video wasn't autoplaying) in the Chrome for Android (Version 56.0).

As per this post in developers.google.com, From Chrome 53, the autoplay option is respected by the browser, if the video is muted.

So using autoplay muted attributes in video tag enables the video to be autoplayed in Chrome browsers from version 53.

Excerpt from the above link:

Muted autoplay for video is supported by Chrome for Android as of version 53. Playback will start automatically for a video element once it comes into view if both autoplay and muted are set[...]

<video autoplay muted>
    <source src="video.webm" type="video/webm" />
    <source src="video.mp4" type="video/mp4" />
</video>
  • Muted autoplay is supported by Safari on iOS 10 and later.
  • Autoplay, whether muted or not, is already supported on Android by Firefox and UC Browser: they do not block any kind of autoplay.

We recently addressed a similar issue with an embedded video and found that the autoplay and muted attributes were not sufficient for our implementation.

We added a third "playsinline" attribute to the code and it fixed the issue for iOS users.

This fix is specific to videos that are to be played inline. From https://webkit.org/blog/6784/new-video-policies-for-ios/ :

On iPhone, elements will now be allowed to play inline, and will not automatically enter fullscreen mode when playback begins. elements without playsinline attributes will continue to require fullscreen mode for playback on iPhone. When exiting fullscreen with a pinch gesture, elements without playsinline will continue to play inline.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to google-chrome

SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 81 SameSite warning Chrome 77 What's the net::ERR_HTTP2_PROTOCOL_ERROR about? session not created: This version of ChromeDriver only supports Chrome version 74 error with ChromeDriver Chrome using Selenium Jupyter Notebook not saving: '_xsrf' argument missing from post How to fix 'Unchecked runtime.lastError: The message port closed before a response was received' chrome issue? Selenium: WebDriverException:Chrome failed to start: crashed as google-chrome is no longer running so ChromeDriver is assuming that Chrome has crashed WebDriverException: unknown error: DevToolsActivePort file doesn't exist while trying to initiate Chrome Browser How to make audio autoplay on chrome How to handle "Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first." on Desktop with Chrome 66?

Examples related to safari

How to Inspect Element using Safari Browser What does the shrink-to-fit viewport meta attribute do? background: fixed no repeat not working on mobile Swift Open Link in Safari How do I make flex box work in safari? onClick not working on mobile (touch) window.open(url, '_blank'); not working on iMac/Safari HTML5 Video tag not working in Safari , iPhone and iPad NodeJS/express: Cache and 304 status code Video auto play is not working in Safari and Chrome desktop browser

Examples related to webkit

com.apple.WebKit.WebContent drops 113 error: Could not find specified service HTML5 Video autoplay on iPhone What does the shrink-to-fit viewport meta attribute do? Chrome / Safari not filling 100% height of flex parent How to style HTML5 range input to have different color before and after slider? What are -moz- and -webkit-? Video auto play is not working in Safari and Chrome desktop browser Rotate and translate Background color not showing in print preview Blurry text after using CSS transform: scale(); in Chrome