如何处理“Uncaught(in promise)DOMException:play()失败,因为用户没有先与文档交互。”在桌面上使用Chrome 66?

问题描述 投票:67回答:13

我收到错误消息..

未捕获(在promise中)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>元素一样简单吗?对此有任何负面影响吗?

javascript google-chrome video html5-video
13个回答
77
投票

要在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更新试图阻止标签在用户标签上创建随机噪音。这就是为什么静音属性使自动播放再次起作用的原因。


0
投票

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

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


0
投票

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

下面我使用原型函数来包装本机DOM播放函数,获取其承诺,然后在浏览器抛出异常时降级为播放按钮。该扩展解决了浏览器的缺点,并且在具有目标元素知识的任何页面中即插即用。

// 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>

0
投票

您应该在muted中添加videoElement属性,以便按预期进行代码工作。看下去..

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

别忘了添加有效的视频链接作为来源


-4
投票

在地址栏中输入Chrome://flags

搜索:自动播放

自动播放政策

决定是否允许音频或视频自动播放时使用的策略。

- Mac,Windows,Linux,Chrome OS,Android

将其设置为“无需用户手势”

重新启动Chrome,您无需更改任何代码


27
投票
  1. 打开chrome://flags/#autoplay-policy
  2. 设置无用户手势是必需的
  3. 重新启动Chrome

10
投票

我发现的最佳解决方案是静音视频

HTML

<video loop muted autoplay id="videomain">
  <source src="videoname.mp4" type="video/mp4">
</video>

9
投票

回答手头的问题...... 不能拥有这些属性,能够自动播放具有音频的媒体,您需要在文档上注册用户手势。

但是,这种限制非常弱:如果您确实在父文档上收到了此用户手势,并且您的视频是从iframe加载的,那么您可以播放它...

因此,例如this fiddle,这是唯一的

<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>

这意味着您的广告可能可以播放,因为您确实为主页提供了用户手势。


现在,请注意Safari和Mobile Chrome有比这更严格的规则,并且要求您在用户事件处理程序本身的play()<video>元素上以编程方式实际触发至少一次<audio>方法。

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>

如果您不需要音频,那么只需将其连接到您的媒体,只允许视频轨道的视频也可以自动播放,并且会降低用户的带宽使用率。


3
投票

尝试使用mousemove事件lisentner

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

document.body.addEventListener("mousemove", function () {
    audio.play()
})

3
投票

对我来说(在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();
}

2
投票

UPDATE

如果这种技术不再起作用 - 还有另一种选择。您可以包含一个简短且非常安静(-60db)的音频,并在隐藏按钮的单击处理程序中播放。之后,将允许播放所有其他音频/视频文件,而无需直接用户交互。您可以从http://adventure.land/sounds/loops/empty_loop_for_js_performance.wav获取无声音频并将其切换为半秒(或更短)。


有一个非常简单的解决方案 - 只需在页面中添加一个按钮,将其设置为不可见,然后在button.click()之前调用play()方法

像Chromium版本70.0.3538.67(官方版本)(64位)中的魅力

var btn = document.getElementById('btn');
document.addEventListener(btn,myPlay,false);
btn.click();

function myPlay()
{
  document.getElementById('movie').play();
}
<video
    title="Advertisement" id="movie"
    style="background-color: rgb(0, 0, 0); position: absolute; width: 640px; height: 360px;"
    src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm"
    ></video>
    <button type="button" style="z-index:-1;opacity:0;position: absolute;left:-1000px;" id="btn"></button>

0
投票

我在Android手机上玩了一些问题。经过几次尝试后,我发现当Data Saver打开时,没有自动播放:

如果启用了Data Saver模式,则没有自动播放。如果启用了数据保护模式,则在媒体设置中禁用自动播放。

Source


0
投票

Chrome需要用户互动才能通过js(video.play())自动播放或播放视频。但是,任何时刻的互动都可以是任何形式的。如果您只是在页面上单击随机,视频将自动播放。我解决了,然后添加一个按钮(仅限Chrome浏览器),显示“启用视频自动播放”。该按钮不执行任何操作,只需单击它即可进行任何其他视频所需的用户交互。

© www.soinside.com 2019 - 2024. All rights reserved.