Safari webkitAudioContext.createBuffer API вызывает исключение NotSupportedError - PullRequest
0 голосов
/ 10 февраля 2019

Я использую JavaScript Web Audio API AudioContext для воспроизведения аудио.Он отлично работает с другими основными браузерами, но Safari на MacOS вызывает исключение NotSupportedError при вызове API webkitAudioContext.createBuffer.Я нашел этот вопрос, Play PCM с javascript , также указал, что в конце страницы была такая проблема с Safari.Итак, я отладил «Рабочий пример https://o.lgm.cl/example.html (16-битный LSB)» оттуда и столкнулся с той же проблемой с Safari.

Поскольку я все еще новичок в StackOverflow, я не могу добавлять комментарии к этому вопросу, спрашивая, как они решили эту проблему.Итак, кто-то может помочь?Очень признателен!

Редактировать:

Запустите эти 2 строки кода в консоли JavaScript Safari, чтобы воспроизвести проблему:

var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); 
var myAudioBuffer = audioCtx.createBuffer(1, 48000, 16000); 

> NotSupportedError: The operation is not supported.

1 Ответ

0 голосов
/ 13 февраля 2019

Ошибка, которую вы получаете, почти ожидаема.Спецификация Web Audio говорит, что NotSupportedError должен быть выдан, если sampleRate находится за пределами поддерживаемого диапазона.Но в нем также говорится, что самая низкая поддерживаемая sampleRate должна составлять не менее 8000 Гц.

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

Реализация Safari Web Audio поддерживает только AudioBuffers с 22050 Гц и более.Поэтому я бы предложил создать AudioBuffer с частотой 32000 Гц, потому что 32 кратно 16, что немного облегчает рассуждение о следующем шаге.

При заполнении буфера необходимо компенсировать больший sampleRate путем интерполяциинедостающие значения сами.Я думаю, что базовая линейная интерполяция должна работать достаточно хорошо.Но вы также можете использовать OfflineAudioContext для повторной выборки вашего AudioBuffer.

В идеальном мире (например, Firefox, Chrome или Opera) вы можете выполнить повторную выборку AudioBuffer следующим образом:

// Let's assume you have an AudioBuffer called audioBuffer of 1 second at 16 kHz.
const offlineAudioContext = new OfflineAudioContext(
    { length: 32000, sampleRate: 32000 }
);
const audioBufferSourceNode = new AudioBufferSourceNode(
    offlineAudioContext,
    { buffer: audioBuffer }
);

audioBufferSourceNode.start(0);
audioBufferSourceNode.connect(offlineAudioContext.destination);

const resampledAudioBuffer = await offlineAudioContext.startRendering();

Переменная resampledAudioBuffer теперь будет ссылаться на пересчитанный AudioBuffer с частотой 32 кГц.

Но реализация API Web Audio в Safari устарела и глючит.Он не только не поддерживает создание AudioBuffers с частотой менее 22050 Гц, но также не может создавать OfflineAudioContext с частотой менее 44100 Гц.

Однако все, что вам нужно для вашего варианта использования, - это выполнить повторную выборку данных с помощьюфактор два.Теоретически это то же самое, что изменить частоту дискретизации от 16 кГц до 32 кГц или от 44100 Гц до 88200 Гц.

Таким образом, вы можете создать AudioBuffer на частоте 44100 Гц и заполнить его данными, которые на самом деле на частоте 16 кГц.Затем вы повторно измеряете этот буфер до 88200 Гц.Полученные данные будут вашими исходными данными в 32 кГц.

Это все очень сложно, но, к сожалению, я не знаю другого способа сделать это в Safari.

Чтобы избежать необходимостиЧтобы использовать устаревший синтаксис, который все еще необходим для Safari, я бы порекомендовал использовать полифилл.Я являюсь автором стандартизированного аудио-контекста , поэтому я бы порекомендовал это, но он не единственный.

...