I have a video (meant for background purposes), that is muted and I intend to auto-play. If I were to put the following code into an html file:
<video playsinline autoplay muted loop>
<source src=".mp4">
</video>
It would work just fine on Chrome.
However, If I were to insert the exact same video using DOM manipulation, I would have trouble on Chrome but success in other browsers like Firefox.
<html>
<body>
</body>
<script>
function render() {
const video = document.createElement('video');
video.setAttribute('muted', true);
video.setAttribute('autoplay', true);
video.setAttribute('loop', true);
video.setAttribute('playsinline', true);
const source = document.createElement('source');
source.setAttribute('src', '.mp4');
video.appendChild(source);
document.body.appendChild(video);
}
render();
</script>
</html>
Chrome appears notorious for blocking autoplay. The general solutions are either to be muted (which I already do), or to use dom manipulation to call play (which doesn't work). Is there a way to get this to work after inserting the video into the dom. The reason I care is because my actual website requires everything to be rendered (My site is in ember.js).
This is in Chrome version 71.
Thanks!
I have a video (meant for background purposes), that is muted and I intend to auto-play. If I were to put the following code into an html file:
<video playsinline autoplay muted loop>
<source src="https://res.cloudinary./dthskrjhy/video/upload/v1545324364/ASR/Typenex_Dandelion_Break_-_Fade_To_Black.mp4">
</video>
It would work just fine on Chrome.
However, If I were to insert the exact same video using DOM manipulation, I would have trouble on Chrome but success in other browsers like Firefox.
<html>
<body>
</body>
<script>
function render() {
const video = document.createElement('video');
video.setAttribute('muted', true);
video.setAttribute('autoplay', true);
video.setAttribute('loop', true);
video.setAttribute('playsinline', true);
const source = document.createElement('source');
source.setAttribute('src', 'https://res.cloudinary./dthskrjhy/video/upload/v1545324364/ASR/Typenex_Dandelion_Break_-_Fade_To_Black.mp4');
video.appendChild(source);
document.body.appendChild(video);
}
render();
</script>
</html>
Chrome appears notorious for blocking autoplay. The general solutions are either to be muted (which I already do), or to use dom manipulation to call play (which doesn't work). Is there a way to get this to work after inserting the video into the dom. The reason I care is because my actual website requires everything to be rendered (My site is in ember.js).
This is in Chrome version 71.
Thanks!
Share Improve this question edited Jan 18, 2019 at 2:15 Cameron asked Jan 18, 2019 at 2:01 CameronCameron 2,9953 gold badges35 silver badges48 bronze badges 6- Works for me in Chrome Version 71.0.3578.98 (Official Build) (64-bit) – Kosh Commented Jan 18, 2019 at 2:11
- that's really strange. I have the exact same version and the exact same code but have this problem – Cameron Commented Jan 18, 2019 at 2:14
- @KoshVery - right click on the tab and select "Mute Site", then reload the page. Won't play. If the user turns off autoplay there is nothing you can do to enable it. – Randy Casburn Commented Jan 18, 2019 at 2:15
- While this is true, I find that even with Mute Site disabled I cannot get it to autoplay. There must be something else going on... – Cameron Commented Jan 18, 2019 at 2:17
- For the ones able to autoplay on Chrome (e.g @KoshVery) , you probably had an interaction with the page (e.g if you tried from jsfiddle, just interacting with the parent page counts as interaction). Here is a live example, be sure to not click anywhere when the page loads. Can repro on 71 and 73, both on macOs – Kaiido Commented Jan 18, 2019 at 2:21
2 Answers
Reset to default 9This is probably a bug (and not the only one with this autoplay policy...).
When you set the muted
attribute through Element.setAttribute()
, the policy is not unleashed like it should be.
To workaround that, set the IDL attribute through the Element's property:
function render() {
const video = document.createElement('video');
video.muted = true;
video.autoplay = true;
video.loop = true;
video.setAttribute('playsinline', true);
const source = document.createElement('source');
source.setAttribute('src', 'https://res.cloudinary./dthskrjhy/video/upload/v1545324364/ASR/Typenex_Dandelion_Break_-_Fade_To_Black.mp4');
video.appendChild(source);
document.body.appendChild(video);
}
render();
As a fiddle since StackSnippets requiring a click event form the parent page are anyway always allowed to autoplay ;-).
Async, Await, & IIFE
After finding this article a couple of months ago, I still couldn't get a consistent autoplay behavior, muted or otherwise. So the only thing I hadn't tried is packing the async function
in an IIFE (Immediately Invoked Function Expression).
In the demo:
It is dynamically inserted into the DOM with
.insertAdjacentHTML()
It should
autoplay
It should be unmutedAll of the above should happen without user interaction.
Demo
var clip = document.getElementById('clip');
(function() {
playMedia();
})();
async function playMedia() {
try {
await stamp();
await clip.play();
} catch (err) {
}
}
function stamp() {
document.body.insertAdjacentHTML('beforeend', `<video id='clip' poster='https://image.ibb.co/iD44vf/e2517.jpg' src='https://storage04.dropshots./photos8000/photos/1381926/20181019/182332.mp4' width='100%' autoplay loop playsinline></video>`);
}