javascript 播放 AUDIO 时 Google Chrome Uncaught (in promise) DOMException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/54719283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Google Chrome Uncaught (in promise) DOMException while playing AUDIO
提问by Shrayus Masanam
Google Chrome blocks playing audio/video by default. I've looked up the problem, but I can only find a solution for a video and I want the audio to loop. Here is my code:
默认情况下,Google Chrome 会阻止播放音频/视频。我已经查找了问题,但我只能找到视频的解决方案,并且我希望音频循环播放。这是我的代码:
var audio = new Audio('audio/audio.mp3'); audio.play(); audio.loop = true;
This results in "Uncaught (in promise) DOMException" only on Google Chrome because of new policies.
由于新政策,这只会在 Google Chrome 上导致“未捕获(承诺)DOMException”。
回答by Norman Breau
You're receiving an uncaught exception because you aren't handling an error.
您收到一个未捕获的异常,因为您没有处理错误。
https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play
https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play
Audio is an HTMLMediaElementobject, and the play()method returns a promise. Therefore I recommend handling the error.
音频是一个HTMLMediaElement对象,该play()方法返回一个承诺。因此我建议处理错误。
var promise = audio.play();
if (promise) {
//Older browsers may not return a promise, according to the MDN website
promise.catch(function(error) { console.error(error); });
}
One of two errors are possible:
可能出现以下两种错误之一:
NotSupportedError
不支持错误
This means that the audio source is not supported by the browser (probably due to audio format)
这意味着浏览器不支持音频源(可能是由于音频格式)
NotAllowedError
不允许错误
This is the one I suspect you are triggering. This means the user needs to explicitly trigger the audio.play(), so the method is only usable if it is in response to a user generated event such as a click event.
这是我怀疑你正在触发的。这意味着用户需要显式触发audio.play(),因此该方法仅在响应用户生成的事件(例如单击事件)时可用。
Docs:
文档:
The user agent (browser) or operating system doesn't allow playback of media in the current context or situation. This may happen, for example, if the browser requires the user to explicitly start media playback by clicking a "play" button.
用户代理(浏览器)或操作系统不允许在当前上下文或情况下播放媒体。例如,如果浏览器要求用户通过单击“播放”按钮显式开始媒体播放,则可能会发生这种情况。
回答by Kardi Teknomo
The browser requires the user to explicitly start media playback by clicking a "play" button. Code below solves your problem.
浏览器要求用户通过单击“播放”按钮显式启动媒体播放。下面的代码可以解决您的问题。
<!DOCTYPE html>
<html>
<head>
<title>Play MP3 music on web</title>
<script>
function playMusic(){
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.
});
}
}
</script>
</head>
<body>
<p>Play MP3</p>
<input type="button" value="play music" onClick="playMusic();">
<audio loop id="sound">
<source src="audio/audio.mp3" type="audio/mpeg">
<p>Browser doesn't support html5</p>
</audio>
</body>
</html>
回答by Daweb
This code may help. It will fire the autoplay (and loop) with a first user's interaction with the DOM.
此代码可能会有所帮助。它将在第一个用户与 DOM 的交互中触发自动播放(和循环)。
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
</head>
<style>html,body{height:100%}</style>
<body>
<!-- SOUND -->
<audio loop id="sound">
<source src="sound.mp3" type="audio/mpeg">
<p>Browser doesn't support html5</p>
</audio>
<!-- CONTENT -->
<button onClick="audio_manager.play()">Play sound</button>
<button onClick="document.querySelector('body').style.backgroundColor = '#'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6);">Do something else</button>
<ol id="text"><li>Autoplay will be start on user first interaction with body (click anywhere to test)</li></ol>
<!-- JS SCRIPT -->
<script>
var audio_manager = {
// Variables
user_has_interacted: false,
detection_is_active: false,
/**
* Init function
*
* Detect first user's interaction
*/
init: function(){
// If already detecting => return
if( audio_manager.detection_is_active){
return false;
}
// Detection active
audio_manager.detection_is_active = true;
// Set up eventListener for user's first interaction
document.querySelector('body').addEventListener('click', audio_manager.detect_first_interaction, true);
},
detect_first_interaction: function(e) {
// Set user_has_interacted to true
audio_manager.user_has_interacted = true;
// Remove listener
document.querySelector('body').removeEventListener(e.type, audio_manager.detect_first_interaction, true);
// Play media (= Autoplay)
audio_manager.play();
// Log first detection
document.getElementById('text').innerHTML += "<li>Autoplay, first interaction detected on " + e.type + " on " + e.target.nodeName + "</li>";
},
/**
* Play function
*
* Play "sound" or init first user's detection
*/
play: function(){
// If user interaction, play media
if(audio_manager.user_has_interacted){
document.getElementById('sound').play();
return true;
}
// Init detection
audio_manager.init();
}
};
// Load autoplay
audio_manager.play();
// Uncomment next line to test autoplay on load without workaround => throw error "Uncaught (in promise) DOMException" or "NotAllowedError: The play method is not allowed by the user agent or the platform in the current context, possibly because the user denied permission."
//document.getElementById('sound').play();
</script>
</body>
</html>
Not a perfect workaround, but useful in some case.
不是完美的解决方法,但在某些情况下很有用。

