Safari AudioContext приостановлен даже при создании по клику - PullRequest
0 голосов
/ 26 июня 2019

У меня проблемы с созданием AudioContext с Safari (для ПК и мобильных устройств).Кажется, что даже с созданием после взаимодействия с пользователем, оно все еще приостановлено.

Мой код:

<button onclick="test()">Test</button>
const test = () => {
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    audioContext = new AudioContext();
    console.log(audioContext.state); // Suspended
}

Это должен быть минимальный рабочий пример, верно?Что здесь не так?

1 Ответ

1 голос
/ 26 июня 2019

Я думаю, что Safari действительно ведет себя правильно (по крайней мере, частично) в этом случае. Спецификация Web Audio говорит, что ...

Вновь созданный AudioContext всегда начинается в приостановленном состоянии, и событие изменения состояния будет запускаться всякий раз, когда состояние изменяется на другое состояние.

https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-onstatechange

К сожалению, Safari не выполняет переход в состояние running самостоятельно. Вы должны явно попросить это сделать.

audioContext.resume();
audioContext.onstatechange = () => console.log(audioContext.state);

Событие statechange должно сработать почти сразу. Если вы выполните это в обработчике кликов.

Приведенная выше функция будет выглядеть следующим образом:

const test = () => {
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    audioContext = new AudioContext();
    console.log(audioContext.state); //suspended
    audioContext.resume();
    audioContext.onstatechange = () => console.log(audioContext.state); // running
}

Интересно, что Safari запускает событие statechange, только если вы сохранили оператор console.log перед вызовом resume().

Однако есть еще один способ взлома AudioContext. Просто создайте простой GainNode.

const test = () => {
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    audioContext = new AudioContext();
    audioContext.createGain();
    console.log(audioContext.state); // running
}

Вы также можете попробовать standard-audio-context , который заставляет все браузеры вести себя одинаково в этом отношении.

...