前言
之前想找一个图片压缩和转格式的插件,但vite社区里没有,就自己写了一个vite-plugin-image-tools
好了,现在想要一个音频的压缩转换格式的插件,也找不到😄,真的没人有这种需求吗?
算了算了,自己写一个吧,实现和vite-plugin-image-tools差不多,就把思路交给ai让它帮我写吧。
插件
安装:
# npm
npm i -D vite-plugin-audio-compress
# pnpm
pnpm i -D vite-plugin-audio-compress
#yarn
yarn add -D vite-plugin-audio-compress
使用
import { defineConfig } from "vite";
import audioCompress from "vite-plugin-audio-compress";
export default defineConfig({
plugins: [audioCompress()],
});
配置说明
类型可从 vite-plugin-audio-compress 与 vite-plugin-audio-compress/type 导入。
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
include / exclude | FilterPattern | - | Rollup 风格的 glob 过滤 |
filter | (filePath: string) => boolean | () => true | 额外自定义过滤 |
format | string | mp3 | 输出格式 |
bitrate | string | 128k | 音频码率 |
sampleRate | number | 44100 | 采样率 |
channels | number | 2 | 声道数 |
transform | (filePath: string) => void | Partial<...> | - | 针对单文件的参数覆盖 |
cacheDir | string | node_modules/.cache/vite-plugin-audio-compress | 缓存目录 |
concurrency | number | 2 | ffmpeg 最大并发数 |
removeOriginal | boolean | false | 保留字段以兼容旧版;打包时对匹配的音频资源一律就地替换(扩展名不变则对外路径不变) |
需求
- 构建阶段对匹配规则的音频资源做转码/压缩(默认输出 MP3,码率、采样率、声道等可配)。
- 产物中 引用路径与实际写出文件名一致(含扩展名变化,例如
.wav→.mp3)。 - 开发环境上对真实音频请求返回已转码内容,并带 磁盘缓存,避免重复跑 ffmpeg。
- 可配置
include/exclude/filter/transform;ffmpeg 任务通过 并发池 限制并行度。
技术栈
| 组件 | 作用 |
|---|---|
ffmpeg-static | 捆绑 ffmpeg 二进制,减少对环境预装 ffmpeg 的依赖(CI 需匹配 OS/架构)。 |
execa | 调用 ffmpeg 子进程。 |
Rollup generateBundle | 构建期遍历 bundle 中的 asset,就地更新内容与 fileName,再重写 chunk/文本 asset 中的引用。 |
实现要点
1. 开发:configureServer 与 ?url
中间件在解析 req.url 后,对带 ?url、?import、?raw 等资源后缀的请求 直接 next(),交给 Vite 资源管线。若误把这类请求当静态文件返回 audio/*,浏览器侧易出现 模块脚本 MIME 类型 与预期不符的问题。
对其余映射到项目根 / publicDir 下的真实音频路径,经 filter 命中后:processAudioFile 写入缓存路径,Content-Type 按输出扩展名设置,fs.createReadStream(cachePath).pipe(res) 返回。
缓存键依赖 源内容哈希 与 编码参数(见 createSourceHash 与 resolveTransformOptions 一类逻辑),参数变更会生成新缓存文件。
2. 生产:generateBundle 与 Rolldown
基本和vite-plugin-image-tools的思路差不多,对bundle进行修改,唯一值得注意的是rolldown和rollup有点区别
在 Rolldown 驱动的 Vite 中,对 generateBundle 回调里 bundle[newFileName] = … 形式的新增赋值会被忽略(仅告警)。因此实现上 不依赖新增 bundle 键,而是对 已有音频 asset 对象 就地赋值 fileName 与 source(Uint8Array / Buffer)。
总结
此插件比较适合音频较少,且不是特别大的场景(特别大的应该也不会放git仓库吧😓)
emmm,除此之外好像没啥好总结,相关实现之前在vite-plugin-image-tools就写过,只是把图片处理变成音频处理,就这样吧。
有问题随时issue,加star哦~