私はゲームを作っていて、発生しているイベントで音を鳴らしたいです。現在、以下のようなオブジェクトがあります。
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スレッドとスタックオーバーフローの質問を検索しましたが、エラーの修正definitionを見つけることができません。
どうすれば修正できますか?
.wav
ファイルの使用のみが許可されています。これは、コードホスティングサービスで許可されている唯一のファイル形式であるためです。
Audio.play()は、再生が正常に開始されたときに解決されるPromiseを返します。許可の問題など、何らかの理由で再生を開始しないと、約束が拒否されます。
const playedPromise = audio.play();
if (playedPromise) {
playedPromise.catch((e) => {
if (e.name === 'NotAllowedError' ||
e.name === 'NotSupportedError') {
//console.log(e.name);
}
});
}
あなたの場合、あなたのブラウザ/ OSはオーディオの自動再生を許可していないように見えます。ユーザーエージェント(ブラウザ)またはオペレーティングシステムでは、現在のコンテキストまたは状況でメディアを再生できません。これは、たとえば、ブラウザでユーザーが「再生」ボタンをクリックしてメディアの再生を明示的に開始する必要がある場合に発生することがあります。 こちら は参考値です。
自動再生に関する限り、新しいブラウザーポリシーに従って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');
});
添付のバグから、問題はオーディオ/ビデオの自動再生がデフォルトで無効になっていることが原因のようです。もちろん、これは悪用の量を減らしますが、ユーザーにとって実用的です。ただし、状況によっては、オンザフライでオーディオオブジェクトを作成できないことを意味します。
代わりに、事前に作成し、URLを切り替えて、必要なときにオーディオを再開するだけです。添付されたチケットからの次のスニペットは有望なようです。
// 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();
});
}