I am using @mediapipe/tasks-vision npm package in the webapp, I want to use my own wasm folder that's present in 'node_modules/@mediapipe/tasks-vision/wasm'.
I am using next.js as the front end.
Any help or sharing is most appreciated.
Code Snippet:-
import { FaceLandmarker, FilesetResolver, DrawingUtils} from "@mediapipe/tasks-vision";
Initialize face landmarker
useEffect(() => {
const createFaceLandmarker = async () => {
const filesetResolver = await FilesetResolver.forVisionTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.14/wasm");
faceLandmarker = await FaceLandmarker.createFromOptions(filesetResolver, {
baseOptions: {
modelAssetPath: "https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task",
delegate: "GPU"
},
outputFaceBlendshapes: true,
runningMode: "VIDEO",
numFaces: 1
});
setLoaded(true);
};
createFaceLandmarker();
}, []);
I have tried every possible way that are below but didn't get the solution:-
A URL must be passed, and not a path. The way this seems to work is the mediapipe library uses the URL you pass to inject a <script>
tag into the page that point towards URLs derived from that one (sub files). The relevant code that ultimately does this (after many nested calls) is here.
This is really quite unusual, hence your legitimate confusion. The library must have some reason for wanting to download this lib asynchronously from a URL at runtime like this. The likely reason is the JS is dynamically loaded based on some conditions about the browser environment, and also because it wants to then further download the WASM binaries, which can't be bundled direct into a JS app trivially.
Regardless It means that we can't use ES import
s to provide the lib during the build.
Instead, you would need to make the specific directory inside of node_modules
available such that it was served from the NextJS public
folder and therefore available on a URL like http://yoursite.com/wasm
.
To do that in an automated way, we could modify NextJS's Webpack configuration such that the relevant files from node_modules
are automatically copied into the public
dir.
First install copy-webpack-plugin to your project:
npm install copy-webpack-plugin --save-dev
In your next.config.js
:
const CopyPlugin = require("copy-webpack-plugin");
const nextConfig = {
webpack: (config) => {
const customPlugins = [
new CopyPlugin({
patterns: [
{
from: 'node_modules/@mediapipe/tasks-vision/wasm',
to: '../public/', // Reason for `..` is because next uses the hidden `.next` folder during build
},
],
}),
];
config.plugins.push(...customPlugins);
return config;
},
};
module.exports = nextConfig;
You will want to add public/wasm
to your .gitignore
to not accidentally commit these files. We will rely on the build copying them to the right place.
Now the files should be hosted on a URL on your site e.g. http://yoursite.com/wasm
.
Next, change the reference to this URL in the code:
const filesetResolver = await FilesetResolver.forVisionTasks("/wasm");
Restart NextJS to ensure the build config change is applied.