wasm-media-encoders icon indicating copy to clipboard operation
wasm-media-encoders copied to clipboard

Web Workers support

Open vyconm opened this issue 6 months ago • 1 comments

Awesome little package - I am currently experimenting with converting audio files to smaller versions for use in our AI platform, and this fits just the case!

As that can obviously heavily block the main thread, I am trying to create a client side worker for this, but seem to be running into Browser API issues:

Uncaught (in promise) TypeError: (self.AudioContext || self.webkitAudioContext) is not a constructor at self.onmessage (encodeMp3Worker.js:6:24) self.onmessage @ encodeMp3Worker.js:6

We are using SvelteKit 2 with Svelte 5, which is all based around Vite. My code looks like this:

import { createEncoder } from "wasm-media-encoders";

self.onmessage = async function (e) {
  const { pcmLeft, pcmRight, sampleRate, numberOfChannels } = e.data;

  try {
    const encoder = await createEncoder(
      "audio/mpeg",
      new URL("wasm-media-encoder/wasm/mp3", import.meta.url),
    );

    encoder.configure({
      sampleRate: sampleRate,
      channels: numberOfChannels,
      vbrQuality: 6,
    });

    let outBuffer = new Uint8Array(1024 * 1024);
    let offset = 0;
    let moreData = true;

    while (true) {
      const mp3Data = moreData
        ? encoder.encode([pcmLeft, pcmRight])
        : encoder.finalize();

      if (mp3Data.length + offset > outBuffer.length) {
        const newBuffer = new Uint8Array(mp3Data.length + offset);
        newBuffer.set(outBuffer);
        outBuffer = newBuffer;
      }

      outBuffer.set(mp3Data, offset);
      offset += mp3Data.length;

      if (!moreData) {
        break;
      }

      moreData = false;
    }

    const mp3Blob = new Blob([new Uint8Array(outBuffer.buffer, 0, offset)], {
      type: "audio/mp3",
    });

    self.postMessage({
      mp3Blob,
    });
  } catch (error) {
    console.error("Error during MP3 encoding:", error);
    self.postMessage({
      error: error.message,
    });
  }
};

I was under the impression, that the imported package should basically only be WASM, yet it is searching for Browser API types - is this expected behaviour?

Thank you for the help!

vyconm avatar Sep 03 '24 19:09 vyconm