上传前,在浏览器内压缩视频
browser-video-compression 是一个 MIT 开源的 JavaScript 组件。用户选择视频后,它在浏览器内把视频缩小到合适的分辨率并转为 H.264 MP4,再交给你现有的上传流程。适用于课程平台、表单、招聘工具等需要用户上传视频的网站。
上传更快,失败更少
手机拍摄的 1080p 视频压缩为 720p H.264 后,体积通常减少 60%–90%。上传时间随之缩短,移动网络下中途失败的概率也更低。
不会阻断上传
浏览器不支持、文件无法解码或压缩后没有变小时,组件返回原文件并注明原因,上传流程照常进行。
无需服务器与 ffmpeg.wasm
直接调用浏览器的 WebCodecs 硬件编码,不下载数十 MB 的 WebAssembly,也不需要配置跨域隔离响应头。
安装
npm install github:karuha-m/browser-video-compression组件以 ES 模块发布,附带 TypeScript 类型定义,依赖 mediabunny 读取与写入媒体文件。
快速开始
在文件选择后调用 compressVideo,把返回的 result.file 交给原有的上传代码即可。
import { compressVideo } from 'browser-video-compression';
input.addEventListener('change', async (event) => {
const original = event.target.files[0];
const result = await compressVideo(original, {
maxWidthOrHeight: 1280, // 720p
skipBelowMB: 10, // small files are uploaded as they are
onProgress: (p) => console.log(Math.round(p * 100) + '%'),
});
// result.file is the compressed file, or the original when
// compression was skipped (see result.skipReason)
const body = new FormData();
body.append('video', result.file);
await fetch('/upload', { method: 'POST', body });
});配合上传库使用
result.file 是标准的 File 对象,可直接交给 tus、Uppy、S3 预签名地址或 Mux、Cloudflare Stream 的直传接口。
import * as tus from 'tus-js-client';
const { file } = await compressVideo(original);
new tus.Upload(file, { endpoint: '/files/' }).start();上传前检查
inspectVideo 只读取容器元数据,不解码整个文件,可用于在上传前检查时长、分辨率与编码。
import { inspectVideo } from 'browser-video-compression';
const info = await inspectVideo(file);
// { duration, width, height, videoCodec, audioCodec, bitrate, canDecode, ... }
if (info.duration > 600) alert('Please keep videos under 10 minutes.');取消压缩
const controller = new AbortController();
cancelButton.onclick = () => controller.abort();
const result = await compressVideo(file, { signal: controller.signal });参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| maxWidthOrHeight | 1280 | 输出视频长边的像素上限,较小的视频保持原尺寸。 |
| skipBelowMB | — | 不超过该体积且尺寸已在上限内的文件原样返回。 |
| quality | 'medium' | 码率预设:low、medium、high,按输出分辨率换算。 |
| videoBitrate | — | 视频码率(bps),设置后覆盖 quality。 |
| audioBitrate | 128000 | 仅在音频需要重新编码时使用;可直接复制的音轨原样保留。 |
| maxFrameRate | — | 输出帧率上限(Hz),默认沿用源视频帧率。 |
| format | 'mp4' | mp4 输出 H.264 + AAC;webm 输出 VP9/VP8 + Opus。 |
| onProgress | — | 进度回调,取值 0 到 1。 |
| signal | — | AbortSignal,用于取消压缩。 |
| stallTimeoutMs | 90000 | 页面可见时编码器持续无进展的超时时间,超时后返回原文件。 |
返回值包含 file、compressed、skipReason、originalSize、size、width、height 与 duration。只有在调用方取消时 Promise 才会被拒绝;其余情况下 compressed 为 false 时,skipReason 说明返回原文件的原因:
already-small文件已低于 skipBelowMB,且尺寸在上限内。unsupported-browser当前浏览器没有可用的 WebCodecs 编码器。unsupported-input文件没有视频轨,或当前浏览器无法解码该视频。not-smaller压缩结果没有比原文件更小。failed压缩过程中出错,详细信息见 error 字段。
浏览器支持
| Chrome / Edge 94+ | 支持(桌面端与 Android) |
| Safari 16.4+ | 支持(macOS 与 iOS) |
| Firefox 130+ | 支持;非 AAC 音轨需注册 WebAssembly AAC 编码器 |
| 更早的浏览器 | 返回原文件,不影响上传 |
适用场景
在线课程与培训平台
学员提交作业视频、讲师上传课程录像。压缩后上传更快,存储与分发成本同步下降。
表单与问卷
让填写者在表单中附上视频说明或产品演示,避免因文件过大被上传限制拒绝。
招聘与视频面试
候选人用手机录制的自我介绍体积较大,压缩后在移动网络下也能顺利提交。
电商与交易平台
卖家上传商品视频前统一分辨率与编码,后端无需再为每个文件排队转码。
想先看看压缩效果,可以直接使用 VideoKit 在线视频压缩,它同样在浏览器内处理文件。
常见问题
压缩在哪里进行?视频会被上传到第三方吗?
压缩完全在用户的浏览器内完成,组件本身不发送任何网络请求。压缩后的文件由你的页面按原有方式上传到你自己的服务器或存储。
和 ffmpeg.wasm 相比有什么区别?
ffmpeg.wasm 需要下载约 30 MB 的 WebAssembly,多线程版本还依赖跨域隔离响应头,编码在 CPU 上以软件方式进行。本组件调用浏览器内置的 WebCodecs 编码器,多数设备上可使用硬件加速,无需额外下载与响应头配置。
浏览器不支持时会发生什么?
compressVideo 返回原文件,compressed 为 false,skipReason 为 unsupported-browser。上传流程不需要额外分支处理。
支持哪些输入格式?
支持 MP4、MOV、WebM、MKV 等常见容器。视频编码需为当前浏览器能够解码的格式:H.264 各浏览器均支持,HEVC、VP9、AV1 取决于设备。
能处理多大的文件?
压缩结果在返回前保存在内存中。桌面浏览器可处理数 GB 的文件;移动设备上处理 2 GB 以上的文件时,建议降低 maxWidthOrHeight 或直接上传原文件。
可以在 React、Vue 或 Web Worker 中使用吗?
可以。组件不依赖任何框架,输入与输出都是标准的 File 对象;使用的 API 在 Web Worker 中同样可用。
使用许可是什么?
MIT 许可,可用于商业项目,无需署名以外的任何条件。
团队接入咨询
VideoKit 的在线工具每月在用户浏览器内完成超过 10 万次视频处理。如果你的团队计划在上传流程中接入浏览器端压缩,可以留下联系方式:我们会了解你的上传量与场景,并用你提供的样本视频测试压缩效果与设备兼容性。