I tried to integrate Mediasoup into a Typescript application built with webpack. Unfortunately the worker binary doesn’t get loaded when I am creating a new worker with the createWorker() method. The following error is produced:
I tried to set PATH and LD_LIBRARY_PATH to …/node_modules/mediasoup/ or …/node_modules/mediasoup/worker/out/Release (where the binary in fact exists and is executable) but that didn’t help.
Webpack is not (only) client-side. It’s used as a kind of “Makefile” for the Typescript build process.Among other things it can also be used to create “dynamic imports” (implemented through “code splitting”).
Honestly no idea about the issue. The mediasoup-worker is compiled and properly placed when you do npm install in your Node project that includes mediasoup dependency. And of course it’s placed within node_modules/mediasoup/ folder. I don’t think webpack can change that or expect something different.
This is in mediasoup/src/Worker.ts (which is translated into mediasoup/lib/Worker.js):
// If env MEDIASOUP_WORKER_BIN is given, use it as worker binary.
// Otherwise if env MEDIASOUP_BUILDTYPE is 'Debug' use the Debug binary.
// Otherwise use the Release binary.
const workerBin = process.env.MEDIASOUP_WORKER_BIN
? process.env.MEDIASOUP_WORKER_BIN
: process.env.MEDIASOUP_BUILDTYPE === 'Debug'
? path.join(__dirname, '..', 'worker', 'out', 'Debug', 'mediasoup-worker')
: path.join(__dirname, '..', 'worker', 'out', 'Release', 'mediasoup-worker');
We don’t set any absolute path, or yes, we do (based on __dirname).
No idea how to help, you should debug what your “npm” installer is doing.
Apologies for reviving a dead thread, I wanted to leave this here for anyone else treading the same path.
So there are a couple of things at play here:
1st we’re using Yarn, which may or may not involve using PnP, if you are using PnP then everything is going to be zipped in your cache, don’t feel down, all is not lost! yarn probably had the good sense to unplug the package because of the post-install compile for the worker.
But this doesn’t help you much right because you went all webpack-fu and you need to productionize this stuff, and the entire point of web packing was to #1File your server, cool, I got you!
So in your webpack config we will need to make a couple of changes, first yarn add -D the copy-webpack-plugin and add it into your webpack config:
Next you will need a plugins section in the webpack config:
plugins: [
new CopyPlugin({
patterns: [
{
from: "./.yarn/unplugged/mediasoup*/node_modules/mediasoup/worker/out/Release/mediasoup-worker",
to: "./worker/out/Release/mediasoup-worker",
toType: "file",
},
],
}),
],
What we’re doing is copying the file we compiled (I presume we’re in your pipeline so building for your target architecture here).
We don’t know the unpacked folder name in yarn for mediasoup so, we’re using a wildcard, webpack will get confused and think this is a directory because there is no file extension so we’re going to give it the hint toType.
Finally, as mentioned in the above thread, media soup is using some classy logic to figure out the path of the worker.
So we need to add this to the webpack config to change the behaviour of the __dirname, otherwise, the “…” in the path join will kill our hopes and dreams.
node: {
__dirname: true,
},
So now you’re going to end up with a dist file containing the correct folder structure for the worker, the worker binary, and your code with a modified __dir behaviour that will stop the “…” in the path calculation killing us off.
Sorry, I had more images here but apparently, I’m only allowed 1 embedded image as a new user.
Hopefully, this helps the next yarn + webpacker in their journey
I don’t think it’s an issue, and there certainly isn’t anything wrong with classy logic, it’s just webpack changing the behavior of __dirname.
The env var is there for folks to override the location; that was super useful this morning when I solved it one way, it was only really double back that caught me out.
But this thread was enough of a hint in the right direction, I just wanted to leave as close to a complete solution here for the next person.
I don’t know if parcel or snowpack or esbuild will have the same issue, webpack is a hangover from a lot of AWS lambda work with them still only supporting CJS.
I did wonder about a fallback to look in process.cwd for mediasoup_worker, don’t think it’s important though, and the documentation is really solid around this.