Determine if Chrome has blocked HTML5 video autoplay? - javascript

As of Chrome 46, new background tabs will no longer autoplay audio or video. How can an application tell if its autoplay has been blocked?
Some ideas:
UA sniff for Chrome 46+
check if tab is visible with Visibility API
check if new tab with History API
check if video is actually playing
Something hacky like this will probably work, but I would really like to know if there's a better way:
function isAutoplayBlocked() {
return isChrome46 && isNewTab && isHiddenTab;
}

Firstly on mobile, autoplay is completely blocked.
The best way to see if your video is blocked is to look for the media events that indicate that the element has started playing such as ontimeupdate and your element has autoplay attribute attached. If there are no updates and no user interactions then you can assume that autoplay has been suspended.

Related

How do I force audio to autoplay on chrome and firefox?

I'm trying to add autoplaying music to a tumblr theme, but Chrome and Firefox both prevent autoplaying audio by default. How do I circumvent this?
Currently, to hear the autoplaying music, a user would have to change their personal browser settings to allow autoplay. Is there a workaround I can use to make the page play audio even if they have sound set to automatic (in Chrome) or autoplay blocked (in Firefox)?
Tumblr themes allow HTML, CSS, and Javascript, so I'd be happy for a solution using any of those. Ideally I would like my autoplay solution to allow multiple songs in a playlist, if possible.
I tried adding an invisible iframe, but that didn't work; I'm not sure whether it was the third-party audio player I'm using, or just that the iframe technique doesn't work at all anymore.
You can't circumvent auto-play from being blocked. There has to be some user interaction before the audio can play. This is the same for both HTML <audio> element as well as the web-audio API's audioContext
There's some reading about this on MDN Autoplay guide for media and Web Audio's API
You can try to play the audio on javascript onload.
Example:
HTML:
<audio controls id="horseAudio">
<source src="https://www.w3schools.com/html/horse.ogg" type="audio/ogg">
<source src="https://www.w3schools.com/html/horse.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
JavaScript:
window.onload = function (){
document.getElementById("horseAudio").play();
}
I do not think there is a way around autoplay being deactivated until there is user interaction. I was working on a project with similar problem and I decided to put a "begin" button on it to direct the user to click it. By clicking it (click event listener), they would have satisfied an interaction and it would then play my animations and audio.

Allow Audio to Play on Page Load

I'm maintaining a legacy ASP/VBScript application for some warehouse scanners. They run Android 7 with Chrome 64. I can configure Chrome however I want so I'm not constrained like a normal website would be. Due to the nature of this web application, playing a sound on page load would improve usability (when the submitted action fails). Is there any way to allow an audio file to play on page load?
I can play sounds easily after a user interaction. However, I've tried multiple methods to play a sound on page load without success:
An <audio> tag with autoplay does not play (<audio autoplay="">).
Play the sound during the load event (Audio.play()). The returned Promise fails with the error:
NotAllowedError: play() can only be initiated by a user gesture.
Create an Audio with autoplay, and append it to body during the load event.
Create an Audio, append it to body, and .play() it during the load event. Yields the same "NotAllowedError".
Whitelisting the website for sounds in Chrome.
Ensuring the media autoplay setting is set to allowed in Chrome.
Both Chrome and Firefox, have dropped support for the autoplay attribute for both audio and video unless it's a video with the sound muted.
You can read more on that here: Autoplay Policy
However, recently I found a workaround using the Howler.js library, and it seems to work quite well in just these lines of code:
let timer, sound;
sound = new Howl({
src: ['<?= get_theme_file_uri() ?>/images/spotAudio.mp3']
});
sound.play();
You can download the library and read the docs here: https://howlerjs.com/

Bypassing chrome autopause on videos with sound?

I have a website set-up, where the background is a YouTube video using Tubular.js plugin. There is a problem with chrome browsers, that auto pauses the youtube video if I load it with mute: false flag. Chrome is the only offender, as it works with opera, firefox etc. If I change the flag to mute: true the video will atuplay fine.
Chrome recently started to block atuplayed videos with sound. Is there an option to bypass this on chrome, or at least modify the tubular.js library/js call so that it will only mute (regardless of settings) on chrome user-agents?
https://codepen.io/anon/pen/MGEZrO
Thanks in advance
According to chrome logic it is impossible to autoplay video if it is NOT muted. However they allow to autoplay video if it is muted and WILL NOT stop it if user will unmute it. By this (user interaction) chrome means just a single tap OR click by the user on the website (everywhere, not video components only).
Just make your user to make a single click on your webpage and THEN you can mount/start video with autoplay and sound.
I have the similar situation with my react spa. And I force my user to make a single click before mounting the video. Only this way it starts to play with sound.
I also had the situation where the video MUST have started even without click and the I just addEventListener on whole page to unmute it as soon as possible
play(from = null) {
document.addEventListener('click', () => {
// any click will force my video to unmute
this.player.muted = false;
});
// rest code for updating state etc
}
Unfortunately, triggering click is not working (the video will stop automatically)
According to their guidelines about autoplay on chrome ;
Unfortunately, Chrome cannot provide any whitelist exceptions to the autoplay policy.
They also explain how to present the content in a less-invasive way (muted video first) and some other tips about the policy.

Are there known issues (in Feb 2018) with HTML5 Audio / Video in Chrome Mobile? [duplicate]

With the release of OSX High-Sierra*, one of the new features in Safari is that videos on websites will not auto play anymore and scripts can't start it either, just like on iOS. As a user, I like the feature, but as a developer it puts a problem before me: I have an in-browser HTML5 game that contains video. The videos do not get automatically played anymore unless the user changes their settings. This messes up the game flow.
My question is, can I somehow use the players' interaction with the game as a trigger for the video to start playing automatically, even if said activity is not directly linked to the video element?
I cannot use jQuery or other frameworks, because of a restraint that my employer has put on our development. The one exception is pixi.js which - among all other animations - we are also using to play our videos inside a pixi container.
*The same restriction also applies on Mobile Chrome.
Yes, you can bind on event that are not directly ones triggered on the video element:
btn.onclick = e => vid.play();
<button id="btn">play</button><br>
<video id="vid" src="https://dl.dropboxusercontent.com/s/bch2j17v6ny4ako/movie720p.mp4"></video>
So you can replace this button with any other splash screen requesting an user click, and you'll be granted access to play the video.
But to keep this ability, you must call at least once the video's play method inside the event handler itself.
Not working:
btn.onclick = e => {
// won't work, we're not in the event handler anymore
setTimeout(()=> vid.play().catch(console.error), 5000);
}
<button id="btn">play</button><br>
<video id="vid" src="https://dl.dropboxusercontent.com/s/bch2j17v6ny4ako/movie720p.mp4"></video>
Proper fix:
btn.onclick = e => {
vid.play().then(()=>vid.pause()); // grants full access to the video
setTimeout(()=> vid.play().catch(console.error), 5000);
}
<button id="btn">play</button><br>
<video id="vid" src="https://dl.dropboxusercontent.com/s/bch2j17v6ny4ako/movie720p.mp4"></video>
Ps: here is the list of trusted events as defined by the specs, I'm not sure if Safari limits itself to these, nor if it includes all of these.
Important note regarding Chrome and preparing multiple MediaElements
Chrome has a long-standing bug caused by the maximum simultaneous requests per host which does affect MediaElement playing in the page, limiting their number to 6.
This means that you can not use the method above to prepare more than 6 different MediaElements in your page.
At least two workarounds exist though:
It seems that once a MediaElement has been marked as user-approved, it will keep this state, even though you change its src. So you could prepare a maximum of MediaElements and then change their src when needed.
The Web Audio API, while also concerned by this user-gesture requirement can play any number of audio sources once allowed. So, thanks to the decodeAudioData() method, one could load all their audio resources as AudioBuffers, and even audio resources from videos medias, which images stream could just be displayed in a muted <video> element in parallel of the AudioBuffer.
In my case i was combining transparent video (with audio) with GSAP animation. The solution from Kaiido works perfectly!
First, on user interaction, start and pause the video:
videoPlayer.play().then(() => videoPlayer.pause());
After that you can play it whenever you want. Like this:
const tl = gsap.timeline();
tl.from('.element', {scale: 0, duration: 5);
tl.add(() => videoPlayer.play());
Video will play after the scale animation :).
Tested in Chrome, Safari on iPhone

Chrome extension - listening to YouTube events

var ytplayer = document.getElementById("movie_player");
ytplayer.addEventListener('onStateChange', 'onPlayerChange');
function onPlayerChange(newState) {
alert('do something at least...');
if(newState == 0) {
alert('movie has stopped');
}
}
This is how I try to listen to YouTube events with a Google Chrome extension. It doesn't give me any error at all, even though it should when the movie has finished. Or at least when the state has changed. Does anyone know what is wrong?
Console doesn't give me any errors.
Your code works fine on Firefox because the player is Flash. However Chrome supports HTML5 and the player is HTML5 Video Player. So there is no element which has "movie_player" id. Are you sure your video player is Flash on Chrome. Right click the video and see player info in context menu. More details about YouTube HTML5 Player.
Youtube HTML5 player is currently in trial, so you should detect user's player mode and add a fallback for it at least YT completely use HTML5.
The HTML5 video element fires its own events. Right now, it looks like the easiest way to get at it is by class name (since it doesn’t have an id):
var videoElement = document.getElementsByClassName('video-stream')[0];
Video elements fire a bunch of events, which you can find listed here in the HTML5 spec.
For example:
videoElement.addEventListener('pause', function(){ alert('paused!'); })

Categories