如何处理“Uncaught (in promise) DOMException: play() failed because the user did 't interaction with the document first.”在台式机与Chrome 66?

我正在得到错误信息..

DOMException: play()失败,因为用户没有首先与文档交互。

..当使用Chrome 66版本在桌面上播放视频时。

我确实发现一个广告开始自动播放在一个网站上,但使用以下HTML:

<video
title="Advertisement"
webkit-playsinline="true"
playsinline="true"
style="background-color: rgb(0, 0, 0); position: absolute; width: 640px; height: 360px;"
src="http://ds.serving-sys.com/BurstingRes/Site-2500/Type-16/1ff26f6a-aa27-4b30-a264-df2173c79623.mp4"
autoplay=""></video>

那么,绕过Chrome v66的自动播放拦截器真的像添加webkit-playsinline="true"playsinline="true"autoplay=""属性到<video>元素一样简单吗?这有什么负面影响吗?

427895 次浏览

回答眼前的问题 不,只有这些属性是不够的,为了能够自动播放带有音频的媒体,你需要在你的文档上注册一个用户手势

但是,这个限制是非常弱的:如果你确实在父文档上接收到这个user-gesture,并且你的视频是从iframe加载的,那么你可以播放它…

所以以这小提琴为例,它只是

<video src="myvidwithsound.webm" autoplay=""></video>
在第一次加载时,如果你没有点击任何地方,它将不会运行,因为我们还没有注册任何事件 但是一旦你点击“运行”按钮,那么父文档(jsfiddle.net)确实收到了一个用户手势,现在视频开始播放,即使它在技术上是加载在另一个文档中

但是下面的代码片段将自动播放,因为它需要你实际单击运行代码段按钮。

<video src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm" autoplay=""></video>

This means that your ad was probably able to play because you did provide an user-gesture to the main page.


Now, note that Safari and Mobile Chrome have stricter rules than that, and will require you to actually trigger at least once the play() method programmatically on the <video> or <audio> element from the user-event handler itself.

btn.onclick = e => {
// mark our MediaElement as user-approved
vid.play().then(()=>vid.pause());
// now we can do whatever we want at any time with this MediaElement
setTimeout(()=> vid.play(), 3000);
};
<button id="btn">play in 3s</button>
<video
src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm" id="vid"></video>

如果你不需要音频,那就不要把它附加到你的媒体上,只有视频轨道的视频也可以自动播放,这将减少用户的带宽使用。

在地址栏中输入Chrome: / /旗帜

搜索:播放

播放政策

决定是否允许音频或视频时使用的策略 播放。< / p >

- Mac, Windows, Linux, Chrome OS, Android

将此设置为“;不需要用户手势"

重新启动Chrome浏览器,你不需要改变任何代码

  1. 打开chrome://settings/content/sound
  2. 设置不需要用户手势
  3. 重新启动浏览器

要在chrome 66更新后使html 5元素上的自动播放工作,您只需要将muted属性添加到视频元素。

现在的视频HTML

<video
title="Advertisement"
webkit-playsinline="true"
playsinline="true"
style="background-color: rgb(0, 0, 0); position: absolute; width: 640px; height: 360px;"
src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
autoplay=""></video>

只需要muted="muted"

<video
title="Advertisement"
style="background-color: rgb(0, 0, 0); position: absolute; width: 640px; height: 360px;"
src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
autoplay="true"
muted="muted"></video>

我相信chrome 66的更新是为了阻止标签在用户标签上产生随机噪音。这就是为什么静音属性使自动播放再次工作。

我发现最好的解决办法就是把视频静音

超文本标记语言

<video loop muted autoplay id="videomain">
<source src="videoname.mp4" type="video/mp4">
</video>
我在Android手机上玩游戏时遇到了一些问题。 经过几次尝试,我发现当数据保护程序是没有自动播放:

如果启用了数据保护模式,则不会自动播放。如果启用了数据保护模式,则在“媒体设置”中禁用自动播放。

Source .

尝试使用鼠标移动事件监听器

var audio = document.createElement("AUDIO")
document.body.appendChild(audio);
audio.src = "./audio/rain.m4a"


document.body.addEventListener("mousemove", function () {
audio.play()
})
Chrome需要一个用户交互的视频被自动播放或通过js (video.play())播放。 但这种互动可以是任何形式的,在任何时刻。 如果你只是在页面上随机点击,视频将自动播放。 然后我解决了这个问题,添加了一个按钮(只在chrome浏览器上),说“启用视频自动播放”。该按钮什么都不做,只是点击它,是任何进一步视频所需的用户交互

对我来说(在Angular项目中),这段代码有帮助:

在HTML中,你应该添加autoplay muted

在JS / TS

playVideo() {
const media = this.videoplayer.nativeElement;
media.muted = true; // without this line it's not working although I have "muted" in HTML
media.play();
}

我在尝试播放音频文件时遇到了类似的错误。起初,它是工作的,然后它停止工作时,我开始使用ChangeDetector的markForCheck方法在同一函数中触发重新渲染时,承诺解决(我有一个视图渲染的问题)。

当我把markForCheck改为detectChanges时,它又开始工作了。我真的无法解释发生了什么,我只是想把这个放在这里,也许它会帮助到某人。

扩展DOM元素,处理错误,优雅地降级

下面我使用原型函数来包装原生DOM播放函数,获取它的承诺,然后在浏览器抛出异常时将其降级为播放按钮。这个扩展解决了浏览器的缺点,是即插即用的任何页面与目标元素的知识(s)。

// JavaScript
// Wrap the native DOM audio element play function and handle any autoplay errors
Audio.prototype.play = (function(play) {
return function () {
var audio = this,
args = arguments,
promise = play.apply(audio, args);
if (promise !== undefined) {
promise.catch(_ => {
// Autoplay was prevented. This is optional, but add a button to start playing.
var el = document.createElement("button");
el.innerHTML = "Play";
el.addEventListener("click", function(){play.apply(audio, args);});
this.parentNode.insertBefore(el, this.nextSibling)
});
}
};
})(Audio.prototype.play);


// Try automatically playing our audio via script. This would normally trigger and error.
document.getElementById('MyAudioElement').play()


<!-- HTML -->
<audio id="MyAudioElement" autoplay>
<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>

你应该在你的videoElement中添加muted属性,让你的代码正常工作。看下面..

<video id="IPcamerastream" muted="muted" autoplay src="videoplayback%20(1).mp4" width="960" height="540"></video>

不要忘记添加一个有效的视频链接作为源

就我而言,我必须这么做

 // Initialization in the dom
// Consider the muted attribute
<audio id="notification" src="path/to/sound.mp3" muted></audio>




// in the js code unmute the audio once the event happened
document.getElementById('notification').muted = false;
document.getElementById('notification').play();

根据新的浏览器策略,在播放Audio元素之前,用户必须首先与DOM交互。

如果你想在页面加载中播放媒体,那么你可以简单地添加自动播放属性到HTML中的音频元素,就像这样

<video id="video" src="./music.mp4" autoplay>

或者如果你不想做自动播放,那么你可以使用Javascript处理这个。由于autoplay属性设置为true,媒体将被播放,我们可以简单地静音媒体。

document.getElementById('video').autoplay = true;
document.getElementById('video').muted = true;

小鬼:现在不管你什么时候播放媒体,别忘了把静音属性设为false。像这样

document.getElementById('video').muted = false;
document.getElementById('video').play();

或者,您还可以显示一个简单的弹出窗口,用户将单击模式中的允许按钮。因此,他首先与DOM交互,然后您不需要做任何事情

我得到了这个错误

DOMException: play()失败,因为用户没有首先与文档交互。

下面是我在Angular项目中所做的

关键点:永远不要假设视频会播放,当视频没有真正播放时,不要显示暂停按钮。

你应该总是查看play函数返回的Promise,看看它是否被拒绝了:

ngOnInit(): void{
this.ensureVideoPlays();
}


private ensureVideoPlays(): void{
const video = document.querySelector("video");


if(!video) return;
    

const promise = video.play();
if(promise !== undefined){
promise.then(() => {
// Autoplay started
}).catch(error => {
// Autoplay was prevented.
video.muted = true;
video.play();
});
}
}

来源:播放政策

我有一个类似的问题,我需要播放视频没有静音。我这样做的方式,等待一秒钟,然后通过按钮触发事件。这是我的代码

if (playVideo == '1') {
setTimeout(function() {
$("#watch_video_btn").trigger('click');
}, 1000);
}

音频自动播放属性无法在MS Edge中工作

我改变了我的UI,让用户按下一个按钮来加载网站(当他们点击按钮后,网站加载时,音频播放)

因为他们与DOM交互,然后音频播放!!

在我的情况下,它只是一个点击声音,在开始时自动调用(我不介意它是否静音)。所以我用:

const clickSound = new Audio('click.wav');
clickSound.play().catch(function (error) {
console.log("Chrome cannot play sound without user interaction first")});

来消除错误。