如何处理未捕获的(在Promise中)DOM异常:播放请求被暂停调用所中断。

48

以下是我的ASPX页面代码,用于允许在浏览器中播放WAV格式的音频,但使用我的当前代码,我无法在Chrome浏览器中播放WAV音频,但它在Firefox中可以正常工作。如何处理这个异常?

<script>
    window.onload = function () { document.getElementById("audio").play(); }
    window.addEventListener("load", function () { document.getElementById("audio").play(); });
</script>

<body>
    <audio id='audio' controls autoplay>
        <source src="Sounds/DPM317.wav" type="audio/wav" />
        Your browser does not support the audio element.
    </audio>
</body>

2
为什么你在页面加载时尝试运行 play() 两次?移除其中一行会使生活更美好。 - Jaromanda X
8个回答

52

对于Chrome,他们改变了自动播放的策略,所以您可以在这里了解更多:

var promise = document.querySelector('audio').play();

if (promise !== undefined) {
    promise.then(_ => {
        // Autoplay started!
    }).catch(error => {
        // Autoplay was prevented.
        // Show a "Play" button so that user can start playback.
    });
}

19

尝试在catch块中使用类似这样的回调函数。

document.getElementById("audio").play().catch(function() {
    // do something
});

1
如果play()函数不返回一个Promise,那么这段代码将会出错(目前我相信只有Chrome浏览器中的play()函数返回了Promise)。 - Jaromanda X
我又遇到了这个Uncaught TypeError: Cannot read property 'play' of null。 - user7076604
1
你确定在调用播放时,你的DOM已经加载完成了吗? - zapping
文档加载完成后,添加事件监听器函数(function (event) {}),其中包含以下代码: var audio = document.getElementsByTagName("audio")[0]; audio.pause(); </script>我按照这种方式做了,没有出现错误,但音频没有播放。 - user7076604
window.onload = function () { document.getElementById("audio").play().catch(function() { console.log('发生异常'); }); - zapping

19

我不知道这对你是否仍然有用,但我仍然留下我的评论,希望能帮助其他人。
我遇到了同样的问题,并且@dighan在bountysource.com/issues/上提出的解决方案为我解决了这个问题。

所以这里是解决我的问题的代码:

var media = document.getElementById("YourVideo");
const playPromise = media.play();
if (playPromise !== null){
    playPromise.catch(() => { media.play(); })
}

它仍然会在控制台中抛出一个错误,但至少视频正在播放 :)


12
  1. 所有新的浏览器都支持仅静音自动播放视频,因此请将 <video autoplay muted="muted" loop id="myVideo"> 放入页面中。

类似于这样:

<video autoplay muted="muted" loop id="myVideo"> <source src="https://w.r.glob.net/Coastline-3581.mp4" type="video/mp4"> </video>

  1. 如果您的网站正在使用https,则视频URL应该与SSL状态匹配,并且同样适用于HTTP。

7

muted="muted"属性添加到HTML5标签中解决了我的问题。


0

我赞同Shobhit Verma的观点,并有一个小注记:他在帖子中提到,在Chrome(对于我来说是Opera),需要将播放器静音才能成功自动播放...而具有讽刺意味的是,如果在加载后提高音量,它仍然会播放... 这就像所有那些忽略了滑入你的代码的不可见框架的反弹出机制一样... php-echoed html和javascript为: 10秒的setTimeout onLoad of body标签,将音量调整到最大,自动播放和muted='muted'的视频(是的,$muted_code的部分等于"muted='muted")

echo "<body style='margin-bottom:0pt; margin-top:0pt; margin-left:0pt; margin-right:0pt' onLoad=\"setTimeout(function() {var vid = document.getElementById('hourglass_video'); vid.volume = 1.0;},10000);\">";
    echo "<div id='hourglass_container' width='100%' height='100%' align='center' style='text-align:right; vertical-align:bottom'>";
    echo "<video autoplay {$muted_code}title=\"!!! Pausing this video will immediately end your turn!!!\" oncontextmenu=\"dont_stop_hourglass(event);\" onPause=\"{$action}\" id='hourglass_video' frameborder='0' style='width:95%; margin-top:28%'>";

0

我正在使用 Chrome 版本 75。

在视频标签中添加静音属性。

<video id="myvid" muted>

然后使用JavaScript播放它,并将muted设置为false

var myvideo = document.getElementById("myvid");
myvideo.play();
myvideo.muted = false;

编辑:需要用户交互(至少在页面上点击任何位置才能工作)


0
在我的情况下,我必须等待用户交互,因此我设置了一个clicktouchend监听器。
const isMobile = navigator.maxTouchPoints || "ontouchstart" in document.documentElement;

function play(){
    audioEl.play()
}


document.body.addEventListener(isMobile ? "touchend" : "click", play, { once: true });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接