Skip to content

[worklets] Add ability to determine if a module is available #986

Open
@a2sheppy

Description

@a2sheppy

While the addModule() method available on Worklets lets you load and install modules into the worklet, and uses a promise to let the caller know success or failure, there's no after-the-fact method available to determine the state of the module.

One scenario (slightly contrived but not in a very improbable way) in which this could come into play is a function which is used to set up a new AudioWorkletNode that looks like this:

let audioInfo = {
  audioContext: null,
  myAudioProcessor: null,
  ...
};

async function createMyAudioProcessor() {
  if (!audioInfo.audioContext) {
    try {
      audioInfo.audioContext = new AudioContext();
      await audioInfo.audioContext.resume();
      await audioInfo.audioContext.audioWorklet.addModule(
                  "module-url/module.js");
    } catch(e) {
      return null;
    }
  }

  return new AudioWorkletNode(audioInfo.audioContext,
                  "processor-name");
}

This function checks the specified AudioContext to see if it's null and if it is, creates the context and installs the processor module into it before then proceeding to create a new AudioWorkletNode and return it to the caller.

However, if the user does the following, there's a problem:

let audioInfo.audioContext = new AudioContext();
let audioInfo.myAudioProcessor = createMyProcessor(context);

This will fail because the module hasn't been loaded. To solve problems like this, a method to determine if the module has been loaded would be helpful. That would let the createMyAudioProcessor() function become something like:

async function createMyAudioProcessor() {
  if (!audioInfo.audioContext) {
    try {
      audioInfo.audioContext = new AudioContext();
      await audioInfo.audioContext.resume();
    } catch(e) {
      return null;
    }
  }

  if (!audioContext.isModuleLoaded("module-url/module.js") {
    await audioInfo.audioContext.audioWorklet.addModule(
                  "module-url/module.js");
  }

  return new AudioWorkletNode(audioInfo.audioContext, 
                  "processor-name");
}

This now will work even if the context has already been created:

let audioInfo = {
  audioContext: null,
  myAudioProcessor: null,
  ...
};

audioInfo.audioContext = new AudioContext();
audioInfo.myAudioProcessor = createMyAudioProcessor();

An alternative to isModuleLoaded() would be a method on Worklet that returns a status string, such as:

let moduleStatus = audioContext.audioWorklet.getModuleStatus(
                  "module-url/module.js");

This could also be done at the AudioWorklet level to ask about a processor rather than a module:

let moduleStatus = audioContext.audioWorklet.getProcessorStatus(
                  "processor-name");

The could be a string such as available or unavailable, with the possibility of other statuses.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions