js实现视频压缩
使用 MediaRecorder API 压缩视频
通过 MediaRecorder API 可以录制视频并设置压缩参数。该方法适合在浏览器端直接处理视频文件。
async function compressVideo(file) {
const videoElement = document.createElement('video');
videoElement.src = URL.createObjectURL(file);
await new Promise(resolve => videoElement.onloadedmetadata = resolve);
const canvas = document.createElement('canvas');
canvas.width = videoElement.videoWidth * 0.5; // 缩小分辨率
canvas.height = videoElement.videoHeight * 0.5;
const ctx = canvas.getContext('2d');
const stream = canvas.captureStream();
const recorder = new MediaRecorder(stream, {
mimeType: 'video/webm;codecs=vp9',
bitsPerSecond: 250000 // 设置比特率
});
videoElement.play();
const chunks = [];
recorder.ondataavailable = e => chunks.push(e.data);
recorder.start();
const interval = setInterval(() => {
ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
}, 1000/30);
return new Promise(resolve => {
setTimeout(() => {
clearInterval(interval);
recorder.stop();
resolve(new Blob(chunks, {type: 'video/webm'}));
}, 3000); // 录制3秒
});
}
使用 FFmpeg.wasm 进行高级压缩
FFmpeg.wasm 是 WebAssembly 版本的 FFmpeg,提供更专业的视频处理能力。
import { createFFmpeg } from '@ffmpeg/ffmpeg';
async function compressWithFFmpeg(file) {
const ffmpeg = createFFmpeg({ log: true });
await ffmpeg.load();
ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(file));
await ffmpeg.run(
'-i', 'input.mp4',
'-vf', 'scale=640:-1', // 调整分辨率
'-c:v', 'libx264', // H.264编码
'-crf', '28', // 压缩质量(18-28)
'-preset', 'fast',
'output.mp4'
);
const data = ffmpeg.FS('readFile', 'output.mp4');
return new Blob([data.buffer], { type: 'video/mp4' });
}
使用 Canvas 和 Web Worker 处理
对于长时间压缩任务,建议使用 Web Worker 避免阻塞主线程。
// worker.js
self.onmessage = async (e) => {
const { file, width, height, quality } = e.data;
const video = document.createElement('video');
video.src = URL.createObjectURL(file);
await new Promise(resolve => {
video.onloadedmetadata = resolve;
video.play();
});
const canvas = new OffscreenCanvas(width, height);
const ctx = canvas.getContext('2d');
const frames = [];
for (let i = 0; i < video.duration * 30; i++) {
ctx.drawImage(video, 0, 0, width, height);
frames.push(await canvas.convertToBlob({quality}));
await new Promise(r => setTimeout(r, 1000/30));
}
postMessage(frames);
};
使用第三方库 compressor.js
compressor.js 提供简单的视频压缩接口,适合快速实现基本需求。
import Compressor from 'compressorjs';
new Compressor(file, {
quality: 0.6,
maxWidth: 1280,
maxHeight: 720,
success(result) {
console.log('压缩完成', result);
},
error(err) {
console.error('压缩失败', err);
}
});
注意事项
视频压缩会受浏览器兼容性限制,不同浏览器支持的编码格式不同。建议检测浏览器支持情况:

function checkCodecSupport() {
return MediaRecorder.isTypeSupported('video/webm;codecs=vp9')
|| MediaRecorder.isTypeSupported('video/mp4');
}
移动端设备可能对高分辨率视频处理性能有限,建议先降低分辨率再压缩。






