Next.js v15 + TypeScript环境下使用ricky123 VAD实现浏览器语音活动检测时初始化卡顿的问题求助
先排查代码里的致命疏漏
看你贴的Web Worker代码片段,发现一个很容易踩的小错误:在self.onmessage回调里,你直接写了switch (type),但完全没从event.data里解构出type变量!正确的写法应该是:
self.onmessage = async (event) => { const { type } = event.data; // 这行你漏掉了! switch (type) { case "init": vad = await MicVAD.new({ baseAssetPath: '/vad-models/', stream: undefined, // 你的回调配置... }); console.log("Initialize VAD object."); vad.start(); self.postMessage({ type: "initComplete" }); break; // 其他case... } }
如果没有这行,type变量未定义,switch根本不会走到init分支——你以为是await MicVAD.new卡住了,但实际上这行代码根本没被执行。先把这个补上,应该能解决大部分问题!
再排查模型资源加载的核心问题
如果补完上面的代码还是卡住,那大概率是模型文件加载失败,导致await MicVAD.new一直处于pending状态:
验证
baseAssetPath的正确性
在Next.js v15里,public目录下的资源直接通过根路径访问。你设置的baseAssetPath: '/vad-models/',实际请求的模型URL应该是http://localhost:3000/vad-models/silero_vad_v5.onnx。打开浏览器Network面板,触发VAD初始化,看看这个请求是否存在:- 如果返回404:确认
silero_vad_v5.onnx确实放在public/vad-models/目录下(注意大小写!生产环境/ Linux 系统对文件名大小写敏感)。 - 如果你的Next.js配置了
basePath(比如部署在子路径),那baseAssetPath要带上基础路径,比如baseAssetPath:${process.env.NEXT_PUBLIC_BASE_PATH}/vad-models/``。
- 如果返回404:确认
检查模型文件的完整性
@ricky0123/vad-web的MicVAD可能需要多个配套文件,比如有些版本会依赖silero_vad_v5.onnx和silero_vad_v5.onnx.data。你可以去node_modules/@ricky0123/vad-web/dist/assets目录下看看,把所有相关模型文件都复制到public/vad-models/里。
规范Next.js中Web Worker的使用方式
Next.js v15对Web Worker有内置支持,但要注意正确的导入方式,避免模块解析问题:
在主线程创建Worker时,应该用Next.js推荐的语法:
// 主线程代码 import VADWorker from './ricky123-vad.worker?worker' // 初始化Worker this.ricky123VadWorker = new VADWorker()
这种方式会让Next.js正确处理Worker中的ES模块导入(比如你用的import { MicVAD } from '@ricky0123/vad-web'),避免普通Worker环境下的模块加载错误。
备选方案:如果ricky123 VAD仍有问题,试试原始silero-vad或调整web-vad配置
如果@ricky0123/vad-web的问题始终无法解决,可以直接用原始silero-vad手动实现逻辑(可控性更强):
// VAD Worker代码 import * as ort from 'onnxruntime-web' let session: ort.InferenceSession self.onmessage = async (event) => { const { type, data } = event.data if (type === 'init') { // 手动加载模型 session = await ort.InferenceSession.create('/vad-models/silero_vad_v5.onnx') self.postMessage({ type: 'initComplete' }) } else if (type === 'data') { // 手动处理音频帧、计算语音概率(可参考ricky0123/vad-web的源码逻辑) } }
至于你提到的web-vad问题,大概率是Next.js打包时的wasm文件处理问题,你可以在next.config.js中添加配置:
/** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config) => { config.module.rules.push({ test: /\.wasm$/, type: 'asset/resource', generator: { filename: 'static/wasm/[name].[hash][ext]' } }) return config } } module.exports = nextConfig
这样能确保web-vad依赖的wasm文件被正确打包和加载。
内容来源于stack exchange

