You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js v15 + TypeScript环境下使用ricky123 VAD实现浏览器语音活动检测时初始化卡顿的问题求助

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状态:

  1. 验证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/``。
  2. 检查模型文件的完整性
    @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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 07:10:28