AudioWorklet error: DOMException: The user aborted a request

16.9k views Asked by At

I've successfully instantiated a simple AudioWorklet in React and wish to start a simple oscillator like in Google's example. In order to test run it, I am rendering a button whose onClick event calls the following:

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)))
}

The problem is, on every click, addModule method is returning the following error:

DOMException: The user aborted a request.

I am running Chrome v66 on 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

There are 7 answers

0
Andrei Kirshin On

Changing:

this.context.audioWorklet.addModule('worklet/processor.js') 

with

this.context.audioWorklet.addModule('../worklet/processor.js') 

worked for me.

0
Hamza Kyamanywa On

The Error "DOMException: The user aborted a request." happens when the AudioWorklet.addModule() function cannot load the file from the path or URL you provided. Refer to this MDN page

The api AudioWorklet.addModule() expects a String containing the URL of a JavaScript file with the module to add.

It can be an internal URL that points to your public folder where the browser loads your static files in this case -> 'worklet/processor.js if the worklet folder is inside the public directory of your React app. You can modify your code as below.

this.context.audioWorklet.addModule('worklet/processor.js')

In this case the audioWorklet.addModule() method expects the path to point to your public folder. It can also be an external URL for example a link to Github repository that loads the JS file.

1
StephenL On

My code is straight JavaScript, not React, but I got the same error because the path provided to addModule was incorrect. In my case, both the script that calls addModule and the script provided as the argument to addModule reside in the same directory ("js"). In spite of that, I still had to include this directory in the path to eliminate the error:

...addModule('js/StreamTransmitter.js')...

I hope this helps. Good luck!

1
John Weisz On

This seems to be a bug in the Chromium module loader, it parses the worklet/processor.js file by removing whitespace, which in turn causes it to have JavaScript syntax errors everywhere, which then finally causes this generic non-explanatory error message to show up.

The solution is to serve your worklet-processors (e.g. worklet/processor.js in your case) with:

Content-Type: application/javascript

or

Content-Type: text/javascript
0
Rico Kahler On

I also experienced this error but due to a Webpack issue.

Turns out webpack doesn't support worklets like it supports web workers (see this issue).

I would recommend using worker-url with webpack.

  1. Install worker-url
npm i --save-dev worker-url
  1. Update your webpack config to include the WorkerUrl plugin.
const WorkerUrlPlugin = require('worker-url/plugin');

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

  1. Use WorkerUrl like so:
import { WorkerUrl } from 'worker-url';

const workletUrl = new WorkerUrl(
  new URL('./random-noise-processor', import.meta.url),
  { name: 'worklet' },
);

await context.audioWorklet.addModule(workletUrl);
1
Adam D. On

This worked for me: serve your worklet files from public folder instead of src. The addModule(url) function points there by default, so addModule('worklets/foo.js') references file public\worklets\foo.js

Source: https://hackernoon.com/implementing-audioworklets-with-react-8a80a470474

1
bob On

For anyone else getting this mysterious error, swallow your pride and check the following:

  • The processor doesn't have any errors.
  • The processor is calling external modules with proper path to the external file(s).
  • The external modules don't have any errors.

The promise will abort when external modules that are loaded via "import" have errors, or the paths to the modules can't be resolved (e.g. the path's to the modules are wrong and don't point to existing files).