VideoKit

上传前,在浏览器内压缩视频

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 });

参数

参数默认值说明
maxWidthOrHeight1280输出视频长边的像素上限,较小的视频保持原尺寸。
skipBelowMB—不超过该体积且尺寸已在上限内的文件原样返回。
quality'medium'码率预设:low、medium、high,按输出分辨率换算。
videoBitrate—视频码率(bps),设置后覆盖 quality。
audioBitrate128000仅在音频需要重新编码时使用;可直接复制的音轨原样保留。
maxFrameRate—输出帧率上限(Hz),默认沿用源视频帧率。
format'mp4'mp4 输出 H.264 + AAC;webm 输出 VP9/VP8 + Opus。
onProgress—进度回调,取值 0 到 1。
signal—AbortSignal,用于取消压缩。
stallTimeoutMs90000页面可见时编码器持续无进展的超时时间,超时后返回原文件。

返回值包含 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 万次视频处理。如果你的团队计划在上传流程中接入浏览器端压缩,可以留下联系方式:我们会了解你的上传量与场景,并用你提供的样本视频测试压缩效果与设备兼容性。

请使用公司域名邮箱,便于我们确认团队信息。

信息仅用于回复本次咨询,不会用于其他用途。