Я создал демонстрационный пример голосового помощника, который берет данные с микрофона, передает их в анализатор, а затем использует .getByteFrequencyData()
для отображения визуальных изображений. Он работает следующим образом:
- Нажмите кнопку микрофона для подключения к входу микрофона
- Отпустите кнопку микрофона, чтобы отключить поток микрофона и воспроизвести MP3-ответ.
- Когда заканчивается MP3: вернитесь в режим ожидания и дождитесь нажатия новой кнопки, чтобы снова начать шаг 1.
Живая версия здесь: https://dyadstudios.com/playground/daysi/
Способ, которым я достиг этого, заключается в следующем:
var audioContext = (window.AudioContext) ? new AudioContext() : new window["webkitAudioContext"]();
var analyser = audioContext.createAnalyser();
analyser.fftSize = Math.pow(2, 9); // 512
var sourceMic = undefined; // Microphone stream source
var sourceMp3 = undefined; // MP3 buffer source
// Browser requests mic access
window.navigator.mediaDevices.getUserMedia({audio: true}).then((stream) => {
sourceMic = audioContext.createMediaStreamSource(stream)
})
// 1. Mic button pressed, start listening
listen() {
audioContext.resume();
// Connect mic to analyser
if (sourceMic) {
sourceMic.connect(analyser);
}
}
// 2. Disconnect mic, play mp3
answer(mp3AudioBuffer) {
if (sourceMic) {
// Disconnect mic to prevent audio feedback
sourceMic.disconnect();
}
// Play mp3
sourceMp3 = audioContext.createBufferSource();
sourceMp3.onended = mp3StreamEnded;
sourceMp3.buffer = mp3AudioBuffer;
sourceMp3.connect(analyser);
sourceMp3.start(0);
// Connect to speakers to hear MP3
analyser.connect(audioContext.destination);
}
// 3. MP3 has ended
mp3StreamEnded() {
sourceMp3.disconnect();
// Disconnect speakers (prevents mic feedback)
analyser.disconnect();
}
Он отлично работает на Firefox и Chrome, но OSX Safari 12.1 получает данные с микрофона только при первом нажатии кнопки. Каждый раз, когда я нажимаю кнопку микрофона на втором проходе, анализатор больше не получает данные с микрофона, но данные MP3 все еще работают. Кажется, что подключение, отключение и повторное подключение AudioNode микрофона к анализатору как-то ломает его. Я проверил, и Safari поддерживает AudioNode.connect()
, а также AudioNode.disconnect()
. Я знаю, что реализация WebAudio в Safari немного устарела, есть ли способ обойти эту проблему?