admin管理员组文章数量:1289412
I encounter an error trying to autoplay video in Chrome, which says: DOMException: play() failed because the user didn't interact with the document first.
There is a solution for that for 'normal' pages:
var promise = document.querySelector('video').play();
if (promise !== undefined) {
promise.then(_ => {
// Autoplay started!
}).catch(error => {
// Autoplay was prevented.
// Show a "Play" button so that user can start playback.
});
}
But I play video using Phaser framework Video
object, which doesn't return promise, so I need to determine it user has interacted with the page before
trying to play video. Is there any solution for that?
I encounter an error trying to autoplay video in Chrome, which says: DOMException: play() failed because the user didn't interact with the document first.
There is a solution for that for 'normal' pages:
var promise = document.querySelector('video').play();
if (promise !== undefined) {
promise.then(_ => {
// Autoplay started!
}).catch(error => {
// Autoplay was prevented.
// Show a "Play" button so that user can start playback.
});
}
But I play video using Phaser framework Video
object, which doesn't return promise, so I need to determine it user has interacted with the page before
trying to play video. Is there any solution for that?
- Have you tried setting play on page load? – andrea-f Commented Nov 13, 2018 at 12:04
- @andrea-f Page could be loaded in some other tab, so that user don't interact with it even as it loads – Dmitry Samoylov Commented Nov 13, 2018 at 12:05
- Maybe it's ok to handle tab changes, and dispatch event at this moment? – Ishikawa Yoshi Commented Nov 13, 2018 at 12:32
- @DmitrySamoylov I think it will need at least focus. Unless you can simulate a user action on the page that would trigger autoplay, like for example sending a click event. – andrea-f Commented Nov 13, 2018 at 14:47
- It's surely because your video has sound, due to new policy, Chrome blocks videos that autoplay with sound : developers.google./web/updates/2017/09/… – luiswill Commented Feb 28, 2019 at 10:26
4 Answers
Reset to default 3I'm not satisfied with the responses to this kind of question so here's my take / solution. Keep in mind this uses React but can also be done natively.
(1) Add event listeners
const [userInteracted, setUserInteracted] = useState(false)
useEffect(() => {
const handleInteraction = (event) => { setUserInteracted(true); console.log(`Event log for: ${event}`); }
document.addEventListener('click', handleInteraction, true)
document.addEventListener('scroll', handleInteraction, true)
return () => {
document.removeEventListener('click', handleInteraction('click'))
document.removeEventListener('scroll', handleInteraction('scroll'))
}
}, [])
(2) Use native browser detection object
if (navigator.userActivation.hasBeenActive) { doSomething() }
I personally use this on a div which plays audio when hovered over:
const App = () => {
const [userInteracted, setUserInteracted] = useState(false)
const audioRef = useRef(new Audio(BirdSinging))
const playAudio = () => { if (audioRef.current && userInteracted && navigator.userActivation.hasBeenActive) audioRef.current.play() }
const stopAudio = () => {
if (audioRef.current && userInteracted) {
audioRef.current.pause()
audioRef.current.currentTime = 0
}
}
// avoids play() failed because the user didn't interact with the document first
useEffect(() => {
const handleInteraction = (thing) => { setUserInteracted(true); console.log(thing); }
document.addEventListener('click', handleInteraction, true)
document.addEventListener('scroll', handleInteraction, true)
return () => {
document.removeEventListener('click', handleInteraction('clik'))
document.removeEventListener('scroll', handleInteraction('scr'))
}
}, [])
useEffect(() => {
return () => {
audioRef.current.pause()
}
}, [])
return (
<div className="logo" onMouseEnter={playAudio} onMouseLeave={stopAudio}>
<img src={Logo} alt="Logo" />
</div>
)
}
Look for user interaction with the window
var interacted = false;
function fun(){
interacted = true;
$(window).unbind("scroll");
$(window).unbind("click");
play();
}
$(window).bind("scroll click", fun);
function play(){
if(interacted){
//play audio or video
}
}
window.onFocus
You can use this method to call an event when the tab is focused using JavaScript.
window.onFocus = function(){
playVideo(); //A dummy function
}
mousemove
You can check mouse movement.
document.addEventListener('mousemove', playVideo);
keydown
You can check if user has pressed a key
document.addEventListener('keydown', playVideo);
I think, these events must be enough to check if user has interacted with your site and call a method.
// Set a flag if the user has interacted because the video can't play before
useEffect(() => {
interactionListeners()
}, [])
function interactionListeners(){
window.addEventListener("click", setInteractedFunction)
window.addEventListener("scroll", setInteractedFunction)
}
function removeInteractionListeners(){
window.removeEventListener("click", setInteractedFunction)
window.removeEventListener("scroll", setInteractedFunction)
}
function setInteractedFunction(){
console.log("setting interacted")
if(!interacted)
dispatcher(setInteracted(true))
removeInteractionListeners()
}
本文标签: javascriptHow to determine if user interacted with document to start videoStack Overflow
版权声明:本文标题:javascript - How to determine if user interacted with document to start video? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741462406a2380115.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论