Video auto play is not working in Safari and Chrome desktop browser
Asked Answered
P

35

248

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.

Philippopolis answered 1/8, 2013 at 12:53 Comment(4)
is it working sometimes ? or not working at all... here is an example w3schools.com/tags/tryit.asp?filename=tryhtml5_video_autoplay that i check with chrome, and it works.Archduchess
On some pages it is not working at allPhilippopolis
Facing the same issue, worked fine a week ago and without any change it just stopped working. Maybe it's a browser update, very annoying to have to manually play all the video tags via javascriptPepillo
Not working for me in Chrome.Kellerman
P
525

The best fix I could get was adding this code just after the </video>

<script>
    document.getElementById('vid').play();
</script>

...not pretty but somehow works.

UPDATE Recently many browsers can only autoplay the videos with sound off, so you'll need to add muted attribute to the video tag too

<video autoplay muted>
...
</video>
Philippopolis answered 1/8, 2013 at 12:53 Comment(10)
Or you can code with jQuery $("videoID").get(0).play(); #4647498Venerate
Or like this: $("video[autoplay]").each(function(){ this.play(); });Martins
still problem if its not muted developers.google.com/web/updates/2017/09/…Circumstantiate
this won't work anymore without user interaction AFAIKUnderquote
see this #43570960Waylen
works in Chrome 2020 but tbh this hack can be the only reason chrome should stop invalidating autoplaySilverts
To work on Safari mobile, I also had to include playsinlineStromboli
autoplay="true" muted="true" , it works for me, thanksShigella
Muted somehow worksMinim
autoplay works only with mutedIdiophone
B
127

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.
Boogie answered 23/2, 2017 at 11:44 Comment(2)
I had this issue in Safari 11 where a background video (no audio) wouldn't play automatically. Adding muted and autoplay did the trick. Thanks!Ifill
So why then does autoplay, WITH sound on, work for youtube? It has worked that way since the site's inception.Catling
J
68

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>
Jameson answered 18/5, 2018 at 0:40 Comment(1)
John Pallett's comment on the new policy. He is Google Chrome's Product Manager and Media Muter.Frivol
G
33

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.

Genu answered 13/11, 2014 at 11:14 Comment(3)
Good call that it doesn't work with .wrap(). However, as far as I can tell, the code needs .get(0) to work: $("#vid").get(0).play();Homeo
@Homeo .get(0) or just $('#vid')[0].play()Taka
Oct 2017, video not autoplaying in spite of attribute in tag is still an issue in Safari. Using [0].play() as suggested by mattsoave/pmrotule solved the issue.Psychotherapy
L
31

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>`
Linskey answered 27/10, 2017 at 21:25 Comment(2)
Works for latest Chrome on Windows8Latta
On Crome if i add muted disable sound. I don't want thisStraitlaced
D
31

It worked for me when combined with muted attribute

Deficit answered 9/9, 2021 at 14:4 Comment(3)
I don't understand the logic behind it but it works for me!Fulminate
correct answer for this questionConfidential
THIS! Thank you! Makes sense too! I just wish there was better documentation/logging to indicate that.Janeanjaneczka
S
25

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>
Schargel answered 25/9, 2019 at 7:54 Comment(1)
That doesn't add anything new. The accepted answer already mentions this. Also the second answer goes into detail.Protostele
I
18
var video = document.querySelector('video');
video.muted = true;
video.play()

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

Inhabited answered 20/9, 2018 at 8:53 Comment(0)
B
15

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

Biped answered 10/7, 2014 at 9:11 Comment(1)
The preload attribute is ignored by browser if autoplay is present.Penhall
M
14

I had a problem when playing a video on Safari on iPhones. Adding the playsinline attribute in the video tag can solve this problem, and it works!

<video autoplay muted loop playsinline class="someClass">
  <source src="source.mp4" type="video/mp4">
</video>

You will also get this problem on Safari on OSX, in case you get yourself confused about this property playsinline, here is the explaination.

Mobile browsers, playsinline will play the video right where it is instead of the default, which is to open it up fullscreen while it plays.

For the Safari on OSX, as the default websites Auto-Play option is Stop Media with Sound, this strategy can also introduce the permission issue.

That's why we need the property muted.

Safari Preferences

Maleki answered 17/5, 2021 at 13:49 Comment(2)
This worked for me in 2021Net
Still going strong in 2022.Astolat
F
11

Try this:

  <video width="320" height="240"  autoplay muted>
            <source src="video.mp4" type="video/mp4">
  </video>
Fulvi answered 2/5, 2019 at 10:26 Comment(0)
C
11

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/

Crosspurpose answered 9/6, 2020 at 9:16 Comment(0)
B
11

For angular, you'll have to mute it and play it in the ngAfterViewInit() like the following

<video height="256" loop autoplay muted controls id="vid" #videoRef>
         <source type="video/mp4" src="video_file.mp4"></source>
         <source type="video/ogg" src="video_file.ogg"></source>
</video>
 ​@ViewChild('videoRef', { static: true }) videoRef!: ElementRef

​ngAfterViewInit(): void {
  ​const media = this.videoRef.nativeElement
  ​media.muted = true 
  ​media.play() 
​ } 
Berndt answered 30/11, 2021 at 9:24 Comment(0)
P
9

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);
Postman answered 24/11, 2016 at 5:47 Comment(2)
reason is because you are waiting for the video to be loaded within the buffer then you play it.Impressionism
To be a bit more specific here: the code above waits for 1 second (1000ms) and then plays the video. It doesn't wait for the video to be loaded as it doesn't know when the video is done. To get the correct moment when video is loaded, one should use document.getElementById('vid').addEventListener('loadeddata', function (){//do whatever you want}); more details on the event here.Drool
S
7
  • Please use muted keyword before autoplay word, Here some privacy change at April, 2018.
  • You may read policy here
Schriever answered 23/4, 2021 at 13:13 Comment(0)
P
6

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.

Pustulant answered 28/11, 2018 at 22:45 Comment(0)
R
6

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

Romance answered 5/12, 2019 at 5:49 Comment(1)
the video is muted, check the questionYamada
M
6

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

Multiversity answered 11/6, 2020 at 0:59 Comment(1)
Wow, this worked for me! Did not expect thatHear
S
5

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.

Samford answered 1/8, 2013 at 13:58 Comment(0)
O
5

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>
Onlybegotten answered 27/11, 2020 at 1:0 Comment(0)
A
4

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);
Alkaline answered 24/11, 2014 at 15:14 Comment(1)
Nothing worked on Chrome worked for me either. With the .play() fix (hack) above I was getting a "Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause()." in the console. There was a few other jQuery functions on the page, so thought that a timer would give Chrome enough time to sort itself out. It worked. I set a 0.5 second timer in $( document ).ready()Diastasis
T
4

Spent two hours trying all solutions mentioned above.

This is what finally worked for me:

var vid = document.getElementById("myVideo");
vid.muted = true;
Tradelast answered 10/5, 2019 at 0:12 Comment(0)
T
4

Angular 10:

<video [muted]="true" [autoplay]="true" [loop]="true">
    <source src="/assets/video.mp4" type="video/mp4"/>
</video>
Tulley answered 9/1, 2021 at 19:50 Comment(1)
In my case, this still didn't work (Angular 11.2) in Chrome. In the code I checked the video elements muted value and it was still set to false. Manually changing it to true fixed the issue. Example: const videoElm = this.backgroundVideo.nativeElement as HTMLVideoElement; videoElm.muted = true;Libertinage
D
4

Nothing worked on Safari iOS until I added playsinline attribute to the video.

If you're using react based application it would be playsInline.

Dungdungan answered 4/9, 2022 at 1:23 Comment(0)
A
3

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();  
Anagram answered 24/5, 2018 at 5:44 Comment(0)
P
2
<video onload='this.play()' src='the source' autoplay controls></video>

This worked for me.

Pathe answered 10/10, 2021 at 12:23 Comment(1)
This answers points the core problem with autoplay of videos. The rule of thumb is that nothing on page can do sounds automatically, without prior user interaction. Muting makes autoplay on page load possible.Retha
B
2

iOS Safari, Safari requires us to add the playsinline attribute.

<video autoplay muted playsinline>
    <source src="video.mp4" type="video/mp4" />
</video>
Bannerman answered 10/7, 2023 at 7:54 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Crease
W
1

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.

Witha answered 22/8, 2014 at 9:44 Comment(0)
T
1

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();
}
Templas answered 28/10, 2017 at 5:14 Comment(0)
L
1

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.

Leniency answered 10/1, 2018 at 9:42 Comment(0)
R
0

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">
Rolf answered 19/12, 2020 at 19:39 Comment(0)
E
0

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.
Errhine answered 19/2, 2021 at 7:11 Comment(0)
U
0

Angular 15:

  • This script wasn't appending the element to the DOM on ios Safari until I added the additional appendChild method in the catch statement.

Component:

  @ViewChild('videoPlayer') videoPlayer!: ElementRef;

  video_playback_error: boolean = false;

...


  ngAfterViewInit(): void {
    this.ngZone.runOutsideAngular(() => {
   this.playVideo();
    });
  }

playVideo() {
    let that = this;
    let v = document.createElement('video');
    v.id = 'videoElement'
    v.src = this.mp4_video_url; // we need this
    v.muted = true;
    v.autoplay = true;
    v.loop = true;
    v.preload = 'none';
    v.playsInline = true;
    v.crossOrigin="anonymous";
    v.classList.add("w-full", "desktop-sm:h-[700px]", "h-[calc(95vh-150px)]", "absolute", "top-0", "left-0", "object-cover");
    const promise = v.play();

    if (promise !== undefined) {
      promise.then(function() {
        console.log('autoplay started');
        that.videoPlayer.nativeElement.appendChild(v);
        v.muted = true;
        v.autoplay = true;
        v.src = that.mp4_video_url;

      // Automatic playback started!
      }).catch(function(error) {
        console.log('autoplay error - attempting to play again in .mp4 | ', error);
        v.muted = true;
        v.autoplay = true;
        v.src = that.mp4_video_url;
        
        let fallback = v.play();
        if (fallback !== undefined) {
          fallback.then((_: any) => {
            
            console.log('autoplay started');
            that.videoPlayer.nativeElement.appendChild(v);
            v.muted = true;
            v.autoplay = true;
            v.src = that.mp4_video_url;
            // Autoplay started!
          }).catch((error: any) => {

            console.log('autoplay failed - falling back to image | ', error)
            that.video_playback_error = true;
          })
        } else {
          that.video_playback_error = true;
        }
      });
    } else {
      this.video_playback_error = true;
    }
  }

Template:

 <div #videoPlayer class="block"></div>
Unattached answered 27/7, 2023 at 20:13 Comment(0)
A
0

Well I am writing this answer for people who are still stuck in 2024.

Cases: 1. Everything works fine on chrome but not on safari?

-> Possible solution : Change your battery saver setting to never. It only works in this setting! (Wth safari :/)

enter image description here

2. For chrome even if you have autplay, playsinline and muted

-> Chances are your chrome is still not setting muted to true, you need to do oncanplay -> videoRef.muted=true. whichever frontend frame you are using!

Acrodont answered 19/2 at 8:35 Comment(0)
P
0

One line:

    <video autoplay muted loop onloadeddata="event.target.play()">
Pily answered 1/4 at 18:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.