对象方法中的局部变量音频未播放
Posted
技术标签:
【中文标题】对象方法中的局部变量音频未播放【英文标题】:Local variable audio in object method not playing 【发布时间】:2018-10-30 06:17:45 【问题描述】:我正在制作游戏,我希望在发生的事件中播放声音。我目前有一个如下所示的对象:
var soundObject =
invaderShoot: function()
var audio = new Audio("laser.wav");
audio.play();
,
//Many more of the same method
;
然后我正在播放这样的声音:
soundObject.invaderShoot();
但是,当我尝试这样做时,会出现以下错误:
Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
它会在方法中突出显示这一行:
audio.play();
有什么问题?我搜索了 GitHub 线程和 Stack Overflow 问题,但我找不到错误的定义,更不用说如何修复它了。
我应该如何解决这个问题?
我只被允许使用.wav
文件,因为这是我的代码托管服务允许的唯一文件格式。
【问题讨论】:
所有浏览器都出现这种情况吗? 【参考方案1】:Audio.play() 返回一个 Promise,当播放成功开始时该 Promise 被解析。由于任何原因(例如权限问题)未能开始播放,都会导致 Promise 被拒绝。
const playedPromise = audio.play();
if (playedPromise)
playedPromise.catch((e) =>
if (e.name === 'NotAllowedError' ||
e.name === 'NotSupportedError')
//console.log(e.name);
);
在您的情况下,您的浏览器/操作系统似乎不允许自动播放音频。 用户代理(浏览器)或操作系统不允许在当前上下文或情况下播放媒体。例如,如果浏览器要求用户通过单击“播放”按钮明确地开始媒体播放,这可能会发生。 Here 是参考。
就自动播放而言,您可能需要根据新的浏览器策略在 html 中添加 AudoContext。 https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio
编辑
window.onload = function()
var context = new AudioContext();
// Setup all nodes
...
context.resume().then(() =>
audio.play();
console.log('Playback resumed successfully');
);
【讨论】:
但是当你有const playedPromise = audio.play();
,你会如何执行这个函数呢? play()
在您提供的代码中的什么位置?
您可以在代码中添加音频上下文并忽略承诺部分。
例如
是的,在 Safari11 之后,他们添加了这个限制,但他们允许一些例外,比如 Youtube 等。
它似乎工作,非常感谢!如果有任何问题,我会与您联系。【参考方案2】:
从附加的错误来看,问题似乎是由于默认情况下禁用了音频/视频自动播放。这对用户来说当然是实用的,因为它虽然增加了滥用的数量,但它减少了滥用的数量。但是,对于您的情况,这意味着您无法动态创建音频对象。
相反,您应该事先创建它,并在需要时简单地切换 URL/恢复音频。 随附票证中的以下 sn-p 似乎很有希望。
// sm2 attaches the audio element as sound._a
let audio = sound._a;
audio.crossOrigin = 'anonymous';
sound._sourceNode = audioContext.createMediaElementSource(audio);
sound._sourceNode.connect(inputNode);
function play()
/**
* If an AudioContext is created prior to the document receiving a
* user gesture, it will be created in the "suspended" state, and
* you will need to call resume() after a user gesture is
* received.
*/
audioContext.resume().then(() =>
sound.play();
);
https://github.com/scottschiller/SoundManager2/issues/178
【讨论】:
以上是关于对象方法中的局部变量音频未播放的主要内容,如果未能解决你的问题,请参考以下文章