我尝试在 Chrome 中自动播放视频时遇到错误,提示:
DOMException: play() failed because the user didn't interact with the document first.
对于“普通”页面有一个解决方案:
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.
});
}
但是我使用 Phaser 框架
Video
对象播放视频,它不会返回承诺,所以我需要确定用户是否已与尝试播放视频的页面 before
进行交互。有什么解决办法吗?
寻找用户与窗口的交互
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
}
}
我对此类问题的回答不满意,所以这是我的看法/解决方案。请记住,这使用了 React,但也可以在本地完成。
(1)添加事件监听器
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)使用原生浏览器检测对象
if (navigator.userActivation.hasBeenActive) { doSomething() }
我个人在 div 上使用它,当鼠标悬停在 div 上时播放音频:
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>
)
}