Ошибка AudioWorklet: DOMException: пользователь прервал запрос
Я успешно создал простой AudioWorklet в React и хочу запустить простой генератор, как в примере с Google. Чтобы протестировать его, я рендерил кнопку, событие onClick которой вызывает следующее:
SRC /App.jsx:
userGesture(){
//create a new AudioContext
this.context = new AudioContext();
//Add our Processor module to the AudioWorklet
this.context.audioWorklet.addModule('worklet/processor.js').then(() => {
//Create an oscillator and run it through the processor
let oscillator = new OscillatorNode(this.context);
let bypasser = new MyWorkletNode(this.context, 'my-worklet-processor');
//Connect to the context's destination and start
oscillator.connect(bypasser).connect(this.context.destination);
oscillator.start();
})
.catch((e => console.log(e)))
}
Проблема в том, что при каждом клике метод addModule возвращает следующую ошибку:
DOMException: The user aborted a request.
Я использую Chrome v66 на Ubuntu v16.0.4.
SRC /worklet/worklet-node.js:
export default class MyWorkletNode extends window.AudioWorkletNode {
constructor(context) {
super(context, 'my-worklet-processor');
}
}
SRC /worklet/processor.js
class MyWorkletProcessor extends AudioWorkletProcessor {
constructor() {
super();
}
process(inputs, outputs) {
let input = inputs[0];
let output = outputs[0];
for (let channel = 0; channel < output.length; ++channel) {
output[channel].set(input[channel]);
}
return true;
}
}
registerProcessor('my-worklet-processor', MyWorkletProcessor);
7 ответов
Мой код - прямой JavaScript, а не React, но я получил ту же ошибку, потому что указан неверный путь к addModule. В моем случае и сценарий, который вызывает addModule, и сценарий, предоставленный в качестве аргумента для addModule, находятся в одном и том же каталоге ("js"). Несмотря на это, мне все равно пришлось включить этот каталог в путь, чтобы устранить ошибку:
...addModule('js/StreamTransmitter.js')...
Надеюсь, это поможет. Удачи!
Это сработало для меня: обслуживайте файлы рабочихлет из
public
папка вместо
src
. В
addModule(url)
функция указывает туда по умолчанию, поэтому
addModule('worklets/foo.js')
файл ссылок
public\worklets\foo.js
Источник: https://hackernoon.com/implementing-audioworklets-with-react-8a80a470474
Если кто-то еще получает эту загадочную ошибку, проглотите свою гордость и проверьте следующее:
- В процессоре ошибок нет.
- Процессор вызывает внешние модули с правильным путем к внешнему файлу (ам).
- Во внешних модулях ошибок нет.
Обещание будет прервано, когда внешние модули, загруженные с помощью "импорта", будут иметь ошибки или пути к модулям не могут быть разрешены (например, путь к модулям неверен и не указывает на существующие файлы).
Это похоже на ошибку в загрузчике модуля Chromium, он анализирует worklet/processor.js
файл, удаляя пробелы, что, в свою очередь, вызывает повсюду ошибки синтаксиса JavaScript, что в итоге приводит к появлению этого общего необъяснимого сообщения об ошибке.
Решение состоит в том, чтобы обслуживать ваши рабочие процессоры (например, worklet/processor.js
в вашем случае) с:
Content-Type: application/javascript
или же
Content-Type: text/javascript
Я также столкнулся с этой ошибкой, но из-за проблемы с Webpack.
Оказывается, webpack не поддерживает рабочие процессы, как он поддерживает веб-работники (см. этот выпуск).
я бы рекомендовал использоватьс вебпаком.
- Установить
worker-url
npm i --save-dev worker-url
- Обновите конфигурацию вашего веб-пакета, чтобы включить плагин WorkerUrl.
const WorkerUrlPlugin = require('worker-url/plugin');
module.exports = {
// ...
plugins: [new WorkerUrlPlugin()],
// ...
};
- Используйте WorkerUrl следующим образом:
import { WorkerUrl } from 'worker-url';
const workletUrl = new WorkerUrl(
new URL('./random-noise-processor', import.meta.url),
{ name: 'worklet' },
);
await context.audioWorklet.addModule(workletUrl);
Ошибка"DOMException: The user aborted a request."
происходит, когда функция не может загрузить файл по указанному вами пути или URL-адресу. Обратитесь к этой странице MDN
APIAudioWorklet.addModule()
ожидает строку, содержащую URL-адрес файла JavaScript с модулем для добавления.
В данном случае это может быть внутренний URL-адрес, указывающий на то, куда браузер загружает ваши статические файлы ->'worklet/processor.js
еслиworklet folder
находится внутриpublic directory
вашего приложения React. Вы можете изменить свой код, как показано ниже.
this.context.audioWorklet.addModule('worklet/processor.js')
В этом случаеaudioWorklet.addModule()
метод ожидает, что путь будет указывать на вашpublic folder
. Это также может быть внешний URL-адрес, например ссылка на репозиторий Github, который загружает файл JS.
Меняется:
this.context.audioWorklet.addModule('worklet/processor.js')
с участием
this.context.audioWorklet.addModule('../worklet/processor.js')
работал у меня.