Ошибка 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 не поддерживает рабочие процессы, как он поддерживает веб-работники (см. этот выпуск).

я бы рекомендовал использоватьс вебпаком.

  1. Установитьworker-url
      npm i --save-dev worker-url
  1. Обновите конфигурацию вашего веб-пакета, чтобы включить плагин WorkerUrl.
      const WorkerUrlPlugin = require('worker-url/plugin');

module.exports = {
  // ...
  plugins: [new WorkerUrlPlugin()],
  // ...
};

  1. Используйте 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') 

работал у меня.

Другие вопросы по тегам