Next.js项目中如何使用@mediapipe/tasks-vision本地wasm子文件夹?
在Next.js中本地加载@mediapipe/tasks-vision的Wasm资源
你之前的尝试没成功,核心原因是Next.js的构建机制不会把node_modules里的静态资源直接暴露给客户端,客户端无法直接访问服务器端的node_modules目录,直接写相对路径或者import文件夹都不生效。下面给你几个可行的解决方案:
方案一:手动复制Wasm资源到Public目录
- 找到
node_modules/@mediapipe/tasks-vision/wasm文件夹,把里面的所有文件(包括.wasm、.js等)复制到你的Next.js项目的public/mediapipe-wasm目录下(如果没有mediapipe-wasm文件夹就新建一个) - 修改你的初始化代码,把FilesetResolver的路径改成客户端可访问的静态资源路径:
import { FaceLandmarker, FilesetResolver, DrawingUtils} from "@mediapipe/tasks-vision"; import { useEffect, useState } from 'react'; let faceLandmarker; export default function YourComponent() { const [loaded, setLoaded] = useState(false); useEffect(() => { const createFaceLandmarker = async () => { // 这里用public目录下的路径,Next.js会自动映射到根路径 const filesetResolver = await FilesetResolver.forVisionTasks("/mediapipe-wasm"); faceLandmarker = await FaceLandmarker.createFromOptions(filesetResolver, { baseOptions: { // 如果你想把模型也本地化,就把face_landmarker.task下载到public目录,然后写"/face_landmarker.task" 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(); }, []); // 组件后续逻辑... }
方案二:用npm脚本自动复制资源(推荐)
手动复制太麻烦,可以加个postinstall脚本,每次执行npm install后自动把Wasm资源复制到public目录:
在项目的package.json里添加:
"scripts": { // 其他脚本... "postinstall": "cp -r node_modules/@mediapipe/tasks-vision/wasm public/mediapipe-wasm" }
注意:Windows系统下需要把cp -r换成xcopy /E /I,或者用跨平台的工具比如copyfiles(需要先安装npm i copyfiles -D),脚本改成:"postinstall": "copyfiles -u 3 node_modules/@mediapipe/tasks-vision/wasm/** public/mediapipe-wasm"
为什么之前的方法无效?
import wasm from '@mediapipe/tasks-vision/wasm':Wasm文件夹不是一个可导入的ES模块,这种写法不符合模块导入规范../node_modules/@mediapipe/tasks-vision/wasm:客户端浏览器无法访问服务器端的node_modules目录,这个路径在客户端环境下是无效的FilesetResolver.forVisionTasks需要的是客户端可访问的URL路径,不是本地文件系统的路径
内容的提问来源于stack exchange,提问作者Ritik
相关产品推荐
相关产品推荐

