I have just created video object on fly , then add 2 attributes such as source and muted before appending the video object in the document and finally use method play() to play the added video as illustrated below.
let v = document.createElement("video");
v.setAttribute("src","videoplayback.mp4");
v.setAttribute("muted","muted");
document.body.appendChild(v);
v.play().catch((e)=>{ console.log(e)}); // it returns DomException why?
So can someone can tell me What is wrong or solve this for me .
NB :one image of the video is displayed but it is not running..
by default, not just in Chrome but also in Mozilla Firefox and other browsers the video autoplay command is being denied if the Video contains audio and is not muted.
The only way around it is a javascript forced autoplay with audio.
However if you set the video tag to muted="muted" and autoplay the video will still autoplay even if you have set your browser to not to autoplay videos onload.
It's a new feature that has been added to Google Chrome - media (e.g. videos and sounds) cannot be played before the user interacts actively with the page (click). Just add a created variable, put all your code inside a click handler, and create the video if created is false, and set created to true:
let created = false;
$(document).on("click", () => {
if (!created) {
created = true;
let v = document.createElement("video");
v.setAttribute("src","videoplayback.mp4");
v.setAttribute("muted","muted");
document.body.appendChild(v);
v.play().catch((e)=>{ console.log(e)});
}
});
This may seem obvious, however, make sure you don't have an extension installed that is preventing the video from playing. In my case, a site I recently completed has been working fine. I went back to take a look at the site and got this error message: VM476:96 Uncaught (in promise) DOMException: The play method is not allowed by the user agent.
Within a few minutes, I realized I recently installed AutoplayStopper which of course was preventing the video from running auto play.
This is because of your browser default settings. It has set not to play any Audio or video.
Firefox:
https://support.mozilla.org/en-US/kb/block-autoplay
Related
Is there a way programmatically to begin audio play before the user has interacted with the page?
With the following JavaScript:
console.log('Playing abc.');
XYZ.abc = new Audio('audio/abc.wav');
XYZ.abc.play();
I'm getting an error message,
Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.
When I click on the page, that goes away.
Is the standard UI pattern to request the user to click to start sound, or is there a loophole to do this programmatically?
Thanks,
So what the problem is that users don't usually expect audio to come from the website, so chrome requires your audio or video element to be muted by default. For the <audio> tag, you need to add the muted attribute, so -> <audio muted>
Respectively, the js element will have a .muted property. So, what you need is XYZ.abc.muted = true;
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/
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
I am currently using HTML5 audio to play sound on particular button in my angular app, sound is coming in desktop in all browsers, but it has problem with Android/IOS browsers.
So I tried below things:
1). First I tried to play the sound through js but it is not coming as Android/IOS chrome not allow me to use audio.play(), it always give me the error,
Uncaught (in promise) DOMException: play() can only be initiated by a user gesture.
2). Then if it is not allowing me to use audio.play, so to avoid first i created one audio element with autoplay property in html to test that audio tag is working on mobile or not, and found that it is working.
<audio id = "audio1" src="s.mp3" type="audio/mpeg" autoplay></audio>
So what i did that I created one html element of audio with autoplay property with javasript because i want audio to be play on click of button not on load.
var source = "s.mp3";
var element = document.createElement('audio');
element.setAttribute("src",source);
element.setAttribute("autoplay","");
document.body.appendChild(element);
but this is not working in mobiles chrome, looking like strange to me as I am just created the element with the same attributes as I did that in html.
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!'); })