Нет, это не « в ответ на нажатие кнопки ».
В ответ на это событие щелчка вы запускаете асинхронную задачу.К тому времени, когда вы звоните source.start(0)
, ваше событие уже давно умерло (или, по крайней мере, больше не является "жестом доверенного пользователя". Поэтому они действительно заблокируют этот вызов.
Чтобы обойти это, вы можете просто пометитьконтекст разрешен с тишиной. Затем, когда данные будут доступны, вы сможете запустить их без ограничений:
function markContextAsAllowed(context) {
const gain = context.createGain();
gain.gain.value = 0; // silence
const osc = context.createOscillator();
osc.connect(gain);
gain.connect(context.destination);
osc.onended = e => gain.disconnect();
osc.start(0);
osc.stop(0.01);
}
onPreviewPressed(media: Media): void {
const url = ".....";
// declare in the event handler
const context = new(window.AudioContext || window.webkitAudioContext)();
const source = context.createBufferSource();
// allow context synchronously
markContextAsAllowed(context);
this.httpClient.get(url, {
responseType: 'blob'
}).subscribe(x => {
const fileReader = new FileReader();
fileReader.onloadend = () => {
context.decodeAudioData(fileReader.result, buffer => {
source.buffer = buffer;
source.connect(context.destination);
source.start(0);
}, y => {
console.info("Error: " + y);
});
};
fileReader.readAsArrayBuffer(x);
});
}
Как скрипка, так как Safari не любит чрезмернуюЗащищенный StackSnippets®
Кроме того, мои угловые знания очень ограничены, но если httpClient.get
поддерживает опцию {responseType: 'arraybuffer'}
, вы можете избавиться от этого FileReader и избежать двойного заполнения памяти одними и теми же данными..
Наконец, если вы собираетесь воспроизводить этот звук более одного раза, рассмотрите возможность его предварительной выборки и предварительного декодирования, тогда вы сможете избежать всего асинхронного беспорядка.