eshaz / wasm-audio-decoders

Browser and NodeJS Web Assembly audio decoder libraries that are highly optimized for size and performance.
399 stars 23 forks source link

Using the Opus Decoder in an Audio Worklet #107

Closed spacehash closed 6 months ago

spacehash commented 6 months ago

I'm building a UI in React, and instantiating an audio worklet with the following block.

audioContext.audioWorklet.addModule(workletURL).then(() => { ... }

I can use the decoder in react via the following block.

decoder.ready.then(() => {
    decoder.decodeFrame(base64DecodedOpusFrame).then((opusStructure) => { ... }
});

This works just fine, and I'm able to send the resulting opusStructure.channelData to the worklet and play audio. However, I would like to do this decoding step in the worklet thread, and I can't seem to figure out how to do so. I can import any other npm js package in the worklet.js file via something like the following.

import { package } from "package"

But when I try to do the following, execution stops on that import.

import {OpusDecoder} from "opus-decoder"

I'm unsure how to give a more verbose error explanation, as I'm not sure how to extract that info from a javascript Audio Worklet. Any help would be greatly appreciated.

eshaz commented 6 months ago

I'm not sure import will work at all within an AudioWorklet, depending on how the React app is being built. I believe the AudioWorklet will execute within it's own environment, and won't have access to any of the code defined outside of it, which would include any bundler code that handles the import statement.

There is OpusDecoderWebWorker that executes in a web worker thread, which will accomplish the same multi-threading that running the decoder within an AudioWorklet would. I would recommend using that if you need concurrency. You can decode the Opus data in small chunks if needed by passing the data into the decode method. It will return chunks of audio that can be immediately played in sequence or piped into another AudioWorklet for additional processing.

You might try debugging the worklet with the browser debugger, if you want to continue with that option.

spacehash commented 6 months ago

I'm not sure why I didn't infer, from the name, OpusDecoderWebWorker is a web worker, and as such executes in it's own thread :D. Playing audio in its decode method is trivial and suits my needs. Thank you for your quick response!