Использование getByteFrequencyData на iPad и Safari / Chrome - PullRequest
0 голосов
/ 19 марта 2020

Я работаю над (веб-) анимацией, которая двигает губами с воспроизводимой аудио речью. Я использую Javascript getByteFrequencyData () для определения низких и высоких частот и очень реалистичного c движения рта.

Код отлично работает во всех Windows браузерах, на android (chrome), но я сталкиваюсь с огромной проблемой на IOS с Safari, а также с Chrome: getByteFrequencyData всегда возвращает постоянное значение. Ошибки не регистрируются в консоли, поэтому все объекты создаются, звук воспроизводится (как запущено в контексте взаимодействия с пользователем).

ОБНОВЛЕНИЕ: Я тестировал Safari, Firefox, Edge и Chrome, все с тот же результат.

ОБНОВЛЕНИЕ2: все приложение работает не в Safari OSX, а в Chrome OSX. На Chrome OSX (Catalina) getByteFrequencyData также работает хорошо. Кажется, это проблема iOS.

Вот как я запускаю аудиосистему (один раз):

...
audio = document.getElementById("audio");  
audio.addEventListener('ended', onAudioPlayed, false);
var AudioContext = window.AudioContext || window.webkitAudioContext;  
ctx = new AudioContext();
audioSrc = ctx.createMediaElementSource(audio);
audioSrc.connect(ctx.destination);
analyser = ctx.createAnalyser();
frequencyData = new Uint8Array(analyser.frequencyBinCount);
...

И я использую метод requestAnimationFrame-Method для подачи анимации:

...    
audio.src = "audio/" + audioQueue.shift();
console.log("play: "+audio.src);
audio.type = "audio/mp3";
analyser.fftSize = 64;
analyser.smoothingTimeConstant = 0.4;
analyser.minDecibels = -80;
analyser.maxDecibels = -20;
audioSrc.connect(analyser);
analyser.getByteFrequencyData(frequencyData);

function renderFrame() {
    if (!audio.paused) requestAnimationFrame(renderFrame);
    analyser.getByteFrequencyData(frequencyData);
    avgHigh = 0;
    avgLow = 0;

    count = analyser.frequencyBinCount;
    //console.log("rendermund " + frequencyData[0]);
    for (i = 0; i < count; i++) {
        if (i < count/4)
            avgLow += frequencyData[i]
        else
            avgHigh += frequencyData[i];
    }
    console.log("rendermund " + avgHigh + "/" + avgLow);
    avgLow = avgLow/2000;
    avgHigh = avgHigh/2000;
    if (avgLow > 1) avgLow = 1;
    if (avgHigh > 1) avgHigh = 1;
    mund(avgHigh,avgLow); // Here I draw the mouth...
}
audio.load();
audio.play();
renderFrame();
...

Есть ли альтернативный способ получения живой информации о сэмплах, которые воспроизводятся в данный момент?

Странно то, что я не получаю никаких сообщений об ошибках - getByteFrequencyData () возвращает массив ожидаемого размера, но с постоянными значениями (0) на iOS. Я протестировал последнюю версию IO на Ipad Air, IPad Air 2 и iPad 5-го и 6-го поколения с одинаковым результатом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...